summaryrefslogtreecommitdiff
path: root/platform/android/java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/java')
-rw-r--r--platform/android/java/app/build.gradle13
-rw-r--r--platform/android/java/app/config.gradle7
-rw-r--r--platform/android/java/app/res/values/themes.xml4
-rw-r--r--platform/android/java/app/settings.gradle13
-rw-r--r--platform/android/java/build.gradle11
-rw-r--r--platform/android/java/editor/build.gradle11
-rw-r--r--platform/android/java/editor/src/main/AndroidManifest.xml7
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java124
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt146
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.java)10
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotProjectManager.java)9
-rw-r--r--platform/android/java/editor/src/main/res/values/dimens.xml5
-rw-r--r--platform/android/java/lib/AndroidManifest.xml13
-rw-r--r--platform/android/java/lib/build.gradle10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java20
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotIO.java24
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java50
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java3
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java141
-rw-r--r--platform/android/java/nativeSrcsConfigs/build.gradle5
-rw-r--r--platform/android/java/settings.gradle15
22 files changed, 420 insertions, 225 deletions
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index b6303d1bc9..63b10e62b1 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -1,6 +1,4 @@
// Gradle build config for Godot Engine's Android port.
-apply from: 'config.gradle'
-
buildscript {
apply from: 'config.gradle'
@@ -14,7 +12,12 @@ buildscript {
}
}
-apply plugin: 'com.android.application'
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+apply from: 'config.gradle'
allprojects {
repositories {
@@ -79,6 +82,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
assetPacks = [":assetPacks:installTime"]
defaultConfig {
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 1b2976e715..73a412a2b0 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,11 +1,12 @@
ext.versions = [
androidGradlePlugin: '7.0.3',
- compileSdk : 30,
+ compileSdk : 31,
minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
buildTools : '30.0.3',
- kotlinVersion : '1.6.10',
+ kotlinVersion : '1.6.21',
fragmentVersion : '1.3.6',
+ nexusPublishVersion: '1.1.0',
javaVersion : 11,
ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
@@ -14,7 +15,7 @@ ext.versions = [
ext.libraries = [
androidGradlePlugin: "com.android.tools.build:gradle:$versions.androidGradlePlugin",
kotlinGradlePlugin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlinVersion",
- kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlinVersion",
+ kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib:$versions.kotlinVersion",
androidxFragment : "androidx.fragment:fragment:$versions.fragmentVersion",
]
diff --git a/platform/android/java/app/res/values/themes.xml b/platform/android/java/app/res/values/themes.xml
index 99f723f5ba..d64b50ca45 100644
--- a/platform/android/java/app/res/values/themes.xml
+++ b/platform/android/java/app/res/values/themes.xml
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
- <style name="GodotAppMainTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen"/>
+ <style name="GodotAppMainTheme" parent="@android:style/Theme.Black.NoTitleBar"/>
- <style name="GodotAppSplashTheme" parent="@style/GodotAppMainTheme">
+ <style name="GodotAppSplashTheme" parent="@android:style/Theme.Black.NoTitleBar.Fullscreen">
<item name="android:windowBackground">@drawable/splash_drawable</item>
<item name="android:windowLayoutInDisplayCutoutMode">shortEdges</item>
</style>
diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle
index e38d7b2ba6..ba53aefe7f 100644
--- a/platform/android/java/app/settings.gradle
+++ b/platform/android/java/app/settings.gradle
@@ -1,2 +1,15 @@
// This is the root directory of the Godot custom build.
+pluginManagement {
+ apply from: 'config.gradle'
+
+ plugins {
+ id 'com.android.application' version versions.androidGradlePlugin
+ id 'org.jetbrains.kotlin.android' version versions.kotlinVersion
+ }
+ repositories {
+ gradlePluginPortal()
+ google()
+ }
+}
+
include ':assetPacks:installTime'
diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle
index e16ca65df5..da30bd3a95 100644
--- a/platform/android/java/build.gradle
+++ b/platform/android/java/build.gradle
@@ -1,7 +1,3 @@
-apply plugin: 'io.github.gradle-nexus.publish-plugin'
-apply from: 'app/config.gradle'
-apply from: 'scripts/publish-root.gradle'
-
buildscript {
apply from: 'app/config.gradle'
@@ -17,6 +13,13 @@ buildscript {
}
}
+plugins {
+ id 'io.github.gradle-nexus.publish-plugin'
+}
+
+apply from: 'app/config.gradle'
+apply from: 'scripts/publish-root.gradle'
+
allprojects {
repositories {
google()
diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle
index 3312f61ad3..dd167c3880 100644
--- a/platform/android/java/editor/build.gradle
+++ b/platform/android/java/editor/build.gradle
@@ -1,10 +1,15 @@
// Gradle build config for Godot Engine's Android port.
-apply plugin: 'com.android.application'
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
dependencies {
implementation libraries.kotlinStdLib
implementation libraries.androidxFragment
implementation project(":lib")
+
+ implementation "androidx.window:window:1.0.0"
}
android {
@@ -29,6 +34,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
buildTypes {
dev {
initWith debug
diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml
index bae075d929..659caf7ab4 100644
--- a/platform/android/java/editor/src/main/AndroidManifest.xml
+++ b/platform/android/java/editor/src/main/AndroidManifest.xml
@@ -34,6 +34,9 @@
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:process=":GodotProjectManager">
+ <layout android:defaultHeight="@dimen/editor_default_window_height"
+ android:defaultWidth="@dimen/editor_default_window_width" />
+
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
@@ -47,6 +50,8 @@
android:launchMode="singleTask"
android:screenOrientation="userLandscape"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
+ <layout android:defaultHeight="@dimen/editor_default_window_height"
+ android:defaultWidth="@dimen/editor_default_window_width" />
</activity>
<activity
@@ -57,6 +62,8 @@
android:launchMode="singleTask"
android:screenOrientation="userLandscape"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
+ <layout android:defaultHeight="@dimen/editor_default_window_height"
+ android:defaultWidth="@dimen/editor_default_window_width" />
</activity>
</application>
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
deleted file mode 100644
index 8a6bf88267..0000000000
--- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*************************************************************************/
-/* 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);
- }
-
- @Override
- public void setRequestedOrientation(int requestedOrientation) {
- if (!overrideOrientationRequest()) {
- super.setRequestedOrientation(requestedOrientation);
- }
- }
-
- /**
- * The Godot Android Editor sets its own orientation via its AndroidManifest
- */
- protected boolean overrideOrientationRequest() {
- return true;
- }
-}
diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
new file mode 100644
index 0000000000..a1ade722e8
--- /dev/null
+++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt
@@ -0,0 +1,146 @@
+/*************************************************************************/
+/* GodotEditor.kt */
+/*************************************************************************/
+/* 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 android.content.Intent
+import android.os.Build
+import android.os.Bundle
+import android.os.Debug
+import androidx.window.layout.WindowMetricsCalculator
+import org.godotengine.godot.FullScreenGodotApp
+import org.godotengine.godot.utils.PermissionsUtil
+import java.util.*
+import kotlin.math.min
+
+/**
+ * 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.
+ */
+open class GodotEditor : FullScreenGodotApp() {
+
+ companion object {
+ private const val WAIT_FOR_DEBUGGER = false
+
+ private const val COMMAND_LINE_PARAMS = "command_line_params"
+
+ private const val EDITOR_ARG = "--editor"
+ private const val PROJECT_MANAGER_ARG = "--project-manager"
+ }
+
+ private val commandLineParams = ArrayList<String>()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ PermissionsUtil.requestManifestPermissions(this)
+
+ val params = intent.getStringArrayExtra(COMMAND_LINE_PARAMS)
+ updateCommandLineParams(params)
+
+ if (BuildConfig.BUILD_TYPE == "debug" && WAIT_FOR_DEBUGGER) {
+ Debug.waitForDebugger()
+ }
+
+ super.onCreate(savedInstanceState)
+ }
+
+ private fun updateCommandLineParams(args: Array<String>?) {
+ // Update the list of command line params with the new args
+ commandLineParams.clear()
+ if (args != null && args.isNotEmpty()) {
+ commandLineParams.addAll(listOf(*args))
+ }
+ }
+
+ override fun getCommandLine() = commandLineParams
+
+ override fun onNewGodotInstanceRequested(args: Array<String>) {
+ // Parse the arguments to figure out which activity to start.
+ var targetClass: Class<*> = GodotGame::class.java
+
+ // Whether we should launch the new godot instance in an adjacent window
+ // https://developer.android.com/reference/android/content/Intent#FLAG_ACTIVITY_LAUNCH_ADJACENT
+ var launchAdjacent =
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen)
+
+ for (arg in args) {
+ if (EDITOR_ARG == arg) {
+ targetClass = GodotEditor::class.java
+ launchAdjacent = false
+ break
+ }
+
+ if (PROJECT_MANAGER_ARG == arg) {
+ targetClass = GodotProjectManager::class.java
+ launchAdjacent = false
+ break
+ }
+ }
+
+ // Launch a new activity
+ val newInstance = Intent(this, targetClass)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .putExtra(COMMAND_LINE_PARAMS, args)
+ if (launchAdjacent) {
+ newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT)
+ }
+ startActivity(newInstance)
+ }
+
+ // Get the screen's density scale
+ protected val isLargeScreen: Boolean
+ // Get the minimum window size // Correspond to the EXPANDED window size class.
+ get() {
+ val metrics = WindowMetricsCalculator.getOrCreate().computeMaximumWindowMetrics(this)
+
+ // Get the screen's density scale
+ val scale = resources.displayMetrics.density
+
+ // Get the minimum window size
+ val minSize = min(metrics.bounds.width(), metrics.bounds.height()).toFloat()
+ val minSizeDp = minSize / scale
+ return minSizeDp >= 840f // Correspond to the EXPANDED window size class.
+ }
+
+ override fun setRequestedOrientation(requestedOrientation: Int) {
+ if (!overrideOrientationRequest()) {
+ super.setRequestedOrientation(requestedOrientation)
+ }
+ }
+
+ /**
+ * The Godot Android Editor sets its own orientation via its AndroidManifest
+ */
+ protected open fun overrideOrientationRequest() = true
+}
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.kt
index 12766775a8..783095f93a 100644
--- 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.kt
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotGame.java */
+/* GodotGame.kt */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,13 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.editor;
+package org.godotengine.editor
/**
* Drives the 'run project' window of the Godot Editor.
*/
-public class GodotGame extends GodotEditor {
- protected boolean overrideOrientationRequest() {
- return false;
- }
+class GodotGame : GodotEditor() {
+ override fun overrideOrientationRequest() = false
}
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.kt
index d30f66bb8c..bcf4659603 100644
--- 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.kt
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* GodotProjectManager.java */
+/* GodotProjectManager.kt */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,14 +28,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-package org.godotengine.editor;
+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.
+ * [GodotEditor] activity.
*/
-public class GodotProjectManager extends GodotEditor {
-}
+class GodotProjectManager : GodotEditor()
diff --git a/platform/android/java/editor/src/main/res/values/dimens.xml b/platform/android/java/editor/src/main/res/values/dimens.xml
new file mode 100644
index 0000000000..03fb6184d2
--- /dev/null
+++ b/platform/android/java/editor/src/main/res/values/dimens.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <dimen name="editor_default_window_height">600dp</dimen>
+ <dimen name="editor_default_window_width">800dp</dimen>
+</resources>
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index 2de62271c4..90dc61a6ac 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -16,12 +16,13 @@
<service android:name=".GodotDownloaderService" />
- </application>
+ <activity
+ android:name=".utils.ProcessPhoenix"
+ android:theme="@android:style/Theme.Translucent.NoTitleBar"
+ android:process=":phoenix"
+ android:exported="false"
+ />
- <instrumentation
- android:icon="@mipmap/icon"
- android:label="@string/godot_project_name_string"
- android:name="org.godotengine.godot.GodotInstrumentation"
- android:targetPackage="org.godotengine.godot" />
+ </application>
</manifest>
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index c806de1ded..6b82326a27 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -1,5 +1,7 @@
-apply plugin: 'com.android.library'
-apply plugin: 'kotlin-android'
+plugins {
+ id 'com.android.library'
+ id 'org.jetbrains.kotlin.android'
+}
ext {
PUBLISH_VERSION = getGodotPublishVersion()
@@ -34,6 +36,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
buildTypes {
dev {
initWith debug
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index fb1604f6af..f21f88db0a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -30,7 +30,8 @@
package org.godotengine.godot;
-import android.content.ComponentName;
+import org.godotengine.godot.utils.ProcessPhoenix;
+
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
@@ -71,6 +72,7 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
@Override
public void onDestroy() {
+ Log.v(TAG, "Destroying Godot app...");
super.onDestroy();
onGodotForceQuit(godotFragment);
}
@@ -78,27 +80,21 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
@Override
public final void onGodotForceQuit(Godot instance) {
if (instance == godotFragment) {
- System.exit(0);
+ Log.v(TAG, "Force quitting Godot instance");
+ ProcessPhoenix.forceQuit(this);
}
}
@Override
public final void onGodotRestartRequested(Godot instance) {
if (instance == godotFragment) {
- // HACK:
- //
- // Currently it's very hard to properly deinitialize Godot on Android to restart the game
+ // It's very hard to properly de-initialize Godot on Android to restart the game
// from scratch. Therefore, we need to kill the whole app process and relaunch it.
//
// Restarting only the activity, wouldn't be enough unless it did proper cleanup (including
// releasing and reloading native libs or resetting their state somehow and clearing statics).
- //
- // Using instrumentation is a way of making the whole app process restart, because Android
- // will kill any process of the same package which was already running.
- //
- Bundle args = new Bundle();
- args.putParcelable("intent", getIntent());
- startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args);
+ Log.v(TAG, "Restarting Godot instance...");
+ ProcessPhoenix.triggerRebirth(this);
}
}
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 377881be85..cafae94d62 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -463,13 +463,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
tts = new GodotTTS(activity);
mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
- mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
- mSensorManager.registerListener(this, mGravity, SensorManager.SENSOR_DELAY_GAME);
mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
- mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
- mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
GodotLib.initialize(activity, this, activity.getAssets(), use_apk_expansion);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
index b69d25dd8b..a8e3669ac6 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java
@@ -224,12 +224,30 @@ public class GodotIO {
}
public int getScreenDPI() {
- DisplayMetrics metrics = activity.getResources().getDisplayMetrics();
- return (int)(metrics.density * 160f);
+ return activity.getResources().getDisplayMetrics().densityDpi;
}
+ /**
+ * Returns bucketized density values.
+ */
public float getScaledDensity() {
- return activity.getResources().getDisplayMetrics().scaledDensity;
+ int densityDpi = activity.getResources().getDisplayMetrics().densityDpi;
+ float selectedScaledDensity;
+ if (densityDpi >= DisplayMetrics.DENSITY_XXXHIGH) {
+ selectedScaledDensity = 4.0f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_XXHIGH) {
+ selectedScaledDensity = 3.0f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_XHIGH) {
+ selectedScaledDensity = 2.0f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_HIGH) {
+ selectedScaledDensity = 1.5f;
+ } else if (densityDpi >= DisplayMetrics.DENSITY_MEDIUM) {
+ selectedScaledDensity = 1.0f;
+ } else {
+ selectedScaledDensity = 0.75f;
+ }
+ Log.d(TAG, "Selected scaled density: " + selectedScaledDensity);
+ return selectedScaledDensity;
}
public double getScreenRefreshRate(double fallback) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
deleted file mode 100644
index 44f0a3eb3e..0000000000
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*************************************************************************/
-/* GodotInstrumentation.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.godot;
-
-import android.app.Instrumentation;
-import android.content.Intent;
-import android.os.Bundle;
-
-public class GodotInstrumentation extends Instrumentation {
- private Intent intent;
-
- @Override
- public void onCreate(Bundle arguments) {
- intent = arguments.getParcelable("intent");
- start();
- }
-
- @Override
- public void onStart() {
- startActivitySync(intent);
- }
-}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
index 8694bb91e1..ccfb865b1a 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java
@@ -186,6 +186,9 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
if (mJoystickIds.indexOfKey(deviceId) >= 0) {
final int godotJoyId = mJoystickIds.get(deviceId);
Joystick joystick = mJoysticksDevices.get(deviceId);
+ if (joystick == null) {
+ return true;
+ }
for (int i = 0; i < joystick.axes.size(); i++) {
final int axis = joystick.axes.get(i);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java b/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java
new file mode 100644
index 0000000000..2cc37b627a
--- /dev/null
+++ b/platform/android/java/lib/src/org/godotengine/godot/utils/ProcessPhoenix.java
@@ -0,0 +1,141 @@
+// clang-format off
+
+/* Third-party library.
+ * Upstream: https://github.com/JakeWharton/ProcessPhoenix
+ * Commit: 12cb27c2cc9c3fc555e97f2db89e571667de82c4
+ */
+
+/*
+ * Copyright (C) 2014 Jake Wharton
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.godotengine.godot.utils;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Process;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+
+/**
+ * Process Phoenix facilitates restarting your application process. This should only be used for
+ * things like fundamental state changes in your debug builds (e.g., changing from staging to
+ * production).
+ * <p>
+ * Trigger process recreation by calling {@link #triggerRebirth} with a {@link Context} instance.
+ */
+public final class ProcessPhoenix extends Activity {
+ private static final String KEY_RESTART_INTENTS = "phoenix_restart_intents";
+ private static final String KEY_MAIN_PROCESS_PID = "phoenix_main_process_pid";
+
+ /**
+ * Call to restart the application process using the {@linkplain Intent#CATEGORY_DEFAULT default}
+ * activity as an intent.
+ * <p>
+ * Behavior of the current process after invoking this method is undefined.
+ */
+ public static void triggerRebirth(Context context) {
+ triggerRebirth(context, getRestartIntent(context));
+ }
+
+ /**
+ * Call to restart the application process using the specified intents.
+ * <p>
+ * Behavior of the current process after invoking this method is undefined.
+ */
+ public static void triggerRebirth(Context context, Intent... nextIntents) {
+ if (nextIntents.length < 1) {
+ throw new IllegalArgumentException("intents cannot be empty");
+ }
+ // create a new task for the first activity.
+ nextIntents[0].addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
+
+ Intent intent = new Intent(context, ProcessPhoenix.class);
+ intent.addFlags(FLAG_ACTIVITY_NEW_TASK); // In case we are called with non-Activity context.
+ intent.putParcelableArrayListExtra(KEY_RESTART_INTENTS, new ArrayList<>(Arrays.asList(nextIntents)));
+ intent.putExtra(KEY_MAIN_PROCESS_PID, Process.myPid());
+ context.startActivity(intent);
+ }
+
+ // -- GODOT start --
+ /**
+ * Finish the activity and kill its process
+ */
+ public static void forceQuit(Activity activity) {
+ forceQuit(activity, Process.myPid());
+ }
+
+ /**
+ * Finish the activity and kill its process
+ * @param activity
+ * @param pid
+ */
+ public static void forceQuit(Activity activity, int pid) {
+ Process.killProcess(pid); // Kill original main process
+ activity.finish();
+ Runtime.getRuntime().exit(0); // Kill kill kill!
+ }
+
+ // -- GODOT end --
+
+ private static Intent getRestartIntent(Context context) {
+ String packageName = context.getPackageName();
+ Intent defaultIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
+ if (defaultIntent != null) {
+ return defaultIntent;
+ }
+
+ throw new IllegalStateException("Unable to determine default activity for "
+ + packageName
+ + ". Does an activity specify the DEFAULT category in its intent filter?");
+ }
+
+ @Override protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // -- GODOT start --
+ ArrayList<Intent> intents = getIntent().getParcelableArrayListExtra(KEY_RESTART_INTENTS);
+ startActivities(intents.toArray(new Intent[intents.size()]));
+ forceQuit(this, getIntent().getIntExtra(KEY_MAIN_PROCESS_PID, -1));
+ // -- GODOT end --
+ }
+
+ /**
+ * Checks if the current process is a temporary Phoenix Process.
+ * This can be used to avoid initialisation of unused resources or to prevent running code that
+ * is not multi-process ready.
+ *
+ * @return true if the current process is a temporary Phoenix Process
+ */
+ public static boolean isPhoenixProcess(Context context) {
+ int currentPid = Process.myPid();
+ ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ List<ActivityManager.RunningAppProcessInfo> runningProcesses = manager.getRunningAppProcesses();
+ if (runningProcesses != null) {
+ for (ActivityManager.RunningAppProcessInfo processInfo : runningProcesses) {
+ if (processInfo.pid == currentPid && processInfo.processName.endsWith(":phoenix")) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
diff --git a/platform/android/java/nativeSrcsConfigs/build.gradle b/platform/android/java/nativeSrcsConfigs/build.gradle
index 0cb769b539..5e810ae1ba 100644
--- a/platform/android/java/nativeSrcsConfigs/build.gradle
+++ b/platform/android/java/nativeSrcsConfigs/build.gradle
@@ -1,6 +1,7 @@
// Non functional android library used to provide Android Studio editor support to the project.
plugins {
id 'com.android.library'
+ id 'org.jetbrains.kotlin.android'
}
android {
@@ -18,6 +19,10 @@ android {
targetCompatibility versions.javaVersion
}
+ kotlinOptions {
+ jvmTarget = versions.javaVersion
+ }
+
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/NOTICE'
diff --git a/platform/android/java/settings.gradle b/platform/android/java/settings.gradle
index 56e1b6fd3a..466ffebf22 100644
--- a/platform/android/java/settings.gradle
+++ b/platform/android/java/settings.gradle
@@ -1,4 +1,19 @@
// Configure the root project.
+pluginManagement {
+ apply from: 'app/config.gradle'
+
+ plugins {
+ id 'com.android.application' version versions.androidGradlePlugin
+ id 'com.android.library' version versions.androidGradlePlugin
+ id 'org.jetbrains.kotlin.android' version versions.kotlinVersion
+ id 'io.github.gradle-nexus.publish-plugin' version versions.nexusPublishVersion
+ }
+ repositories {
+ gradlePluginPortal()
+ google()
+ }
+}
+
rootProject.name = "Godot"
include ':app'