diff options
Diffstat (limited to 'platform/android/java')
19 files changed, 221 insertions, 50 deletions
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index b9d15deec9..308f126d5d 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -29,6 +29,8 @@ allprojects { configurations { // Initializes a placeholder for the devImplementation dependency configuration. devImplementation {} + // Initializes a placeholder for the monoImplementation dependency configuration. + monoImplementation {} } dependencies { @@ -42,9 +44,9 @@ dependencies { } else { // Godot gradle 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']) + debugImplementation fileTree(dir: 'libs/debug', include: ['**/*.jar', '*.aar']) + devImplementation fileTree(dir: 'libs/dev', include: ['**/*.jar', '*.aar']) + releaseImplementation fileTree(dir: 'libs/release', include: ['**/*.jar', '*.aar']) } // Godot user plugins remote dependencies @@ -60,6 +62,18 @@ dependencies { if (pluginsBinaries != null && pluginsBinaries.size() > 0) { implementation files(pluginsBinaries) } + + // Automatically pick up local dependencies in res://addons + String addonsDirectory = getAddonsDirectory() + if (addonsDirectory != null && !addonsDirectory.isBlank()) { + implementation fileTree(dir: "$addonsDirectory", include: ['*.jar', '*.aar']) + } + + // .NET dependencies + String jar = '../../../../modules/mono/thirdparty/libSystem.Security.Cryptography.Native.Android.jar' + if (file(jar).exists()) { + monoImplementation files(jar) + } } android { @@ -155,6 +169,10 @@ android { } } + buildFeatures { + buildConfig = true + } + buildTypes { debug { @@ -192,6 +210,13 @@ android { } } + flavorDimensions 'edition' + + productFlavors { + standard {} + mono {} + } + sourceSets { main { manifest.srcFile 'AndroidManifest.xml' @@ -207,7 +232,8 @@ android { applicationVariants.all { variant -> variant.outputs.all { output -> - output.outputFileName = "android_${variant.name}.apk" + String filenameSuffix = variant.flavorName == "mono" ? variant.name : variant.buildType.name + output.outputFileName = "android_${filenameSuffix}.apk" } } } @@ -220,12 +246,20 @@ task copyAndRenameBinary(type: Copy) { String exportPath = getExportPath() String exportFilename = getExportFilename() + String exportEdition = getExportEdition() String exportBuildType = getExportBuildType() + String exportBuildTypeCapitalized = exportBuildType.capitalize() String exportFormat = getExportFormat() boolean isAab = exportFormat == "aab" - String sourceFilepath = isAab ? "$buildDir/outputs/bundle/$exportBuildType/build-${exportBuildType}.aab" : "$buildDir/outputs/apk/$exportBuildType/android_${exportBuildType}.apk" - String sourceFilename = isAab ? "build-${exportBuildType}.aab" : "android_${exportBuildType}.apk" + boolean isMono = exportEdition == "mono" + String filenameSuffix = exportBuildType + if (isMono) { + filenameSuffix = isAab ? "${exportEdition}-${exportBuildType}" : "${exportEdition}${exportBuildTypeCapitalized}" + } + + String sourceFilename = isAab ? "build-${filenameSuffix}.aab" : "android_${filenameSuffix}.apk" + String sourceFilepath = isAab ? "$buildDir/outputs/bundle/${exportEdition}${exportBuildTypeCapitalized}/$sourceFilename" : "$buildDir/outputs/apk/$exportEdition/$exportBuildType/$sourceFilename" from sourceFilepath into exportPath diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 611a9c4a40..e8921e1bb1 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -224,6 +224,14 @@ ext.getExportFilename = { return exportFilename } +ext.getExportEdition = { + String exportEdition = project.hasProperty("export_edition") ? project.property("export_edition") : "" + if (exportEdition == null || exportEdition.isEmpty()) { + exportEdition = "standard" + } + return exportEdition +} + ext.getExportBuildType = { String exportBuildType = project.hasProperty("export_build_type") ? project.property("export_build_type") : "" if (exportBuildType == null || exportBuildType.isEmpty()) { @@ -400,3 +408,8 @@ ext.shouldUseLegacyPackaging = { -> // Default behavior for minSdk >= 23 return false } + +ext.getAddonsDirectory = { -> + String addonsDirectory = project.hasProperty("addons_directory") ? project.property("addons_directory") : "" + return addonsDirectory +} 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 22e617f6e7..9d4991e120 100644 --- a/platform/android/java/app/src/com/godot/game/GodotApp.java +++ b/platform/android/java/app/src/com/godot/game/GodotApp.java @@ -33,14 +33,29 @@ package com.godot.game; import org.godotengine.godot.GodotActivity; import android.os.Bundle; +import android.util.Log; import androidx.core.splashscreen.SplashScreen; +import com.godot.game.BuildConfig; + /** * Template activity for Godot Android builds. * Feel free to extend and modify this class for your custom logic. */ public class GodotApp extends GodotActivity { + static { + // .NET libraries. + if (BuildConfig.FLAVOR.equals("mono")) { + try { + Log.v("GODOT", "Loading System.Security.Cryptography.Native.Android library"); + System.loadLibrary("System.Security.Cryptography.Native.Android"); + } catch (UnsatisfiedLinkError e) { + Log.e("GODOT", "Unable to load System.Security.Cryptography.Native.Android library"); + } + } + } + @Override public void onCreate(Bundle savedInstanceState) { SplashScreen.installSplashScreen(this); diff --git a/platform/android/java/build.gradle b/platform/android/java/build.gradle index 974f072c18..9184e8c5d5 100644 --- a/platform/android/java/build.gradle +++ b/platform/android/java/build.gradle @@ -25,11 +25,12 @@ allprojects { ext { supportedAbis = ["arm32", "arm64", "x86_32", "x86_64"] supportedFlavors = ["editor", "template"] - supportedEditorVendors = ["google", "meta"] + supportedAndroidDistributions = ["android", "horizonos"] supportedFlavorsBuildTypes = [ "editor": ["dev", "debug", "release"], "template": ["dev", "debug", "release"] ] + supportedEditions = ["standard", "mono"] // Used by gradle to specify which architecture to build for by default when running // `./gradlew build` (this command is usually used by Android Studio). @@ -53,7 +54,7 @@ def getSconsTaskName(String flavor, String buildType, String abi) { * The zip file also includes some gradle tools to enable gradle builds from the Godot Editor. */ task zipGradleBuild(type: Zip) { - onlyIf { generateGodotTemplates.state.executed || generateDevTemplate.state.executed } + onlyIf { generateGodotTemplates.state.executed || generateGodotMonoTemplates.state.executed || generateDevTemplate.state.executed } doFirst { logger.lifecycle("Generating Godot gradle build template") } @@ -94,17 +95,24 @@ def templateExcludedBuildTask() { /** * Generates the build tasks for the given flavor * @param flavor Must be one of the supported flavors ('template' / 'editor') - * @param editorVendor Must be one of the supported editor vendors ('google' / 'meta') + * @param edition Must be one of the supported editions ('standard' / 'mono') + * @param androidDistro Must be one of the supported Android distributions ('android' / 'horizonos') */ -def generateBuildTasks(String flavor = "template", String editorVendor = "google") { +def generateBuildTasks(String flavor = "template", String edition = "standard", String androidDistro = "android") { if (!supportedFlavors.contains(flavor)) { throw new GradleException("Invalid build flavor: $flavor") } - if (!supportedEditorVendors.contains(editorVendor)) { - throw new GradleException("Invalid editor vendor: $editorVendor") + if (!supportedAndroidDistributions.contains(androidDistro)) { + throw new GradleException("Invalid Android distribution: $androidDistro") + } + if (!supportedEditions.contains(edition)) { + throw new GradleException("Invalid build edition: $edition") + } + if (edition == "mono" && flavor != "template") { + throw new GradleException("'mono' edition only supports the 'template' flavor.") } - String capitalizedEditorVendor = editorVendor.capitalize() + String capitalizedAndroidDistro = androidDistro.capitalize() def buildTasks = [] // Only build the binary files for which we have native shared libraries unless we intend @@ -126,6 +134,7 @@ def generateBuildTasks(String flavor = "template", String editorVendor = "google && targetLibs.listFiles().length > 0)) { String capitalizedTarget = target.capitalize() + String capitalizedEdition = edition.capitalize() if (isTemplate) { // Copy the Godot android library archive file into the app module libs directory. // Depends on the library build task to ensure the AAR file is generated prior to copying. @@ -157,41 +166,42 @@ def generateBuildTasks(String flavor = "template", String editorVendor = "google // Copy the generated binary template into the Godot bin directory. // Depends on the app build task to ensure the binary is generated prior to copying. - String copyBinaryTaskName = "copy${capitalizedTarget}BinaryToBin" + String copyBinaryTaskName = "copy${capitalizedEdition}${capitalizedTarget}BinaryToBin" if (tasks.findByName(copyBinaryTaskName) != null) { buildTasks += tasks.getByName(copyBinaryTaskName) } else { buildTasks += tasks.create(name: copyBinaryTaskName, type: Copy) { - dependsOn ":app:assemble${capitalizedTarget}" - from("app/build/outputs/apk/${target}") + String filenameSuffix = edition == "mono" ? "${edition}${capitalizedTarget}" : target + dependsOn ":app:assemble${capitalizedEdition}${capitalizedTarget}" + from("app/build/outputs/apk/${edition}/${target}") into(binDir) - include("android_${target}.apk") + include("android_${filenameSuffix}.apk") } } } else { // Copy the generated editor apk to the bin directory. - String copyEditorApkTaskName = "copyEditor${capitalizedEditorVendor}${capitalizedTarget}ApkToBin" + String copyEditorApkTaskName = "copyEditor${capitalizedAndroidDistro}${capitalizedTarget}ApkToBin" if (tasks.findByName(copyEditorApkTaskName) != null) { buildTasks += tasks.getByName(copyEditorApkTaskName) } else { buildTasks += tasks.create(name: copyEditorApkTaskName, type: Copy) { - dependsOn ":editor:assemble${capitalizedEditorVendor}${capitalizedTarget}" - from("editor/build/outputs/apk/${editorVendor}/${target}") + dependsOn ":editor:assemble${capitalizedAndroidDistro}${capitalizedTarget}" + from("editor/build/outputs/apk/${androidDistro}/${target}") into(androidEditorBuildsDir) - include("android_editor-${editorVendor}-${target}*.apk") + include("android_editor-${androidDistro}-${target}*.apk") } } // Copy the generated editor aab to the bin directory. - String copyEditorAabTaskName = "copyEditor${capitalizedEditorVendor}${capitalizedTarget}AabToBin" + String copyEditorAabTaskName = "copyEditor${capitalizedAndroidDistro}${capitalizedTarget}AabToBin" if (tasks.findByName(copyEditorAabTaskName) != null) { buildTasks += tasks.getByName(copyEditorAabTaskName) } else { buildTasks += tasks.create(name: copyEditorAabTaskName, type: Copy) { - dependsOn ":editor:bundle${capitalizedEditorVendor}${capitalizedTarget}" - from("editor/build/outputs/bundle/${editorVendor}${capitalizedTarget}") + dependsOn ":editor:bundle${capitalizedAndroidDistro}${capitalizedTarget}" + from("editor/build/outputs/bundle/${androidDistro}${capitalizedTarget}") into(androidEditorBuildsDir) - include("android_editor-${editorVendor}-${target}*.aab") + include("android_editor-${androidDistro}-${target}*.aab") } } } @@ -204,7 +214,7 @@ def generateBuildTasks(String flavor = "template", String editorVendor = "google } /** - * Generate the Godot Editor Android binaries. + * Generate the Godot Editor binaries for Android devices. * * Note: Unless the 'generateNativeLibs` argument is specified, the Godot 'tools' shared libraries * must have been generated (via scons) prior to running this gradle task. @@ -212,19 +222,19 @@ def generateBuildTasks(String flavor = "template", String editorVendor = "google */ task generateGodotEditor { gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() - dependsOn = generateBuildTasks("editor", "google") + dependsOn = generateBuildTasks("editor", "standard", "android") } /** - * Generate the Godot Editor Android binaries for Meta devices. + * Generate the Godot Editor binaries for HorizonOS devices. * * Note: Unless the 'generateNativeLibs` argument is specified, the Godot 'tools' shared libraries * must have been generated (via scons) prior to running this gradle task. * The task will only build the binaries for which the shared libraries is available. */ -task generateGodotMetaEditor { +task generateGodotHorizonOSEditor { gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() - dependsOn = generateBuildTasks("editor", "meta") + dependsOn = generateBuildTasks("editor", "standard", "horizonos") } /** @@ -238,6 +248,17 @@ task generateGodotTemplates { } /** + * Master task used to coordinate the tasks defined above to generate the set of Godot templates + * for the 'mono' edition of the engine. + */ +task generateGodotMonoTemplates { + gradle.startParameter.excludedTaskNames += templateExcludedBuildTask() + dependsOn = generateBuildTasks("template", "mono") + + finalizedBy 'zipGradleBuild' +} + +/** * Generates the same output as generateGodotTemplates but with dev symbols */ task generateDevTemplate { @@ -295,6 +316,9 @@ task cleanGodotTemplates(type: Delete) { delete("$binDir/android_debug.apk") delete("$binDir/android_dev.apk") delete("$binDir/android_release.apk") + delete("$binDir/android_monoDebug.apk") + delete("$binDir/android_monoDev.apk") + delete("$binDir/android_monoRelease.apk") delete("$binDir/android_source.zip") delete("$binDir/godot-lib.template_debug.aar") delete("$binDir/godot-lib.template_debug.dev.aar") diff --git a/platform/android/java/editor/build.gradle b/platform/android/java/editor/build.gradle index 54d6b9b5f3..45222ca3b0 100644 --- a/platform/android/java/editor/build.gradle +++ b/platform/android/java/editor/build.gradle @@ -145,14 +145,14 @@ android { } } - flavorDimensions = ["vendor"] + flavorDimensions = ["android_distribution"] productFlavors { - google { - dimension "vendor" + android { + dimension "android_distribution" missingDimensionStrategy 'products', 'editor' } - meta { - dimension "vendor" + horizonos { + dimension "android_distribution" missingDimensionStrategy 'products', 'editor' ndk { //noinspection ChromeOsAbiSupport @@ -176,5 +176,5 @@ dependencies { implementation "org.bouncycastle:bcprov-jdk15to18:1.77" // Meta dependencies - metaImplementation "org.godotengine:godot-openxr-vendors-meta:3.0.0-stable" + horizonosImplementation "org.godotengine:godot-openxr-vendors-meta:3.0.0-stable" } diff --git a/platform/android/java/editor/src/google/java/org/godotengine/editor/GodotEditor.kt b/platform/android/java/editor/src/android/java/org/godotengine/editor/GodotEditor.kt index f15d9f7768..f15d9f7768 100644 --- a/platform/android/java/editor/src/google/java/org/godotengine/editor/GodotEditor.kt +++ b/platform/android/java/editor/src/android/java/org/godotengine/editor/GodotEditor.kt diff --git a/platform/android/java/editor/src/meta/AndroidManifest.xml b/platform/android/java/editor/src/horizonos/AndroidManifest.xml index 06442ac4e6..06442ac4e6 100644 --- a/platform/android/java/editor/src/meta/AndroidManifest.xml +++ b/platform/android/java/editor/src/horizonos/AndroidManifest.xml diff --git a/platform/android/java/editor/src/meta/assets/vr_splash.png b/platform/android/java/editor/src/horizonos/assets/vr_splash.png Binary files differindex 7bddd4325a..7bddd4325a 100644 --- a/platform/android/java/editor/src/meta/assets/vr_splash.png +++ b/platform/android/java/editor/src/horizonos/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/horizonos/java/org/godotengine/editor/GodotEditor.kt index 9f0440e87d..9dc34f2267 100644 --- a/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotEditor.kt +++ b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotEditor.kt @@ -36,7 +36,7 @@ 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. + * This is the implementation of the editor used when running on HorizonOS devices. */ open class GodotEditor : BaseGodotEditor() { @@ -45,16 +45,14 @@ open class GodotEditor : BaseGodotEditor() { 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" + internal val USE_SCENE_PERMISSIONS = listOf("com.oculus.permission.USE_SCENE", "horizonos.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) + // The USE_SCENE permission is requested when the "xr/openxr/enabled" project setting + // is enabled. + excludedPermissions.addAll(USE_SCENE_PERMISSIONS) return excludedPermissions } diff --git a/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotXRGame.kt b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt index d71fbb53f2..0c82791e89 100644 --- a/platform/android/java/editor/src/meta/java/org/godotengine/editor/GodotXRGame.kt +++ b/platform/android/java/editor/src/horizonos/java/org/godotengine/editor/GodotXRGame.kt @@ -31,7 +31,6 @@ package org.godotengine.editor import org.godotengine.godot.GodotLib -import org.godotengine.godot.utils.PermissionsUtil import org.godotengine.godot.xr.XRMode /** @@ -62,8 +61,16 @@ open class GodotXRGame: GodotGame() { val openxrEnabled = GodotLib.getGlobal("xr/openxr/enabled").toBoolean() if (openxrEnabled) { - permissionsToEnable.add(USE_ANCHOR_API_PERMISSION) - permissionsToEnable.add(USE_SCENE_PERMISSION) + // We only request permissions when the `automatically_request_runtime_permissions` + // project setting is enabled. + // If the project setting is not defined, we fall-back to the default behavior which is + // to automatically request permissions. + val automaticallyRequestPermissionsSetting = GodotLib.getGlobal("xr/openxr/extensions/automatically_request_runtime_permissions") + val automaticPermissionsRequestEnabled = automaticallyRequestPermissionsSetting.isNullOrEmpty() || + automaticallyRequestPermissionsSetting.toBoolean() + if (automaticPermissionsRequestEnabled) { + permissionsToEnable.addAll(USE_SCENE_PERMISSIONS) + } } return permissionsToEnable 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 d296d6ad03..7b6d1f6bd1 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 @@ -517,6 +517,10 @@ abstract class BaseGodotEditor : GodotActivity() { return isNativeXRDevice(); } + if (featureTag == "horizonos") { + return isHorizonOSDevice() + } + return false } } diff --git a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml index cfdcca2ab5..bb2ae6bee5 100644 --- a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml +++ b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml @@ -2,4 +2,5 @@ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <background android:drawable="@mipmap/icon_background"/> <foreground android:drawable="@mipmap/icon_foreground"/> + <monochrome android:drawable="@mipmap/icon_monochrome"/> </adaptive-icon> diff --git a/platform/android/java/lib/res/mipmap/icon_monochrome.png b/platform/android/java/lib/res/mipmap/icon_monochrome.png Binary files differnew file mode 100644 index 0000000000..28f59ea119 --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon_monochrome.png 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 5b1d09e749..567b134234 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt @@ -58,6 +58,8 @@ import org.godotengine.godot.input.GodotEditText import org.godotengine.godot.input.GodotInputHandler import org.godotengine.godot.io.directory.DirectoryAccessHandler import org.godotengine.godot.io.file.FileAccessHandler +import org.godotengine.godot.plugin.AndroidRuntimePlugin +import org.godotengine.godot.plugin.GodotPlugin import org.godotengine.godot.plugin.GodotPluginRegistry import org.godotengine.godot.tts.GodotTTS import org.godotengine.godot.utils.CommandLineFileParser @@ -228,7 +230,9 @@ class Godot(private val context: Context) { window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON) Log.v(TAG, "Initializing Godot plugin registry") - GodotPluginRegistry.initializePluginRegistry(this, primaryHost.getHostPlugins(this)) + val runtimePlugins = mutableSetOf<GodotPlugin>(AndroidRuntimePlugin(this)) + runtimePlugins.addAll(primaryHost.getHostPlugins(this)) + GodotPluginRegistry.initializePluginRegistry(this, runtimePlugins) if (io == null) { io = GodotIO(activity) } 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 219631284a..f060c7aaff 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -216,6 +216,14 @@ public class GodotIO { return result; } + public boolean hasHardwareKeyboard() { + if (edit != null) { + return edit.hasHardwareKeyboard(); + } else { + return false; + } + } + public void showKeyboard(String p_existing_text, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) { if (edit != null) { edit.showKeyboard(p_existing_text, GodotEditText.VirtualKeyboardType.values()[p_type], p_max_input_length, p_cursor_start, p_cursor_end); diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index c085bb8886..cacc1643e3 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -264,7 +264,7 @@ public class GodotEditText extends EditText { isModifiedKey; } - boolean hasHardwareKeyboard() { + public boolean hasHardwareKeyboard() { Configuration config = getResources().getConfiguration(); boolean hasHardwareKeyboardConfig = config.keyboard != Configuration.KEYBOARD_NOKEYS && config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/AndroidRuntimePlugin.kt b/platform/android/java/lib/src/org/godotengine/godot/plugin/AndroidRuntimePlugin.kt new file mode 100644 index 0000000000..edb4e7c357 --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/AndroidRuntimePlugin.kt @@ -0,0 +1,63 @@ +/**************************************************************************/ +/* AndroidRuntimePlugin.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.godot.plugin + +import org.godotengine.godot.Godot + +/** + * Provides access to the Android runtime capabilities. + * + * For example, from gdscript, developers can use [getApplicationContext] to access system services + * and check if the device supports vibration. + * + * var android_runtime = Engine.get_singleton("AndroidRuntime") + * if android_runtime: + * print("Checking if the device supports vibration") + * var vibrator_service = android_runtime.getApplicationContext().getSystemService("vibrator") + * if vibrator_service: + * if vibrator_service.hasVibrator(): + * print("Vibration is supported on device!") + * else: + * printerr("Vibration is not supported on device") + * else: + * printerr("Unable to retrieve the vibrator service") + * else: + * printerr("Couldn't find AndroidRuntime singleton") + */ +class AndroidRuntimePlugin(godot: Godot) : GodotPlugin(godot) { + override fun getPluginName() = "AndroidRuntime" + + @UsedByGodot + fun getApplicationContext() = activity?.applicationContext + + @UsedByGodot + override fun getActivity() = super.getActivity() +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java index 4a166112ab..be5a7a2962 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java @@ -50,7 +50,7 @@ public final class SignalInfo { } this.name = signalName; - this.paramTypes = paramTypes == null ? new Class<?>[ 0 ] : paramTypes; + this.paramTypes = paramTypes == null ? new Class<?>[0] : paramTypes; this.paramTypesNames = new String[this.paramTypes.length]; for (int i = 0; i < this.paramTypes.length; i++) { this.paramTypesNames[i] = this.paramTypes[i].getName(); diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/DeviceUtils.kt b/platform/android/java/lib/src/org/godotengine/godot/utils/DeviceUtils.kt index abe0c5f885..dff57581fa 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/DeviceUtils.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/DeviceUtils.kt @@ -38,7 +38,7 @@ package org.godotengine.godot.utils import android.os.Build /** - * Returns true if running on Meta's Horizon OS. + * Returns true if running on Meta Horizon OS. */ fun isHorizonOSDevice(): Boolean { return "Oculus".equals(Build.BRAND, true) |