summaryrefslogtreecommitdiff
path: root/platform/android/java
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2022-03-29 00:04:42 +0200
committerGitHub <noreply@github.com>2022-03-29 00:04:42 +0200
commitfd0716cba92f2189a18118bc67bd05f07d9c420d (patch)
treee03379f330306b4dc2fd51bd537a45e20d573b09 /platform/android/java
parent5149db8d85ac491bafcb1b84203601b8c9593c7f (diff)
parent5711037bf6455ac8e7dc317975b7b0591decbb53 (diff)
Merge pull request #58160 from m4gr3d/android_editor
Diffstat (limited to 'platform/android/java')
-rw-r--r--platform/android/java/app/build.gradle34
-rw-r--r--platform/android/java/app/config.gradle52
-rw-r--r--platform/android/java/build.gradle144
-rw-r--r--platform/android/java/editor/build.gradle74
-rw-r--r--platform/android/java/editor/src/dev/res/values/strings.xml4
-rw-r--r--platform/android/java/editor/src/main/AndroidManifest.xml67
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java110
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java37
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java41
-rw-r--r--platform/android/java/editor/src/main/res/values/strings.xml4
-rw-r--r--platform/android/java/lib/build.gradle84
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java27
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotHost.java10
-rw-r--r--platform/android/java/nativeSrcsConfigs/CMakeLists.txt2
-rw-r--r--platform/android/java/nativeSrcsConfigs/build.gradle3
-rw-r--r--platform/android/java/scripts/publish-module.gradle11
-rw-r--r--platform/android/java/settings.gradle1
17 files changed, 641 insertions, 64 deletions
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index 5d1a9d7b99..b6303d1bc9 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -33,6 +33,11 @@ allprojects {
}
}
+configurations {
+ // Initializes a placeholder for the devImplementation dependency configuration.
+ devImplementation {}
+}
+
dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
@@ -45,6 +50,7 @@ dependencies {
// Custom build mode. In this scenario this project is the only one around and the Godot
// library is available through the pre-generated godot-lib.*.aar android archive files.
debugImplementation fileTree(dir: 'libs/debug', include: ['*.jar', '*.aar'])
+ devImplementation fileTree(dir: 'libs/dev', include: ['*.jar', '*.aar'])
releaseImplementation fileTree(dir: 'libs/release', include: ['*.jar', '*.aar'])
}
@@ -66,6 +72,7 @@ dependencies {
android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
+ ndkVersion versions.ndkVersion
compileOptions {
sourceCompatibility versions.javaVersion
@@ -93,6 +100,8 @@ android {
versionName getExportVersionName()
minSdkVersion getExportMinSdkVersion()
targetSdkVersion getExportTargetSdkVersion()
+
+ missingDimensionStrategy 'products', 'template'
}
lintOptions {
@@ -146,6 +155,18 @@ android {
}
}
+ dev {
+ initWith debug
+ // Signing and zip-aligning are skipped for prebuilt builds, but
+ // performed for custom builds.
+ zipAlignEnabled shouldZipAlign()
+ if (shouldSign()) {
+ signingConfig signingConfigs.debug
+ } else {
+ signingConfig null
+ }
+ }
+
release {
// Signing and zip-aligning are skipped for prebuilt builds, but
// performed for custom builds.
@@ -167,6 +188,7 @@ android {
assets.srcDirs = ['assets']
}
debug.jniLibs.srcDirs = ['libs/debug', 'libs/debug/vulkan_validation_layers']
+ dev.jniLibs.srcDirs = ['libs/dev']
release.jniLibs.srcDirs = ['libs/release']
}
@@ -183,6 +205,12 @@ task copyAndRenameDebugApk(type: Copy) {
rename "android_debug.apk", getExportFilename()
}
+task copyAndRenameDevApk(type: Copy) {
+ from "$buildDir/outputs/apk/dev/android_dev.apk"
+ into getExportPath()
+ rename "android_dev.apk", getExportFilename()
+}
+
task copyAndRenameReleaseApk(type: Copy) {
from "$buildDir/outputs/apk/release/android_release.apk"
into getExportPath()
@@ -195,6 +223,12 @@ task copyAndRenameDebugAab(type: Copy) {
rename "build-debug.aab", getExportFilename()
}
+task copyAndRenameDevAab(type: Copy) {
+ from "$buildDir/outputs/bundle/dev/build-dev.aab"
+ into getExportPath()
+ rename "build-dev.aab", getExportFilename()
+}
+
task copyAndRenameReleaseAab(type: Copy) {
from "$buildDir/outputs/bundle/release/build-release.aab"
into getExportPath()
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index c238d1b361..1b2976e715 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -76,7 +76,7 @@ ext.getGodotEditorVersion = { ->
String editorVersion = project.hasProperty("godot_editor_version") ? project.property("godot_editor_version") : ""
if (editorVersion == null || editorVersion.isEmpty()) {
// Try the library version first
- editorVersion = getGodotLibraryVersion()
+ editorVersion = getGodotLibraryVersionName()
if (editorVersion.isEmpty()) {
// Fallback value.
@@ -86,9 +86,24 @@ ext.getGodotEditorVersion = { ->
return editorVersion
}
+ext.getGodotLibraryVersionCode = { ->
+ String versionName = ""
+ int versionCode = 1
+ (versionName, versionCode) = getGodotLibraryVersion()
+ return versionCode
+}
+
+ext.getGodotLibraryVersionName = { ->
+ String versionName = ""
+ int versionCode = 1
+ (versionName, versionCode) = getGodotLibraryVersion()
+ return versionName
+}
+
ext.generateGodotLibraryVersion = { List<String> requiredKeys ->
// Attempt to read the version from the `version.py` file.
- String libraryVersion = ""
+ String libraryVersionName = ""
+ int libraryVersionCode = 0
File versionFile = new File("../../../version.py")
if (versionFile.isFile()) {
@@ -109,15 +124,35 @@ ext.generateGodotLibraryVersion = { List<String> requiredKeys ->
}
if (requiredKeys.empty) {
- libraryVersion = map.values().join(".")
+ libraryVersionName = map.values().join(".")
+ try {
+ if (map.containsKey("patch")) {
+ libraryVersionCode = Integer.parseInt(map["patch"])
+ }
+
+ if (map.containsKey("minor")) {
+ libraryVersionCode += (Integer.parseInt(map["minor"]) * 100)
+ }
+
+ if (map.containsKey("major")) {
+ libraryVersionCode += (Integer.parseInt(map["major"]) * 10000)
+ }
+ } catch (NumberFormatException ignore) {
+ libraryVersionCode = 1
+ }
}
}
- if (libraryVersion.isEmpty()) {
+ if (libraryVersionName.isEmpty()) {
// Fallback value in case we're unable to read the file.
- libraryVersion = "custom_build"
+ libraryVersionName = "custom_build"
+ }
+
+ if (libraryVersionCode == 0) {
+ libraryVersionCode = 1
}
- return libraryVersion
+
+ return [libraryVersionName, libraryVersionCode]
}
ext.getGodotLibraryVersion = { ->
@@ -127,7 +162,10 @@ ext.getGodotLibraryVersion = { ->
ext.getGodotPublishVersion = { ->
List<String> requiredKeys = ["major", "minor", "patch", "status"]
- return generateGodotLibraryVersion(requiredKeys)
+ String versionName = ""
+ int versionCode = 1
+ (versionName, versionCode) = generateGodotLibraryVersion(requiredKeys)
+ return versionName
}
final String VALUE_SEPARATOR_REGEX = "\\|"
diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle
index 83bc68c992..e16ca65df5 100644
--- a/platform/android/java/build.gradle
+++ b/platform/android/java/build.gradle
@@ -26,21 +26,22 @@ allprojects {
ext {
supportedAbis = ["armv7", "arm64v8", "x86", "x86_64"]
- supportedTargets = ["release", "debug"]
+ supportedTargetsMap = [release: "release", dev: "debug", debug: "release_debug"]
+ supportedFlavors = ["editor", "template"]
- // Used by gradle to specify which architecture to build for by default when running `./gradlew build`.
- // This command is usually used by Android Studio.
+ // Used by gradle to specify which architecture to build for by default when running
+ // `./gradlew build` (this command is usually used by Android Studio).
// If building manually on the command line, it's recommended to use the
- // `./gradlew generateGodotTemplates` build command instead after running the `scons` command.
- // The defaultAbi must be one of the {supportedAbis} values.
- defaultAbi = "arm64v8"
+ // `./gradlew generateGodotTemplates` build command instead after running the `scons` command(s).
+ // The {selectedAbis} values must be from the {supportedAbis} values.
+ selectedAbis = ["arm64v8"]
}
def rootDir = "../../.."
def binDir = "$rootDir/bin/"
-def getSconsTaskName(String buildType) {
- return "compileGodotNativeLibs" + buildType.capitalize()
+def getSconsTaskName(String flavor, String buildType, String abi) {
+ return "compileGodotNativeLibs" + flavor.capitalize() + buildType.capitalize() + abi.capitalize()
}
/**
@@ -55,6 +56,17 @@ task copyDebugBinaryToBin(type: Copy) {
}
/**
+ * Copy the generated 'android_dev.apk' binary template into the Godot bin directory.
+ * Depends on the app build task to ensure the binary is generated prior to copying.
+ */
+task copyDevBinaryToBin(type: Copy) {
+ dependsOn ':app:assembleDev'
+ from('app/build/outputs/apk/dev')
+ into(binDir)
+ include('android_dev.apk')
+}
+
+/**
* Copy the generated 'android_release.apk' binary template into the Godot bin directory.
* Depends on the app build task to ensure the binary is generated prior to copying.
*/
@@ -70,7 +82,7 @@ task copyReleaseBinaryToBin(type: Copy) {
* Depends on the library build task to ensure the AAR file is generated prior to copying.
*/
task copyDebugAARToAppModule(type: Copy) {
- dependsOn ':lib:assembleDebug'
+ dependsOn ':lib:assembleTemplateDebug'
from('lib/build/outputs/aar')
into('app/libs/debug')
include('godot-lib.debug.aar')
@@ -81,18 +93,40 @@ task copyDebugAARToAppModule(type: Copy) {
* Depends on the library build task to ensure the AAR file is generated prior to copying.
*/
task copyDebugAARToBin(type: Copy) {
- dependsOn ':lib:assembleDebug'
+ dependsOn ':lib:assembleTemplateDebug'
from('lib/build/outputs/aar')
into(binDir)
include('godot-lib.debug.aar')
}
/**
+ * Copy the Godot android library archive dev file into the app module dev libs directory.
+ * Depends on the library build task to ensure the AAR file is generated prior to copying.
+ */
+task copyDevAARToAppModule(type: Copy) {
+ dependsOn ':lib:assembleTemplateDev'
+ from('lib/build/outputs/aar')
+ into('app/libs/dev')
+ include('godot-lib.dev.aar')
+}
+
+/**
+ * Copy the Godot android library archive dev file into the root bin directory.
+ * Depends on the library build task to ensure the AAR file is generated prior to copying.
+ */
+task copyDevAARToBin(type: Copy) {
+ dependsOn ':lib:assembleTemplateDev'
+ from('lib/build/outputs/aar')
+ into(binDir)
+ include('godot-lib.dev.aar')
+}
+
+/**
* Copy the Godot android library archive release file into the app module release libs directory.
* Depends on the library build task to ensure the AAR file is generated prior to copying.
*/
task copyReleaseAARToAppModule(type: Copy) {
- dependsOn ':lib:assembleRelease'
+ dependsOn ':lib:assembleTemplateRelease'
from('lib/build/outputs/aar')
into('app/libs/release')
include('godot-lib.release.aar')
@@ -103,7 +137,7 @@ task copyReleaseAARToAppModule(type: Copy) {
* Depends on the library build task to ensure the AAR file is generated prior to copying.
*/
task copyReleaseAARToBin(type: Copy) {
- dependsOn ':lib:assembleRelease'
+ dependsOn ':lib:assembleTemplateRelease'
from('lib/build/outputs/aar')
into(binDir)
include('godot-lib.release.aar')
@@ -111,7 +145,7 @@ task copyReleaseAARToBin(type: Copy) {
/**
* Generate Godot custom build template by zipping the source files from the app directory, as well
- * as the AAR files generated by 'copyDebugAAR' and 'copyReleaseAAR'.
+ * as the AAR files generated by 'copyDebugAAR', 'copyDevAAR' and 'copyReleaseAAR'.
* The zip file also includes some gradle tools to allow building of the custom build.
*/
task zipCustomBuild(type: Zip) {
@@ -130,8 +164,18 @@ def templateExcludedBuildTask() {
def excludedTasks = []
if (!isAndroidStudio()) {
logger.lifecycle("Excluding Android studio build tasks")
- for (String buildType : supportedTargets) {
- excludedTasks += ":lib:" + getSconsTaskName(buildType)
+ for (String flavor : supportedFlavors) {
+ for (String buildType : supportedTargetsMap.keySet()) {
+ if (buildType == "release" && flavor == "editor") {
+ // The editor can't be used with target=release as debugging tools are then not
+ // included, and it would crash on errors instead of reporting them.
+ continue
+ }
+
+ for (String abi : selectedAbis) {
+ excludedTasks += ":lib:" + getSconsTaskName(flavor, buildType, abi)
+ }
+ }
}
}
return excludedTasks
@@ -141,7 +185,7 @@ def templateBuildTasks() {
def tasks = []
// Only build the apks and aar files for which we have native shared libraries.
- for (String target : supportedTargets) {
+ for (String target : supportedTargetsMap.keySet()) {
File targetLibs = new File("lib/libs/" + target)
if (targetLibs != null
&& targetLibs.isDirectory()
@@ -167,6 +211,50 @@ def isAndroidStudio() {
return sysProps != null && sysProps['idea.platform.prefix'] != null
}
+task copyEditorDebugBinaryToBin(type: Copy) {
+ dependsOn ':editor:assembleDebug'
+ from('editor/build/outputs/apk/debug')
+ into(binDir)
+ include('android_editor.apk')
+}
+
+task copyEditorDevBinaryToBin(type: Copy) {
+ dependsOn ':editor:assembleDev'
+ from('editor/build/outputs/apk/dev')
+ into(binDir)
+ include('android_editor_dev.apk')
+}
+
+/**
+ * Generate the Godot Editor Android apk.
+ *
+ * Note: The Godot 'tools' shared libraries must have been generated (via scons) prior to running
+ * this gradle task. The task will only build the apk(s) for which the shared libraries is
+ * available.
+ */
+task generateGodotEditor {
+ gradle.startParameter.excludedTaskNames += templateExcludedBuildTask()
+
+ def tasks = []
+
+ for (String target : supportedTargetsMap.keySet()) {
+ if (target == "release") {
+ // The editor can't be used with target=release as debugging tools are then not
+ // included, and it would crash on errors instead of reporting them.
+ continue
+ }
+ File targetLibs = new File("lib/libs/tools/" + target)
+ if (targetLibs != null
+ && targetLibs.isDirectory()
+ && targetLibs.listFiles() != null
+ && targetLibs.listFiles().length > 0) {
+ tasks += "copyEditor${target.capitalize()}BinaryToBin"
+ }
+ }
+
+ dependsOn = tasks
+}
+
/**
* Master task used to coordinate the tasks defined above to generate the set of Godot templates.
*/
@@ -191,7 +279,27 @@ task generateDevTemplate {
}
/**
- * Clean the generated artifacts.
+ * Clean the generated editor artifacts.
+ */
+task cleanGodotEditor(type: Delete) {
+ // Delete the generated native tools libs
+ delete("lib/libs/tools")
+
+ // Delete the library generated AAR files
+ delete("lib/build/outputs/aar")
+
+ // Delete the generated binary apks
+ delete("editor/build/outputs/apk")
+
+ // Delete the Godot editor apks in the Godot bin directory
+ delete("$binDir/android_editor.apk")
+ delete("$binDir/android_editor_dev.apk")
+
+ finalizedBy getTasksByName("clean", true)
+}
+
+/**
+ * Clean the generated template artifacts.
*/
task cleanGodotTemplates(type: Delete) {
// Delete the generated native libs
@@ -208,9 +316,11 @@ task cleanGodotTemplates(type: Delete) {
// Delete the Godot templates in the Godot bin directory
delete("$binDir/android_debug.apk")
+ delete("$binDir/android_dev.apk")
delete("$binDir/android_release.apk")
delete("$binDir/android_source.zip")
delete("$binDir/godot-lib.debug.aar")
+ delete("$binDir/godot-lib.dev.aar")
delete("$binDir/godot-lib.release.aar")
finalizedBy getTasksByName("clean", true)
diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle
new file mode 100644
index 0000000000..3312f61ad3
--- /dev/null
+++ b/platform/android/java/editor/build.gradle
@@ -0,0 +1,74 @@
+// Gradle build config for Godot Engine's Android port.
+apply plugin: 'com.android.application'
+
+dependencies {
+ implementation libraries.kotlinStdLib
+ implementation libraries.androidxFragment
+ implementation project(":lib")
+}
+
+android {
+ compileSdkVersion versions.compileSdk
+ buildToolsVersion versions.buildTools
+ ndkVersion versions.ndkVersion
+
+ defaultConfig {
+ // The 'applicationId' suffix allows to install Godot 3.x(v3) and 4.x(v4) on the same device
+ applicationId "org.godotengine.editor.v4"
+ versionCode getGodotLibraryVersionCode()
+ versionName getGodotLibraryVersionName()
+ minSdkVersion versions.minSdk
+ //noinspection ExpiredTargetSdkVersion - Restrict to version 29 until https://github.com/godotengine/godot/pull/51815 is submitted
+ targetSdkVersion 29 // versions.targetSdk
+
+ missingDimensionStrategy 'products', 'editor'
+ }
+
+ compileOptions {
+ sourceCompatibility versions.javaVersion
+ targetCompatibility versions.javaVersion
+ }
+
+ buildTypes {
+ dev {
+ initWith debug
+ applicationIdSuffix ".dev"
+ }
+
+ debug {
+ initWith release
+
+ // Need to swap with the release signing config when this is ready for public release.
+ signingConfig signingConfigs.debug
+ }
+
+ release {
+ // This buildtype is disabled below.
+ // The editor can't be used with target=release only, as debugging tools are then not
+ // included, and it would crash on errors instead of reporting them.
+ }
+ }
+
+ packagingOptions {
+ // 'doNotStrip' is enabled for development within Android Studio
+ if (shouldNotStrip()) {
+ doNotStrip '**/*.so'
+ }
+ }
+
+ // Disable 'release' buildtype.
+ // The editor can't be used with target=release only, as debugging tools are then not
+ // included, and it would crash on errors instead of reporting them.
+ variantFilter { variant ->
+ if (variant.buildType.name == "release") {
+ setIgnore(true)
+ }
+ }
+
+ applicationVariants.all { variant ->
+ variant.outputs.all { output ->
+ def suffix = variant.name == "dev" ? "_dev" : ""
+ output.outputFileName = "android_editor${suffix}.apk"
+ }
+ }
+}
diff --git a/platform/android/java/editor/src/dev/res/values/strings.xml b/platform/android/java/editor/src/dev/res/values/strings.xml
new file mode 100644
index 0000000000..45fae3fd39
--- /dev/null
+++ b/platform/android/java/editor/src/dev/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_editor_name_string">Godot Editor 4.x (dev)</string>
+</resources>
diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..0708ffa32f
--- /dev/null
+++ b/platform/android/java/editor/src/main/AndroidManifest.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="org.godotengine.editor"
+ android:installLocation="auto">
+
+ <supports-screens
+ android:largeScreens="true"
+ android:normalScreens="true"
+ android:smallScreens="true"
+ android:xlargeScreens="true" />
+
+ <uses-feature
+ android:glEsVersion="0x00020000"
+ android:required="true" />
+
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application
+ android:allowBackup="false"
+ android:icon="@mipmap/icon"
+ android:label="@string/godot_editor_name_string"
+ tools:ignore="GoogleAppIndexingWarning"
+ android:requestLegacyExternalStorage="true">
+
+ <activity
+ android:name=".GodotProjectManager"
+ android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
+ android:launchMode="singleTask"
+ android:resizeableActivity="false"
+ android:screenOrientation="landscape"
+ android:exported="true"
+ android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
+ android:process=":GodotProjectManager">
+
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name=".GodotEditor"
+ android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
+ android:process=":GodotEditor"
+ android:launchMode="singleTask"
+ android:resizeableActivity="false"
+ android:screenOrientation="landscape"
+ android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
+ </activity>
+
+ <activity
+ android:name=".GodotGame"
+ android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode"
+ android:label="@string/godot_project_name_string"
+ android:process=":GodotGame"
+ android:launchMode="singleTask"
+ android:resizeableActivity="false"
+ android:screenOrientation="landscape"
+ android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
+ </activity>
+
+ </application>
+
+</manifest>
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java
new file mode 100644
index 0000000000..b3a340cc64
--- /dev/null
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java
@@ -0,0 +1,110 @@
+/*************************************************************************/
+/* GodotEditor.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.editor;
+
+import org.godotengine.godot.FullScreenGodotApp;
+import org.godotengine.godot.utils.PermissionsUtil;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Debug;
+
+import androidx.annotation.Nullable;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Base class for the Godot Android Editor activities.
+ *
+ * This provides the basic templates for the activities making up this application.
+ * Each derived activity runs in its own process, which enable up to have several instances of
+ * the Godot engine up and running at the same time.
+ *
+ * It also plays the role of the primary editor window.
+ */
+public class GodotEditor extends FullScreenGodotApp {
+ private static final boolean WAIT_FOR_DEBUGGER = false;
+ private static final String COMMAND_LINE_PARAMS = "command_line_params";
+
+ private static final String EDITOR_ARG = "--editor";
+ private static final String PROJECT_MANAGER_ARG = "--project-manager";
+
+ private final List<String> commandLineParams = new ArrayList<>();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ PermissionsUtil.requestManifestPermissions(this);
+
+ String[] params = getIntent().getStringArrayExtra(COMMAND_LINE_PARAMS);
+ updateCommandLineParams(params);
+
+ if (BuildConfig.BUILD_TYPE.equals("debug") && WAIT_FOR_DEBUGGER) {
+ Debug.waitForDebugger();
+ }
+ super.onCreate(savedInstanceState);
+ }
+
+ private void updateCommandLineParams(@Nullable String[] args) {
+ // Update the list of command line params with the new args
+ commandLineParams.clear();
+ if (args != null && args.length > 0) {
+ commandLineParams.addAll(Arrays.asList(args));
+ }
+ }
+
+ @Override
+ public List<String> getCommandLine() {
+ return commandLineParams;
+ }
+
+ @Override
+ public void onNewGodotInstanceRequested(String[] args) {
+ // Parse the arguments to figure out which activity to start.
+ Class<?> targetClass = GodotGame.class;
+ for (String arg : args) {
+ if (EDITOR_ARG.equals(arg)) {
+ targetClass = GodotEditor.class;
+ break;
+ }
+
+ if (PROJECT_MANAGER_ARG.equals(arg)) {
+ targetClass = GodotProjectManager.class;
+ break;
+ }
+ }
+
+ // Launch a new activity
+ Intent newInstance = new Intent(this, targetClass).putExtra(COMMAND_LINE_PARAMS, args);
+ startActivity(newInstance);
+ }
+}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java
new file mode 100644
index 0000000000..5a0be391cf
--- /dev/null
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java
@@ -0,0 +1,37 @@
+/*************************************************************************/
+/* GodotGame.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.editor;
+
+/**
+ * Drives the 'run project' window of the Godot Editor.
+ */
+public class GodotGame extends GodotEditor {
+}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java
new file mode 100644
index 0000000000..d30f66bb8c
--- /dev/null
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java
@@ -0,0 +1,41 @@
+/*************************************************************************/
+/* GodotProjectManager.java */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+package org.godotengine.editor;
+
+/**
+ * Launcher activity for the Godot Android Editor.
+ *
+ * It presents the user with the project manager interface.
+ * Upon selection of a project, this activity (via its parent logic) starts the
+ * {@link GodotEditor} activity.
+ */
+public class GodotProjectManager extends GodotEditor {
+}
diff --git a/platform/android/java/editor/src/main/res/values/strings.xml b/platform/android/java/editor/src/main/res/values/strings.xml
new file mode 100644
index 0000000000..e8ce34f34d
--- /dev/null
+++ b/platform/android/java/editor/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="godot_editor_name_string">Godot Editor 4.x</string>
+</resources>
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index 120a40a31d..c806de1ded 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -18,14 +18,13 @@ def pathToRootDir = "../../../../"
android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
-
ndkVersion versions.ndkVersion
defaultConfig {
minSdkVersion versions.minSdk
targetSdkVersion versions.targetSdk
- manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersion()]
+ manifestPlaceholders = [godotLibraryVersion: getGodotLibraryVersionName()]
}
namespace = "org.godotengine.godot"
@@ -35,6 +34,18 @@ android {
targetCompatibility versions.javaVersion
}
+ buildTypes {
+ dev {
+ initWith debug
+ }
+ }
+
+ flavorDimensions "products"
+ productFlavors {
+ editor {}
+ template {}
+ }
+
lintOptions {
abortOnError false
disable 'MissingTranslation', 'UnusedResources'
@@ -58,24 +69,50 @@ android {
aidl.srcDirs = ['aidl']
assets.srcDirs = ['assets']
}
+
debug.jniLibs.srcDirs = ['libs/debug']
+ dev.jniLibs.srcDirs = ['libs/dev']
release.jniLibs.srcDirs = ['libs/release']
+
+ // Editor jni library
+ editorDebug.jniLibs.srcDirs = ['libs/tools/debug']
+ editorDev.jniLibs.srcDirs = ['libs/tools/dev']
+ }
+
+ // Disable 'editorRelease'.
+ // The editor can't be used with target=release as debugging tools are then not
+ // included, and it would crash on errors instead of reporting them.
+ variantFilter { variant ->
+ if (variant.name == "editorRelease") {
+ setIgnore(true)
+ }
}
libraryVariants.all { variant ->
- variant.outputs.all { output ->
- output.outputFileName = "godot-lib.${variant.name}.aar"
+ def flavorName = variant.getFlavorName()
+ if (flavorName == null || flavorName == "") {
+ throw new GradleException("Invalid product flavor: $flavorName")
}
- def buildType = variant.buildType.name.capitalize()
+ boolean toolsFlag = flavorName == "editor"
- def releaseTarget = buildType.toLowerCase()
- if (releaseTarget == null || releaseTarget == "") {
- throw new GradleException("Invalid build type: " + buildType)
+ def buildType = variant.buildType.name
+ if (buildType == null || buildType == "" || !supportedTargetsMap.containsKey(buildType)) {
+ throw new GradleException("Invalid build type: $buildType")
}
- if (!supportedAbis.contains(defaultAbi)) {
- throw new GradleException("Invalid default abi: " + defaultAbi)
+ def sconsTarget = supportedTargetsMap[buildType]
+ if (sconsTarget == null || sconsTarget == "") {
+ throw new GradleException("Invalid scons target: $sconsTarget")
+ }
+
+ // Update the name of the generated library
+ def outputSuffix = "${buildType}.aar"
+ if (toolsFlag) {
+ outputSuffix = "tools.$outputSuffix"
+ }
+ variant.outputs.all { output ->
+ output.outputFileName = "godot-lib.${outputSuffix}"
}
// Find scons' executable path
@@ -88,13 +125,11 @@ android {
for (ext in sconsExts) {
String sconsNameExt = sconsName + ext
logger.lifecycle("Checking $sconsNameExt")
-
sconsExecutableFile = org.gradle.internal.os.OperatingSystem.current().findInPath(sconsNameExt)
if (sconsExecutableFile != null) {
// We're done!
break
}
-
// Check all the options in path
List<File> allOptions = org.gradle.internal.os.OperatingSystem.current().findAllInPath(sconsNameExt)
if (!allOptions.isEmpty()) {
@@ -103,27 +138,32 @@ android {
break
}
}
-
if (sconsExecutableFile == null) {
throw new GradleException("Unable to find executable path for the '$sconsName' command.")
} else {
logger.lifecycle("Found executable path for $sconsName: ${sconsExecutableFile.absolutePath}")
}
- // Creating gradle task to generate the native libraries for the default abi.
- def taskName = getSconsTaskName(buildType)
- tasks.create(name: taskName, type: Exec) {
- executable sconsExecutableFile.absolutePath
- args "--directory=${pathToRootDir}", "platform=android", "target=${releaseTarget}", "android_arch=${defaultAbi}", "-j" + Runtime.runtime.availableProcessors()
- }
+ for (String selectedAbi : selectedAbis) {
+ if (!supportedAbis.contains(selectedAbi)) {
+ throw new GradleException("Invalid selected abi: $selectedAbi")
+ }
- // Schedule the tasks so the generated libs are present before the aar file is packaged.
- tasks["merge${buildType}JniLibFolders"].dependsOn taskName
+ // Creating gradle task to generate the native libraries for the selected abi.
+ def taskName = getSconsTaskName(flavorName, buildType, selectedAbi)
+ tasks.create(name: taskName, type: Exec) {
+ executable sconsExecutableFile.absolutePath
+ args "--directory=${pathToRootDir}", "platform=android", "tools=${toolsFlag}", "target=${sconsTarget}", "android_arch=${selectedAbi}", "-j" + Runtime.runtime.availableProcessors()
+ }
+
+ // Schedule the tasks so the generated libs are present before the aar file is packaged.
+ tasks["merge${flavorName.capitalize()}${buildType.capitalize()}JniLibFolders"].dependsOn taskName
+ }
}
// TODO: Enable when issues with AGP 7.1+ are resolved (https://github.com/GodotVR/godot_openxr/issues/187).
// publishing {
-// singleVariant("release") {
+// singleVariant("templateRelease") {
// withSourcesJar()
// withJavadocJar()
// }
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
index 78848c109a..8a86136daf 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -47,7 +47,6 @@ import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.ClipData;
import android.content.ClipboardManager;
-import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
@@ -333,9 +332,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public void restart() {
- if (godotHost != null) {
- godotHost.onGodotRestartRequested(this);
- }
+ runOnUiThread(() -> {
+ if (godotHost != null) {
+ godotHost.onGodotRestartRequested(this);
+ }
+ });
}
public void alert(final String message, final String title) {
@@ -859,9 +860,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private void forceQuit() {
// TODO: This is a temp solution. The proper fix will involve tracking down and properly shutting down each
// native Godot components that is started in Godot#onVideoInit.
- if (godotHost != null) {
- godotHost.onGodotForceQuit(this);
- }
+ runOnUiThread(() -> {
+ if (godotHost != null) {
+ godotHost.onGodotForceQuit(this);
+ }
+ });
}
private boolean obbIsCorrupted(String f, String main_pack_md5) {
@@ -1010,6 +1013,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
mProgressFraction.setText(Helpers.getDownloadProgressString(progress.mOverallProgress,
progress.mOverallTotal));
}
+
public void initInputDevices() {
mRenderView.initInputDevices();
}
@@ -1018,4 +1022,13 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private GodotRenderView getRenderView() { // used by native side to get renderView
return mRenderView;
}
+
+ @Keep
+ private void createNewGodotInstance(String[] args) {
+ runOnUiThread(() -> {
+ if (godotHost != null) {
+ godotHost.onNewGodotInstanceRequested(args);
+ }
+ });
+ }
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
index 8e8f993369..2e7b67194f 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
@@ -60,8 +60,16 @@ public interface GodotHost {
default void onGodotForceQuit(Godot instance) {}
/**
- * Invoked on the GL thread when the Godot instance wants to be restarted. It's up to the host
+ * Invoked on the UI thread when the Godot instance wants to be restarted. It's up to the host
* to perform the appropriate action(s).
*/
default void onGodotRestartRequested(Godot instance) {}
+
+ /**
+ * Invoked on the UI thread when a new Godot instance is requested. It's up to the host to
+ * perform the appropriate action(s).
+ *
+ * @param args Arguments used to initialize the new instance.
+ */
+ default void onNewGodotInstanceRequested(String[] args) {}
}
diff --git a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
index 966c02f7d7..59cfe21c49 100644
--- a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
+++ b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
@@ -16,3 +16,5 @@ add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME}
SYSTEM PUBLIC
${GODOT_ROOT_DIR})
+
+add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DTOOLS_ENABLED)
diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle
index 158bb2b98e..0cb769b539 100644
--- a/platform/android/java/nativeSrcsConfigs/build.gradle
+++ b/platform/android/java/nativeSrcsConfigs/build.gradle
@@ -6,6 +6,7 @@ plugins {
android {
compileSdkVersion versions.compileSdk
buildToolsVersion versions.buildTools
+ ndkVersion versions.ndkVersion
defaultConfig {
minSdkVersion versions.minSdk
@@ -28,8 +29,6 @@ android {
}
}
- ndkVersion versions.ndkVersion
-
externalNativeBuild {
cmake {
path "CMakeLists.txt"
diff --git a/platform/android/java/scripts/publish-module.gradle b/platform/android/java/scripts/publish-module.gradle
index 6b2aea5caf..32b749e493 100644
--- a/platform/android/java/scripts/publish-module.gradle
+++ b/platform/android/java/scripts/publish-module.gradle
@@ -7,20 +7,15 @@ version = PUBLISH_VERSION
afterEvaluate {
publishing {
publications {
- release(MavenPublication) {
+ templateRelease(MavenPublication) {
+ from components.templateRelease
+
// The coordinates of the library, being set from variables that
// we'll set up later
groupId ossrhGroupId
artifactId PUBLISH_ARTIFACT_ID
version PUBLISH_VERSION
- // Two artifacts, the `aar` (or `jar`) and the sources
- if (project.plugins.findPlugin("com.android.library")) {
- from components.release
- } else {
- from components.java
- }
-
// Mostly self-explanatory metadata
pom {
name = PUBLISH_ARTIFACT_ID
diff --git a/platform/android/java/settings.gradle b/platform/android/java/settings.gradle
index 584b626900..56e1b6fd3a 100644
--- a/platform/android/java/settings.gradle
+++ b/platform/android/java/settings.gradle
@@ -4,6 +4,7 @@ rootProject.name = "Godot"
include ':app'
include ':lib'
include ':nativeSrcsConfigs'
+include ':editor'
include ':assetPacks:installTime'
project(':assetPacks:installTime').projectDir = file("app/assetPacks/installTime")