diff options
| author | Fredia Huya-Kouadio <fhuya@meta.com> | 2024-04-20 10:24:11 -0700 |
|---|---|---|
| committer | Fredia Huya-Kouadio <fhuya@meta.com> | 2024-09-06 00:35:50 -0700 |
| commit | 9dc0543da7323e970f4349e65b416ef31056df20 (patch) | |
| tree | 7350403dbba62a1a74830cbdb44978cdb7bda4ae /platform/android/java/editor/src | |
| parent | 835808ed8fa992c961d6989f0a0c48ed2abd69bd (diff) | |
| download | redot-engine-9dc0543da7323e970f4349e65b416ef31056df20.tar.gz | |
Improve support for XR projects
Diffstat (limited to 'platform/android/java/editor/src')
| -rw-r--r-- | platform/android/java/editor/src/google/java/org/godotengine/editor/GodotEditor.kt | 39 | ||||
| -rw-r--r-- | platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt (renamed from platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt) | 100 | ||||
| -rw-r--r-- | platform/android/java/editor/src/main/java/org/godotengine/editor/EditorMessageDispatcher.kt | 10 | ||||
| -rw-r--r-- | platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt | 57 | ||||
| -rw-r--r-- | platform/android/java/editor/src/meta/AndroidManifest.xml | 99 | ||||
| -rw-r--r-- | platform/android/java/editor/src/meta/assets/vr_splash.png | bin | 0 -> 14766 bytes | |||
| -rw-r--r-- | platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotEditor.kt | 94 | ||||
| -rw-r--r-- | platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotXRGame.kt | 71 |
8 files changed, 421 insertions, 49 deletions
diff --git a/platform/android/java/editor/src/google/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/google/java/org/godotengine/editor/GodotEditor.kt new file mode 100644 index 0000000000..f15d9f7768 --- /dev/null +++ b/platform/android/java/editor/src/google/java/org/godotengine/editor/GodotEditor.kt @@ -0,0 +1,39 @@ +/**************************************************************************/ +/* GodotEditor.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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 + +/** + * Primary window of the Godot Editor. + * + * This is the implementation of the editor used when running on regular Android devices. + */ +open class GodotEditor : BaseGodotEditor() { +} 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/BaseGodotEditor.kt index 405b2fb57f..50daf44d2a 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt @@ -1,5 +1,5 @@ /**************************************************************************/ -/* GodotEditor.kt */ +/* BaseGodotEditor.kt */ /**************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -52,6 +52,8 @@ import org.godotengine.godot.GodotLib import org.godotengine.godot.error.Error import org.godotengine.godot.utils.PermissionsUtil import org.godotengine.godot.utils.ProcessPhoenix +import org.godotengine.godot.utils.isHorizonOSDevice +import org.godotengine.godot.utils.isNativeXRDevice import java.util.* import kotlin.math.min @@ -61,13 +63,11 @@ import kotlin.math.min * 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 : GodotActivity() { +abstract class BaseGodotEditor : GodotActivity() { companion object { - private val TAG = GodotEditor::class.java.simpleName + private val TAG = BaseGodotEditor::class.java.simpleName private const val WAIT_FOR_DEBUGGER = false @@ -81,12 +81,13 @@ open class GodotEditor : GodotActivity() { // Command line arguments private const val FULLSCREEN_ARG = "--fullscreen" private const val FULLSCREEN_ARG_SHORT = "-f" - private const val EDITOR_ARG = "--editor" - private const val EDITOR_ARG_SHORT = "-e" - private const val EDITOR_PROJECT_MANAGER_ARG = "--project-manager" - private const val EDITOR_PROJECT_MANAGER_ARG_SHORT = "-p" - private const val BREAKPOINTS_ARG = "--breakpoints" - private const val BREAKPOINTS_ARG_SHORT = "-b" + internal const val EDITOR_ARG = "--editor" + internal const val EDITOR_ARG_SHORT = "-e" + internal const val EDITOR_PROJECT_MANAGER_ARG = "--project-manager" + internal const val EDITOR_PROJECT_MANAGER_ARG_SHORT = "-p" + internal const val BREAKPOINTS_ARG = "--breakpoints" + internal const val BREAKPOINTS_ARG_SHORT = "-b" + internal const val XR_MODE_ARG = "--xr-mode" // Info for the various classes used by the editor internal val EDITOR_MAIN_INFO = EditorWindowInfo(GodotEditor::class.java, 777, "") @@ -122,6 +123,20 @@ open class GodotEditor : GodotActivity() { internal open fun getEditorWindowInfo() = EDITOR_MAIN_INFO + /** + * Set of permissions to be excluded when requesting all permissions at startup. + * + * The permissions in this set will be requested on demand based on use cases. + */ + @CallSuper + protected open fun getExcludedPermissions(): MutableSet<String> { + return mutableSetOf( + // The RECORD_AUDIO permission is requested when the "audio/driver/enable_input" project + // setting is enabled. + Manifest.permission.RECORD_AUDIO + ) + } + override fun onCreate(savedInstanceState: Bundle?) { installSplashScreen() @@ -131,8 +146,8 @@ open class GodotEditor : GodotActivity() { } // We exclude certain permissions from the set we request at startup, as they'll be - // requested on demand based on use-cases. - PermissionsUtil.requestManifestPermissions(this, setOf(Manifest.permission.RECORD_AUDIO)) + // requested on demand based on use cases. + PermissionsUtil.requestManifestPermissions(this, getExcludedPermissions()) val params = intent.getStringArrayExtra(EXTRA_COMMAND_LINE_PARAMS) Log.d(TAG, "Starting intent $intent with parameters ${params.contentToString()}") @@ -152,8 +167,6 @@ open class GodotEditor : GodotActivity() { val longPressEnabled = enableLongPressGestures() val panScaleEnabled = enablePanAndScaleGestures() - checkForProjectPermissionsToEnable() - runOnUiThread { // Enable long press, panning and scaling gestures godotFragment?.godot?.renderView?.inputHandler?.apply { @@ -171,17 +184,6 @@ open class GodotEditor : GodotActivity() { } } - /** - * Check for project permissions to enable - */ - protected open fun checkForProjectPermissionsToEnable() { - // Check for RECORD_AUDIO permission - val audioInputEnabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("audio/driver/enable_input")) - if (audioInputEnabled) { - PermissionsUtil.requestPermission(Manifest.permission.RECORD_AUDIO, this) - } - } - @CallSuper protected open fun updateCommandLineParams(args: List<String>) { // Update the list of command line params with the new args @@ -196,7 +198,7 @@ open class GodotEditor : GodotActivity() { final override fun getCommandLine() = commandLineParams - protected open fun getEditorWindowInfo(args: Array<String>): EditorWindowInfo { + protected open fun retrieveEditorWindowInfo(args: Array<String>): EditorWindowInfo { var hasEditor = false var i = 0 @@ -273,7 +275,7 @@ open class GodotEditor : GodotActivity() { } override fun onNewGodotInstanceRequested(args: Array<String>): Int { - val editorWindowInfo = getEditorWindowInfo(args) + val editorWindowInfo = retrieveEditorWindowInfo(args) // Launch a new activity val sourceView = godotFragment?.view @@ -405,20 +407,26 @@ open class GodotEditor : GodotActivity() { return when (policy) { LaunchPolicy.AUTO -> { - try { - when (Integer.parseInt(GodotLib.getEditorSetting("run/window_placement/android_window"))) { - ANDROID_WINDOW_SAME_AS_EDITOR -> LaunchPolicy.SAME - ANDROID_WINDOW_SIDE_BY_SIDE_WITH_EDITOR -> LaunchPolicy.ADJACENT - ANDROID_WINDOW_SAME_AS_EDITOR_AND_LAUNCH_IN_PIP_MODE -> LaunchPolicy.SAME_AND_LAUNCH_IN_PIP_MODE - else -> { - // ANDROID_WINDOW_AUTO - defaultLaunchPolicy + if (isHorizonOSDevice()) { + // Horizon OS UX is more desktop-like and has support for launching adjacent + // windows. So we always want to launch in adjacent mode when auto is selected. + LaunchPolicy.ADJACENT + } else { + try { + when (Integer.parseInt(GodotLib.getEditorSetting("run/window_placement/android_window"))) { + ANDROID_WINDOW_SAME_AS_EDITOR -> LaunchPolicy.SAME + ANDROID_WINDOW_SIDE_BY_SIDE_WITH_EDITOR -> LaunchPolicy.ADJACENT + ANDROID_WINDOW_SAME_AS_EDITOR_AND_LAUNCH_IN_PIP_MODE -> LaunchPolicy.SAME_AND_LAUNCH_IN_PIP_MODE + else -> { + // ANDROID_WINDOW_AUTO + defaultLaunchPolicy + } } + } catch (e: NumberFormatException) { + Log.w(TAG, "Error parsing the Android window placement editor setting", e) + // Fall-back to the default launch policy + defaultLaunchPolicy } - } catch (e: NumberFormatException) { - Log.w(TAG, "Error parsing the Android window placement editor setting", e) - // Fall-back to the default launch policy - defaultLaunchPolicy } } @@ -431,8 +439,16 @@ open class GodotEditor : GodotActivity() { /** * Returns true the if the device supports picture-in-picture (PiP) */ - protected open fun hasPiPSystemFeature() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && - packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) + protected open fun hasPiPSystemFeature(): Boolean { + if (isNativeXRDevice()) { + // Known native XR devices do not support PiP. + // Will need to revisit as they update their OS. + return false + } + + return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && + packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE) + } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/EditorMessageDispatcher.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/EditorMessageDispatcher.kt index b16e62149a..f5a6ed7dab 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/EditorMessageDispatcher.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/EditorMessageDispatcher.kt @@ -42,9 +42,9 @@ import android.util.Log import java.util.concurrent.ConcurrentHashMap /** - * Used by the [GodotEditor] classes to dispatch messages across processes. + * Used by the [BaseGodotEditor] classes to dispatch messages across processes. */ -internal class EditorMessageDispatcher(private val editor: GodotEditor) { +internal class EditorMessageDispatcher(private val editor: BaseGodotEditor) { companion object { private val TAG = EditorMessageDispatcher::class.java.simpleName @@ -173,7 +173,11 @@ internal class EditorMessageDispatcher(private val editor: GodotEditor) { // to the sender. val senderId = messengerBundle.getInt(KEY_EDITOR_ID) val senderMessenger: Messenger? = messengerBundle.getParcelable(KEY_EDITOR_MESSENGER) - registerMessenger(senderId, senderMessenger) + registerMessenger(senderId, senderMessenger) { + // Terminate current instance when parent is no longer available. + Log.d(TAG, "Terminating current editor instance because parent is no longer available") + editor.finish() + } // Register ourselves to the sender so that it can communicate with us. registerSelfTo(pm, senderMessenger, editor.getEditorWindowInfo().windowId) diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt index 6b4bf255f2..e52d566347 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/GodotGame.kt @@ -30,6 +30,7 @@ package org.godotengine.editor +import android.Manifest import android.annotation.SuppressLint import android.app.PictureInPictureParams import android.content.Intent @@ -38,12 +39,15 @@ import android.os.Build import android.os.Bundle import android.util.Log import android.view.View +import androidx.annotation.CallSuper import org.godotengine.godot.GodotLib +import org.godotengine.godot.utils.PermissionsUtil +import org.godotengine.godot.utils.ProcessPhoenix /** * Drives the 'run project' window of the Godot Editor. */ -class GodotGame : GodotEditor() { +open class GodotGame : GodotEditor() { companion object { private val TAG = GodotGame::class.java.simpleName @@ -136,8 +140,53 @@ class GodotGame : GodotEditor() { override fun enablePanAndScaleGestures() = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("input_devices/pointing/android/enable_pan_and_scale_gestures")) - override fun checkForProjectPermissionsToEnable() { - // Nothing to do.. by the time we get here, the project permissions will have already - // been requested by the Editor window. + override fun onGodotSetupCompleted() { + super.onGodotSetupCompleted() + Log.v(TAG, "OnGodotSetupCompleted") + + // Check if we should be running in XR instead (if available) as it's possible we were + // launched from the project manager which doesn't have that information. + val launchingArgs = intent.getStringArrayExtra(EXTRA_COMMAND_LINE_PARAMS) + if (launchingArgs != null) { + val editorWindowInfo = retrieveEditorWindowInfo(launchingArgs) + if (editorWindowInfo != getEditorWindowInfo()) { + val relaunchIntent = getNewGodotInstanceIntent(editorWindowInfo, launchingArgs) + relaunchIntent.putExtra(EXTRA_NEW_LAUNCH, true) + .putExtra(EditorMessageDispatcher.EXTRA_MSG_DISPATCHER_PAYLOAD, intent.getBundleExtra(EditorMessageDispatcher.EXTRA_MSG_DISPATCHER_PAYLOAD)) + + Log.d(TAG, "Relaunching XR project using ${editorWindowInfo.windowClassName} with parameters ${launchingArgs.contentToString()}") + val godot = godot + if (godot != null) { + godot.destroyAndKillProcess { + ProcessPhoenix.triggerRebirth(this, relaunchIntent) + } + } else { + ProcessPhoenix.triggerRebirth(this, relaunchIntent) + } + return + } + } + + // Request project runtime permissions if necessary + val permissionsToEnable = getProjectPermissionsToEnable() + if (permissionsToEnable.isNotEmpty()) { + PermissionsUtil.requestPermissions(this, permissionsToEnable) + } + } + + /** + * Check for project permissions to enable + */ + @CallSuper + protected open fun getProjectPermissionsToEnable(): MutableList<String> { + val permissionsToEnable = mutableListOf<String>() + + // Check for RECORD_AUDIO permission + val audioInputEnabled = java.lang.Boolean.parseBoolean(GodotLib.getGlobal("audio/driver/enable_input")) + if (audioInputEnabled) { + permissionsToEnable.add(Manifest.permission.RECORD_AUDIO) + } + + return permissionsToEnable } } diff --git a/platform/android/java/editor/src/meta/AndroidManifest.xml b/platform/android/java/editor/src/meta/AndroidManifest.xml new file mode 100644 index 0000000000..06442ac4e6 --- /dev/null +++ b/platform/android/java/editor/src/meta/AndroidManifest.xml @@ -0,0 +1,99 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + xmlns:horizonos="http://schemas.horizonos/sdk"> + + <horizonos:uses-horizonos-sdk + horizonos:minSdkVersion="69" + horizonos:targetSdkVersion="69" /> + + <uses-feature + android:name="android.hardware.vr.headtracking" + android:required="true" + android:version="1"/> + + <!-- Oculus Quest hand tracking --> + <uses-permission android:name="com.oculus.permission.HAND_TRACKING" /> + <uses-feature + android:name="oculus.software.handtracking" + android:required="false" /> + + <!-- Passthrough feature flag --> + <uses-feature android:name="com.oculus.feature.PASSTHROUGH" + android:required="false" /> + + <!-- Overlay keyboard support --> + <uses-feature android:name="oculus.software.overlay_keyboard" android:required="false"/> + + <!-- Render model --> + <uses-permission android:name="com.oculus.permission.RENDER_MODEL" /> + <uses-feature android:name="com.oculus.feature.RENDER_MODEL" android:required="false" /> + + <!-- Anchor api --> + <uses-permission android:name="com.oculus.permission.USE_ANCHOR_API" /> + + <!-- Scene api --> + <uses-permission android:name="com.oculus.permission.USE_SCENE" /> + + <application> + + <activity + android:name=".GodotEditor" + android:exported="true" + android:screenOrientation="landscape" + tools:node="merge" + tools:replace="android:screenOrientation"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.LAUNCHER" /> + <category android:name="com.oculus.intent.category.2D" /> + </intent-filter> + + <meta-data android:name="com.oculus.vrshell.free_resizing_lock_aspect_ratio" android:value="true"/> + </activity> + + <activity + android:name=".GodotXRGame" + android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" + android:process=":GodotXRGame" + android:launchMode="singleTask" + android:icon="@mipmap/ic_play_window" + android:label="@string/godot_game_activity_name" + android:exported="false" + android:screenOrientation="landscape" + android:resizeableActivity="false" + android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="com.oculus.intent.category.VR" /> + <category android:name="org.khronos.openxr.intent.category.IMMERSIVE_HMD" /> + </intent-filter> + </activity> + + <!-- Supported Meta devices --> + <meta-data + android:name="com.oculus.supportedDevices" + android:value="quest3|questpro" + tools:replace="android:value" /> + + <!-- + We remove this meta-data originating from the vendors plugin as we only need the loader for + now since the project being edited provides its own version of the vendors plugin. + + This needs to be removed once we start implementing the immersive version of the project + manager and editor windows. + --> + <meta-data + android:name="org.godotengine.plugin.v2.GodotOpenXRMeta" + android:value="org.godotengine.openxr.vendors.meta.GodotOpenXRMeta" + tools:node="remove" /> + + <!-- Enable system splash screen --> + <meta-data android:name="com.oculus.ossplash" android:value="true"/> + <!-- Enable passthrough background during the splash screen --> + <meta-data android:name="com.oculus.ossplash.background" android:value="passthrough-contextual"/> + + </application> + +</manifest> diff --git a/platform/android/java/editor/src/meta/assets/vr_splash.png b/platform/android/java/editor/src/meta/assets/vr_splash.png Binary files differnew file mode 100644 index 0000000000..7bddd4325a --- /dev/null +++ b/platform/android/java/editor/src/meta/assets/vr_splash.png diff --git a/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotEditor.kt new file mode 100644 index 0000000000..9f0440e87d --- /dev/null +++ b/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotEditor.kt @@ -0,0 +1,94 @@ +/**************************************************************************/ +/* GodotEditor.kt */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* 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.GodotLib +import org.godotengine.godot.utils.isNativeXRDevice + +/** + * Primary window of the Godot Editor. + * + * This is the implementation of the editor used when running on Meta devices. + */ +open class GodotEditor : BaseGodotEditor() { + + companion object { + private val TAG = GodotEditor::class.java.simpleName + + internal val XR_RUN_GAME_INFO = EditorWindowInfo(GodotXRGame::class.java, 1667, ":GodotXRGame") + + internal const val USE_ANCHOR_API_PERMISSION = "com.oculus.permission.USE_ANCHOR_API" + internal const val USE_SCENE_PERMISSION = "com.oculus.permission.USE_SCENE" + } + + override fun getExcludedPermissions(): MutableSet<String> { + val excludedPermissions = super.getExcludedPermissions() + // The USE_ANCHOR_API and USE_SCENE permissions are requested when the "xr/openxr/enabled" + // project setting is enabled. + excludedPermissions.add(USE_ANCHOR_API_PERMISSION) + excludedPermissions.add(USE_SCENE_PERMISSION) + return excludedPermissions + } + + override fun retrieveEditorWindowInfo(args: Array<String>): EditorWindowInfo { + var hasEditor = false + var xrModeOn = false + + var i = 0 + while (i < args.size) { + when (args[i++]) { + EDITOR_ARG, EDITOR_ARG_SHORT, EDITOR_PROJECT_MANAGER_ARG, EDITOR_PROJECT_MANAGER_ARG_SHORT -> hasEditor = true + XR_MODE_ARG -> { + val argValue = args[i++] + xrModeOn = xrModeOn || ("on" == argValue) + } + } + } + + return if (hasEditor) { + EDITOR_MAIN_INFO + } else { + val openxrEnabled = GodotLib.getGlobal("xr/openxr/enabled").toBoolean() + if (openxrEnabled && isNativeXRDevice()) { + XR_RUN_GAME_INFO + } else { + RUN_GAME_INFO + } + } + } + + override fun getEditorWindowInfoForInstanceId(instanceId: Int): EditorWindowInfo? { + return when (instanceId) { + XR_RUN_GAME_INFO.windowId -> XR_RUN_GAME_INFO + else -> super.getEditorWindowInfoForInstanceId(instanceId) + } + } +} diff --git a/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotXRGame.kt b/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotXRGame.kt new file mode 100644 index 0000000000..d71fbb53f2 --- /dev/null +++ b/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotXRGame.kt @@ -0,0 +1,71 @@ +/*************************************************************************/ +/* GodotXRGame.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 org.godotengine.godot.GodotLib +import org.godotengine.godot.utils.PermissionsUtil +import org.godotengine.godot.xr.XRMode + +/** + * Provide support for running XR apps / games from the editor window. + */ +open class GodotXRGame: GodotGame() { + + override fun overrideOrientationRequest() = true + + override fun updateCommandLineParams(args: List<String>) { + val updatedArgs = ArrayList<String>() + if (!args.contains(XRMode.OPENXR.cmdLineArg)) { + updatedArgs.add(XRMode.OPENXR.cmdLineArg) + } + if (!args.contains(XR_MODE_ARG)) { + updatedArgs.add(XR_MODE_ARG) + updatedArgs.add("on") + } + updatedArgs.addAll(args) + + super.updateCommandLineParams(updatedArgs) + } + + override fun getEditorWindowInfo() = XR_RUN_GAME_INFO + + override fun getProjectPermissionsToEnable(): MutableList<String> { + val permissionsToEnable = super.getProjectPermissionsToEnable() + + val openxrEnabled = GodotLib.getGlobal("xr/openxr/enabled").toBoolean() + if (openxrEnabled) { + permissionsToEnable.add(USE_ANCHOR_API_PERMISSION) + permissionsToEnable.add(USE_SCENE_PERMISSION) + } + + return permissionsToEnable + } +} |
