summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/README.md14
-rw-r--r--platform/android/detect.py2
-rw-r--r--platform/android/dir_access_jandroid.cpp2
-rw-r--r--platform/android/export/export.cpp2
-rw-r--r--platform/android/export/export_plugin.cpp43
-rw-r--r--platform/android/export/export_plugin.h7
-rw-r--r--platform/android/export/gradle_export_util.cpp9
-rw-r--r--platform/android/export/gradle_export_util.h6
-rw-r--r--platform/android/java/app/AndroidManifest.xml4
-rw-r--r--platform/android/java/app/assetPacks/installTime/build.gradle8
-rw-r--r--platform/android/java/app/build.gradle5
-rw-r--r--platform/android/java/app/config.gradle6
-rw-r--r--platform/android/java/app/gradle.properties4
-rw-r--r--platform/android/java/app/settings.gradle4
-rw-r--r--platform/android/java/gradle.properties4
-rw-r--r--platform/android/java/lib/build.gradle3
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java21
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java26
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotHost.java6
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java14
-rw-r--r--platform/android/java/settings.gradle3
-rw-r--r--platform/android/logo.pngbin951 -> 968 bytes
23 files changed, 143 insertions, 52 deletions
diff --git a/platform/android/README.md b/platform/android/README.md
new file mode 100644
index 0000000000..343e588553
--- /dev/null
+++ b/platform/android/README.md
@@ -0,0 +1,14 @@
+# Android platform port
+
+This folder contains the Java and C++ (JNI) code for the Android platform port,
+using [Gradle](https://gradle.org/) as a build system.
+
+## Artwork license
+
+[`logo.png`](logo.png) and [`run_icon.png`](run_icon.png) are licensed under
+[Creative Commons Attribution 3.0 Unported](https://developer.android.com/distribute/marketing-tools/brand-guidelines#android_robot)
+per the Android logo usage guidelines:
+
+> The Android robot is reproduced or modified from work created and shared by
+> Google and used according to terms described in the Creative Commons 3.0
+> Attribution License.
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 7a993e9ca6..61ccad9ac3 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -93,7 +93,7 @@ def configure(env):
install_ndk_if_needed(env)
# Workaround for MinGW. See:
- # http://www.scons.org/wiki/LongCmdLinesOnWin32
+ # https://www.scons.org/wiki/LongCmdLinesOnWin32
if os.name == "nt":
import subprocess
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index 0bae090702..0eeee8215d 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -161,7 +161,7 @@ bool DirAccessJAndroid::dir_exists(String p_dir) {
if (current_dir == "")
sd = p_dir;
else {
- if (p_dir.is_rel_path())
+ if (p_dir.is_relative_path())
sd = current_dir.plus_file(p_dir);
else
sd = fix_path(p_dir);
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index fc86abb6f1..8df61831c2 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -48,6 +48,8 @@ void register_android_exporter() {
EDITOR_DEF("export/android/shutdown_adb_on_exit", true);
+ EDITOR_DEF("export/android/one_click_deploy_clear_previous_install", false);
+
Ref<EditorExportPlatformAndroid> exporter = Ref<EditorExportPlatformAndroid>(memnew(EditorExportPlatformAndroid));
EditorExport::get_singleton()->add_export_platform(exporter);
}
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 8ed2d4e60a..60ba1c558a 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -221,6 +221,9 @@ static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_coun
static const int EXPORT_FORMAT_APK = 0;
static const int EXPORT_FORMAT_AAB = 1;
+static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets";
+static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets";
+
void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) {
EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud;
@@ -426,6 +429,11 @@ String EditorExportPlatformAndroid::get_package_name(const String &p_package) co
return pname;
}
+String EditorExportPlatformAndroid::get_assets_directory(const Ref<EditorExportPreset> &p_preset) const {
+ int export_format = int(p_preset->get("custom_template/export_format"));
+ return export_format == EXPORT_FORMAT_AAB ? AAB_ASSETS_DIRECTORY : APK_ASSETS_DIRECTORY;
+}
+
bool EditorExportPlatformAndroid::is_package_name_valid(const String &p_package, String *r_error) const {
String pname = p_package;
@@ -977,6 +985,11 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p
Vector<int> feature_versions;
if (xr_mode_index == 1 /* XRMode.OVR */) {
+ // Set degrees of freedom
+ feature_names.push_back("android.hardware.vr.headtracking");
+ feature_required_list.push_back(true);
+ feature_versions.push_back(1);
+
// Check for hand tracking
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index > 0) {
@@ -1646,8 +1659,6 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false));
-
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
@@ -1794,7 +1805,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
int rv;
String output;
- bool remove_prev = p_preset->get("one_click_deploy/clear_previous_install");
+ bool remove_prev = EDITOR_GET("export/android/one_click_deploy_clear_previous_install");
String version_name = p_preset->get("version/name");
String package_name = p_preset->get("package/unique_name");
@@ -2332,11 +2343,21 @@ Error EditorExportPlatformAndroid::sign_apk(const Ref<EditorExportPreset> &p_pre
void EditorExportPlatformAndroid::_clear_assets_directory() {
DirAccessRef da_res = DirAccess::create(DirAccess::ACCESS_RESOURCES);
- if (da_res->dir_exists("res://android/build/assets")) {
- print_verbose("Clearing assets directory..");
- DirAccessRef da_assets = DirAccess::open("res://android/build/assets");
+
+ // Clear the APK assets directory
+ if (da_res->dir_exists(APK_ASSETS_DIRECTORY)) {
+ print_verbose("Clearing APK assets directory..");
+ DirAccessRef da_assets = DirAccess::open(APK_ASSETS_DIRECTORY);
+ da_assets->erase_contents_recursive();
+ da_res->remove(APK_ASSETS_DIRECTORY);
+ }
+
+ // Clear the AAB assets directory
+ if (da_res->dir_exists(AAB_ASSETS_DIRECTORY)) {
+ print_verbose("Clearing AAB assets directory..");
+ DirAccessRef da_assets = DirAccess::open(AAB_ASSETS_DIRECTORY);
da_assets->erase_contents_recursive();
- da_res->remove("res://android/build/assets");
+ da_res->remove(AAB_ASSETS_DIRECTORY);
}
}
@@ -2456,6 +2477,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
return ERR_UNCONFIGURED;
}
}
+ const String assets_directory = get_assets_directory(p_preset);
String sdk_path = EDITOR_GET("export/android/android_sdk_path");
ERR_FAIL_COND_V_MSG(sdk_path.is_empty(), ERR_UNCONFIGURED, "Android SDK path must be configured in Editor Settings at 'export/android/android_sdk_path'.");
print_verbose("Android sdk path: " + sdk_path);
@@ -2477,6 +2499,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (!apk_expansion) {
print_verbose("Exporting project files..");
CustomExportData user_data;
+ user_data.assets_directory = assets_directory;
user_data.debug = p_debug;
err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, &user_data, copy_gradle_so);
if (err != OK) {
@@ -2498,7 +2521,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
}
}
print_verbose("Storing command line flags..");
- store_file_at_path("res://android/build/assets/_cl_", command_line_flags);
+ store_file_at_path(assets_directory + "/_cl_", command_line_flags);
print_verbose("Updating ANDROID_HOME environment to " + sdk_path);
OS::get_singleton()->set_environment("ANDROID_HOME", sdk_path); //set and overwrite if required
@@ -2611,7 +2634,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String export_filename = p_path.get_file();
String export_path = p_path.get_base_dir();
- if (export_path.is_rel_path()) {
+ if (export_path.is_relative_path()) {
export_path = OS::get_singleton()->get_resource_dir().plus_file(export_path);
}
export_path = ProjectSettings::get_singleton()->globalize_path(export_path).simplify_path();
@@ -2939,7 +2962,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
void EditorExportPlatformAndroid::get_platform_features(List<String> *r_features) {
r_features->push_back("mobile");
- r_features->push_back("Android");
+ r_features->push_back("android");
}
void EditorExportPlatformAndroid::resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) {
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index b061ee4e04..d33f616f11 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -87,11 +87,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
EditorProgress *ep = nullptr;
};
- struct CustomExportData {
- bool debug;
- Vector<String> libs;
- };
-
Vector<PluginConfigAndroid> plugins;
String last_plugin_names;
uint64_t last_custom_build_time = 0;
@@ -109,6 +104,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
String get_package_name(const String &p_package) const;
+ String get_assets_directory(const Ref<EditorExportPreset> &p_preset) const;
+
bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const;
static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data);
diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp
index b9e28a7937..851bd0ac52 100644
--- a/platform/android/export/gradle_export_util.cpp
+++ b/platform/android/export/gradle_export_util.cpp
@@ -121,7 +121,8 @@ Error store_string_at_path(const String &p_path, const String &p_data) {
// It's functionality mirrors that of the method save_apk_file.
// This method will be called ONLY when custom build is enabled.
Error rename_and_store_file_in_gradle_project(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key) {
- String dst_path = p_path.replace_first("res://", "res://android/build/assets/");
+ CustomExportData *export_data = (CustomExportData *)p_userdata;
+ String dst_path = p_path.replace_first("res://", export_data->assets_directory + "/");
print_verbose("Saving project files from " + p_path + " into " + dst_path);
Error err = store_file_at_path(dst_path, p_data);
return err;
@@ -197,6 +198,8 @@ String _get_xr_features_tag(const Ref<EditorExportPreset> &p_preset) {
String manifest_xr_features;
bool uses_xr = (int)(p_preset->get("xr_features/xr_mode")) == 1;
if (uses_xr) {
+ manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"android.hardware.vr.headtracking\" android:required=\"true\" android:version=\"1\" />\n";
+
int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required
if (hand_tracking_index == 1) {
manifest_xr_features += " <uses-feature tools:node=\"replace\" android:name=\"oculus.software.handtracking\" android:required=\"false\" />\n";
@@ -228,7 +231,9 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {
"tools:replace=\"android:screenOrientation\" "
"android:screenOrientation=\"%s\">\n",
orientation);
- if (!uses_xr) {
+ if (uses_xr) {
+ manifest_activity_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.vr.focusaware\" android:value=\"true\" />\n";
+ } else {
manifest_activity_text += " <meta-data tools:node=\"remove\" android:name=\"com.oculus.vr.focusaware\" />\n";
}
manifest_activity_text += " </activity>\n";
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index 8a93c25d79..744022f1f9 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -44,6 +44,12 @@ const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="ut
</resources>
)";
+struct CustomExportData {
+ String assets_directory;
+ bool debug;
+ Vector<String> libs;
+};
+
int _get_android_orientation_value(DisplayServer::ScreenOrientation screen_orientation);
String _get_android_orientation_label(DisplayServer::ScreenOrientation screen_orientation);
diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml
index 00e01884cf..d7bf6cef30 100644
--- a/platform/android/java/app/AndroidManifest.xml
+++ b/platform/android/java/app/AndroidManifest.xml
@@ -49,6 +49,10 @@
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
+
+ <!-- Enable access to OpenXR on Oculus mobile devices, no-op on other Android
+ platforms. -->
+ <category android:name="com.oculus.intent.category.VR" />
</intent-filter>
</activity>
diff --git a/platform/android/java/app/assetPacks/installTime/build.gradle b/platform/android/java/app/assetPacks/installTime/build.gradle
new file mode 100644
index 0000000000..b06faac374
--- /dev/null
+++ b/platform/android/java/app/assetPacks/installTime/build.gradle
@@ -0,0 +1,8 @@
+apply plugin: 'com.android.asset-pack'
+
+assetPack {
+ packName = "installTime" // Directory name for the asset pack
+ dynamicDelivery {
+ deliveryType = "install-time" // Delivery mode
+ }
+}
diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle
index 18e07c3762..a391a3ca9a 100644
--- a/platform/android/java/app/build.gradle
+++ b/platform/android/java/app/build.gradle
@@ -34,9 +34,8 @@ allprojects {
}
dependencies {
- implementation libraries.supportCoreUtils
implementation libraries.kotlinStdLib
- implementation libraries.v4Support
+ implementation libraries.androidxFragment
if (rootProject.findProject(":lib")) {
implementation project(":lib")
@@ -73,6 +72,8 @@ android {
targetCompatibility versions.javaVersion
}
+ assetPacks = [":assetPacks:installTime"]
+
defaultConfig {
// The default ignore pattern for the 'assets' directory includes hidden files and directories which are used by Godot projects.
aaptOptions {
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index fad64c675f..fcee54e493 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -4,9 +4,8 @@ ext.versions = [
minSdk : 19,
targetSdk : 30,
buildTools : '30.0.3',
- supportCoreUtils : '1.0.0',
kotlinVersion : '1.5.10',
- v4Support : '1.0.0',
+ fragmentVersion : '1.3.6',
javaVersion : 1.8,
ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
@@ -14,10 +13,9 @@ ext.versions = [
ext.libraries = [
androidGradlePlugin: "com.android.tools.build:gradle:$versions.androidGradlePlugin",
- supportCoreUtils : "androidx.legacy:legacy-support-core-utils:$versions.supportCoreUtils",
kotlinGradlePlugin : "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlinVersion",
kotlinStdLib : "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$versions.kotlinVersion",
- v4Support : "androidx.legacy:legacy-support-v4:$versions.v4Support"
+ androidxFragment : "androidx.fragment:fragment:$versions.fragmentVersion",
]
ext.getExportPackageName = { ->
diff --git a/platform/android/java/app/gradle.properties b/platform/android/java/app/gradle.properties
index 19587bd81f..0ad8e611ca 100644
--- a/platform/android/java/app/gradle.properties
+++ b/platform/android/java/app/gradle.properties
@@ -4,7 +4,7 @@
# where otherwise specified.
# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
+# https://www.gradle.org/docs/current/userguide/build_environment.html
android.enableJetifier=true
android.useAndroidX=true
@@ -15,7 +15,7 @@ org.gradle.jvmargs=-Xmx4536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# https://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
org.gradle.warning.mode=all
diff --git a/platform/android/java/app/settings.gradle b/platform/android/java/app/settings.gradle
index 33b863c7bf..e38d7b2ba6 100644
--- a/platform/android/java/app/settings.gradle
+++ b/platform/android/java/app/settings.gradle
@@ -1,2 +1,2 @@
-// Empty settings.gradle file to denote this directory as being the root project
-// of the Godot custom build.
+// This is the root directory of the Godot custom build.
+include ':assetPacks:installTime'
diff --git a/platform/android/java/gradle.properties b/platform/android/java/gradle.properties
index b51a19a005..5cd94e85d9 100644
--- a/platform/android/java/gradle.properties
+++ b/platform/android/java/gradle.properties
@@ -7,7 +7,7 @@
# any settings specified in this file.
# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
+# https://www.gradle.org/docs/current/userguide/build_environment.html
android.enableJetifier=true
android.useAndroidX=true
@@ -18,7 +18,7 @@ org.gradle.jvmargs=-Xmx4536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# https://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
org.gradle.warning.mode=all
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index 663ba73d40..fbed4ed078 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -2,9 +2,8 @@ apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
dependencies {
- implementation libraries.supportCoreUtils
implementation libraries.kotlinStdLib
- implementation libraries.v4Support
+ implementation libraries.androidxFragment
}
def pathToRootDir = "../../../../"
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
index 2a72c9818d..9aa65fd786 100644
--- a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
@@ -54,7 +54,7 @@ public class Helpers {
/*
* Parse the Content-Disposition HTTP Header. The format of the header is defined here:
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for
+ * https://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for
* content that is going to be downloaded to the file system. We only support the attachment
* type.
*/
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 ad7048cbf3..3600706c7c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -30,6 +30,7 @@
package org.godotengine.godot;
+import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
@@ -86,6 +87,26 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
}
@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
+ // 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);
+ }
+ }
+
+ @Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (godotFragment != null) {
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 317175858b..70bc73b9ad 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -295,7 +295,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
View pluginView = plugin.onMainCreate(activity);
if (pluginView != null) {
- containerLayout.addView(pluginView);
+ if (plugin.shouldBeOnTop()) {
+ containerLayout.addView(pluginView);
+ } else {
+ containerLayout.addView(pluginView, 0);
+ }
}
}
}
@@ -317,7 +321,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
@SuppressLint("MissingPermission")
@Keep
private void vibrate(int durationMs) {
- if (requestPermission("VIBRATE")) {
+ if (durationMs > 0 && requestPermission("VIBRATE")) {
Vibrator v = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
@@ -331,22 +335,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public void restart() {
- // HACK:
- //
- // Currently it's very hard to properly deinitialize 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.
- //
- final Activity activity = getActivity();
- if (activity != null) {
- Bundle args = new Bundle();
- args.putParcelable("intent", mCurrentIntent);
- activity.startInstrumentation(new ComponentName(activity, GodotInstrumentation.class), null, args);
+ if (godotHost != null) {
+ godotHost.onGodotRestartRequested(this);
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
index 58e982c569..7b22895994 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotHost.java
@@ -58,4 +58,10 @@ public interface GodotHost {
* Invoked on the UI thread as the last step of the Godot instance clean up phase.
*/
default void onGodotForceQuit(Godot instance) {}
+
+ /**
+ * Invoked on the GL thread when the Godot instance wants to be restarted. It's up to the host
+ * to perform the appropriate action(s).
+ */
+ default void onGodotRestartRequested(Godot instance) {}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index 2dc8359615..4536c21ed3 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -191,6 +191,9 @@ public abstract class GodotPlugin {
* The plugin can return a non-null {@link View} layout in order to add it to the Godot view
* hierarchy.
*
+ * Use shouldBeOnTop() to set whether the plugin's {@link View} should be added on top or behind
+ * the main Godot view.
+ *
* @see Activity#onCreate(Bundle)
* @return the plugin's view to be included; null if no views should be included.
*/
@@ -311,6 +314,17 @@ public abstract class GodotPlugin {
}
/**
+ * Returns whether the plugin's {@link View} returned in onMainCreate() should be placed on
+ * top of the main Godot view.
+ *
+ * Returning false causes the plugin's {@link View} to be placed behind, which can be useful
+ * when used with transparency in order to let the Godot view handle inputs.
+ */
+ public boolean shouldBeOnTop() {
+ return true;
+ }
+
+ /**
* Runs the specified action on the UI thread. If the current thread is the UI
* thread, then the action is executed immediately. If the current thread is
* not the UI thread, the action is posted to the event queue of the UI thread.
diff --git a/platform/android/java/settings.gradle b/platform/android/java/settings.gradle
index 524031d93f..584b626900 100644
--- a/platform/android/java/settings.gradle
+++ b/platform/android/java/settings.gradle
@@ -4,3 +4,6 @@ rootProject.name = "Godot"
include ':app'
include ':lib'
include ':nativeSrcsConfigs'
+
+include ':assetPacks:installTime'
+project(':assetPacks:installTime').projectDir = file("app/assetPacks/installTime")
diff --git a/platform/android/logo.png b/platform/android/logo.png
index f44d360a25..9c8be93646 100644
--- a/platform/android/logo.png
+++ b/platform/android/logo.png
Binary files differ