From abcdad7a722c68284559795cf8ab4860c985e5ed Mon Sep 17 00:00:00 2001 From: Jamie Pate Date: Thu, 2 Jan 2025 12:44:40 -0800 Subject: [PATCH] Fix create_instance in android GodotApp so non-editor apps can restart Enables OS.create_instance(args) and OS.set_restart_on_exit(true, args) on android. Borrowed the logic from the editor, so it completely restarts the process so you can pass --rendering-method, --rendering-driver to switch between forward_plus, mobile, gl_compatibility etc on an exported app. Related: https://github.com/godotengine/godot-proposals/issues/6423 --- .../java/app/src/com/godot/game/GodotApp.java | 36 +++++++++++++++++++ .../org/godotengine/editor/BaseGodotEditor.kt | 12 ++----- .../lib/src/org/godotengine/godot/Godot.kt | 23 ++++++++++-- .../org/godotengine/godot/GodotActivity.kt | 15 ++++++++ 4 files changed, 73 insertions(+), 13 deletions(-) diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java index 9d4991e12006..8be4381cd7f9 100644 --- a/platform/android/java/app/src/com/godot/game/GodotApp.java +++ b/platform/android/java/app/src/com/godot/game/GodotApp.java @@ -30,13 +30,21 @@ package com.godot.game; +import org.godotengine.godot.Godot; import org.godotengine.godot.GodotActivity; +import org.godotengine.godot.utils.ProcessPhoenix; +import android.content.ComponentName; +import android.content.Intent; import android.os.Bundle; import android.util.Log; import androidx.core.splashscreen.SplashScreen; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + import com.godot.game.BuildConfig; /** @@ -56,8 +64,36 @@ public class GodotApp extends GodotActivity { } } + // Shouldn't conflict with BaseGodotEditor.RUN_GAME_INFO etc + private final static int WINDOW_ID = 668; + private final static String TAG = GodotApp.class.getSimpleName(); + + private ArrayList commandLineParams = new ArrayList(); + + @Override + public int onNewGodotInstanceRequested(String[] args) { + // Launch a new activity + Log.d(TAG, "Restarting with parameters " + String.join(",", args)); + Godot godot = getGodot(); + Intent newInstance = new Intent() + .setComponent(new ComponentName(this, GodotApp.class)) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + .putExtra(getEXTRA_COMMAND_LINE_PARAMS(), args); + if (godot != null) { + godot.destroyAndKillProcess( + () -> ProcessPhoenix.triggerRebirth(this, newInstance)); + } else { + ProcessPhoenix.triggerRebirth(this, newInstance); + } + return WINDOW_ID; + } + @Override public void onCreate(Bundle savedInstanceState) { + Intent intent = getIntent(); + String[] params = intent.getStringArrayExtra(getEXTRA_COMMAND_LINE_PARAMS()); + Log.d(TAG, "Starting intent " + intent + " with parameters " + (params != null ? String.join(" ", params) : "null")); + updateCommandLineParams(params != null && params.length > 0 ? Arrays.asList(params) : Collections.emptyList()); SplashScreen.installSplashScreen(this); super.onCreate(savedInstanceState); } diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt index 11ac4c85ec3c..70e7b90b125a 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt @@ -71,8 +71,6 @@ abstract class BaseGodotEditor : GodotActivity() { private const val WAIT_FOR_DEBUGGER = false - @JvmStatic - protected val EXTRA_COMMAND_LINE_PARAMS = "command_line_params" @JvmStatic protected val EXTRA_PIP_AVAILABLE = "pip_available" @JvmStatic @@ -116,7 +114,6 @@ abstract class BaseGodotEditor : GodotActivity() { } private val editorMessageDispatcher = EditorMessageDispatcher(this) - private val commandLineParams = ArrayList() private val editorLoadingIndicator: View? by lazy { findViewById(R.id.editor_loading_indicator) } override fun getGodotAppLayout() = R.layout.godot_editor_layout @@ -196,17 +193,12 @@ abstract class BaseGodotEditor : GodotActivity() { @CallSuper protected open fun updateCommandLineParams(args: List) { // Update the list of command line params with the new args - commandLineParams.clear() - if (args.isNotEmpty()) { - commandLineParams.addAll(args) - } + super(args) if (BuildConfig.BUILD_TYPE == "dev") { - commandLineParams.add("--benchmark") + getCommandLine().add("--benchmark") } } - final override fun getCommandLine() = commandLineParams - protected open fun retrieveEditorWindowInfo(args: Array): EditorWindowInfo { var hasEditor = false diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt index fcbb8830f901..a3aacadf49f4 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt @@ -823,9 +823,26 @@ class Godot(private val context: Context) { * Returns true if `Vulkan` is used for rendering. */ private fun usesVulkan(): Boolean { - val renderer = GodotLib.getGlobal("rendering/renderer/rendering_method") - val renderingDevice = GodotLib.getGlobal("rendering/rendering_device/driver") - return ("forward_plus" == renderer || "mobile" == renderer) && "vulkan" == renderingDevice + var rendererSource = "ProjectSettings" + var renderer = GodotLib.getGlobal("rendering/renderer/rendering_method") + var renderingDeviceSource = "ProjectSettings" + var renderingDevice = GodotLib.getGlobal("rendering/rendering_device/driver") + val cmdline = getCommandLine() + var index = cmdline.indexOf("--rendering-method") + if (index > -1 && cmdline.size > index + 1) { + rendererSource = "CommandLine" + renderer = cmdline.get(index + 1) + } + index = cmdline.indexOf("--rendering-driver") + if (index > -1 && cmdline.size > index + 1) { + renderingDeviceSource = "CommandLine" + renderingDevice = cmdline.get(index + 1) + } + val result = ("forward_plus" == renderer || "mobile" == renderer) && "vulkan" == renderingDevice + Log.d(TAG, """usesVulkan(): ${result} + renderingDevice: ${renderingDevice} (${renderingDeviceSource}) + renderer: ${renderer} (${rendererSource})""") + return result } /** diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt b/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt index 474c6e9b2fb2..635c4d1b725c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotActivity.kt @@ -52,10 +52,14 @@ abstract class GodotActivity : FragmentActivity(), GodotHost { companion object { private val TAG = GodotActivity::class.java.simpleName + @JvmStatic + protected val EXTRA_COMMAND_LINE_PARAMS = "command_line_params" + @JvmStatic protected val EXTRA_NEW_LAUNCH = "new_launch_requested" } + private val commandLineParams = ArrayList() /** * Interaction with the [Godot] object is delegated to the [GodotFragment] class. */ @@ -176,4 +180,15 @@ abstract class GodotActivity : FragmentActivity(), GodotHost { protected open fun initGodotInstance(): GodotFragment { return GodotFragment() } + + @CallSuper + protected open fun updateCommandLineParams(args: List) { + // Update the list of command line params with the new args + commandLineParams.clear() + if (args.isNotEmpty()) { + commandLineParams.addAll(args) + } + } + + final override fun getCommandLine() = commandLineParams }