summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/android_keys_utils.h6
-rw-r--r--platform/android/display_server_android.cpp5
-rw-r--r--platform/android/export/export_plugin.cpp110
-rw-r--r--platform/android/export/export_plugin.h22
-rw-r--r--platform/android/java/app/config.gradle8
-rw-r--r--platform/android/java/editor/src/main/java/org/godotengine/editor/GodotEditor.kt19
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.properties2
-rw-r--r--platform/android/java/lib/AndroidManifest.xml3
-rw-r--r--platform/android/java/lib/build.gradle13
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java2
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java4
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt59
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java5
-rw-r--r--platform/android/java_godot_lib_jni.cpp57
-rw-r--r--platform/android/java_godot_view_wrapper.cpp2
-rw-r--r--platform/android/os_android.cpp9
-rw-r--r--platform/android/plugin/godot_plugin_jni.cpp2
17 files changed, 199 insertions, 129 deletions
diff --git a/platform/android/android_keys_utils.h b/platform/android/android_keys_utils.h
index 5ec3ee17aa..bc633aeade 100644
--- a/platform/android/android_keys_utils.h
+++ b/platform/android/android_keys_utils.h
@@ -43,7 +43,6 @@ struct AndroidGodotCodePair {
static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_UNKNOWN, Key::UNKNOWN }, // (0) Unknown key code.
- { AKEYCODE_HOME, Key::HOME }, // (3) Home key.
{ AKEYCODE_BACK, Key::BACK }, // (4) Back key.
{ AKEYCODE_0, Key::KEY_0 }, // (7) '0' key.
{ AKEYCODE_1, Key::KEY_1 }, // (8) '1' key.
@@ -63,6 +62,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_DPAD_RIGHT, Key::RIGHT }, // (22) Directional Pad Right key.
{ AKEYCODE_VOLUME_UP, Key::VOLUMEUP }, // (24) Volume Up key.
{ AKEYCODE_VOLUME_DOWN, Key::VOLUMEDOWN }, // (25) Volume Down key.
+ { AKEYCODE_POWER, Key::STANDBY }, // (26) Power key.
{ AKEYCODE_CLEAR, Key::CLEAR }, // (28) Clear key.
{ AKEYCODE_A, Key::A }, // (29) 'A' key.
{ AKEYCODE_B, Key::B }, // (30) 'B' key.
@@ -98,6 +98,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_SHIFT_RIGHT, Key::SHIFT }, // (60) Right Shift modifier key.
{ AKEYCODE_TAB, Key::TAB }, // (61) Tab key.
{ AKEYCODE_SPACE, Key::SPACE }, // (62) Space key.
+ { AKEYCODE_ENVELOPE, Key::LAUNCHMAIL }, // (65) Envelope special function key.
{ AKEYCODE_ENTER, Key::ENTER }, // (66) Enter key.
{ AKEYCODE_DEL, Key::BACKSPACE }, // (67) Backspace key.
{ AKEYCODE_GRAVE, Key::QUOTELEFT }, // (68) '`' (backtick) key.
@@ -114,6 +115,7 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_MENU, Key::MENU }, // (82) Menu key.
{ AKEYCODE_SEARCH, Key::SEARCH }, // (84) Search key.
{ AKEYCODE_MEDIA_STOP, Key::MEDIASTOP }, // (86) Stop media key.
+ { AKEYCODE_MEDIA_NEXT, Key::MEDIANEXT }, // (87) Play Next media key.
{ AKEYCODE_MEDIA_PREVIOUS, Key::MEDIAPREVIOUS }, // (88) Play Previous media key.
{ AKEYCODE_PAGE_UP, Key::PAGEUP }, // (92) Page Up key.
{ AKEYCODE_PAGE_DOWN, Key::PAGEDOWN }, // (93) Page Down key.
@@ -127,6 +129,8 @@ static AndroidGodotCodePair android_godot_code_pairs[] = {
{ AKEYCODE_META_RIGHT, Key::META }, // (118) Right Meta modifier key.
{ AKEYCODE_SYSRQ, Key::PRINT }, // (120) System Request / Print Screen key.
{ AKEYCODE_BREAK, Key::PAUSE }, // (121) Break / Pause key.
+ { AKEYCODE_MOVE_HOME, Key::HOME }, // (122) Home Movement key.
+ { AKEYCODE_MOVE_END, Key::END }, // (123) End Movement key.
{ AKEYCODE_INSERT, Key::INSERT }, // (124) Insert key.
{ AKEYCODE_FORWARD, Key::FORWARD }, // (125) Forward key.
{ AKEYCODE_MEDIA_PLAY, Key::MEDIAPLAY }, // (126) Play media key.
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 08369e735d..967f5c7dae 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -321,6 +321,11 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type,
case WINDOW_VIEW: {
return 0; // Not supported.
}
+#ifdef GLES3_ENABLED
+ case OPENGL_CONTEXT: {
+ return eglGetCurrentContext();
+ }
+#endif
default: {
return 0;
}
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 3bfdd3b881..c3fba625c6 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -585,12 +585,13 @@ zip_fileinfo EditorExportPlatformAndroid::get_zip_fileinfo() {
return zipfi;
}
-Vector<String> EditorExportPlatformAndroid::get_abis() {
- Vector<String> abis;
- abis.push_back("armeabi-v7a");
- abis.push_back("arm64-v8a");
- abis.push_back("x86");
- abis.push_back("x86_64");
+Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_abis() {
+ // Should have the same order and size as get_archs.
+ Vector<ABI> abis;
+ abis.push_back(ABI("armeabi-v7a", "arm32"));
+ abis.push_back(ABI("arm64-v8a", "arm64"));
+ abis.push_back(ABI("x86", "x86_32"));
+ abis.push_back(ABI("x86_64", "x86_64"));
return abis;
}
@@ -687,14 +688,20 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj
return FAILED;
}
APKExportData *ed = static_cast<APKExportData *>(p_userdata);
- Vector<String> abis = get_abis();
+ Vector<ABI> abis = get_abis();
bool exported = false;
for (int i = 0; i < p_so.tags.size(); ++i) {
// shared objects can be fat (compatible with multiple ABIs)
- int abi_index = abis.find(p_so.tags[i]);
+ int abi_index = -1;
+ for (int j = 0; j < abis.size(); ++j) {
+ if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) {
+ abi_index = j;
+ break;
+ }
+ }
if (abi_index != -1) {
exported = true;
- String abi = abis[abi_index];
+ String abi = abis[abi_index].abi;
String dst_path = String("lib").path_join(abi).path_join(p_so.path.get_file());
Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path);
Error store_err = store_in_apk(ed, dst_path, array);
@@ -702,9 +709,7 @@ Error EditorExportPlatformAndroid::save_apk_so(void *p_userdata, const SharedObj
}
}
if (!exported) {
- String abis_string = String(" ").join(abis);
- String err = "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + abis_string;
- ERR_PRINT(err);
+ ERR_PRINT("Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag: " + join_abis(abis, " ", true));
return FAILED;
}
return OK;
@@ -725,16 +730,22 @@ Error EditorExportPlatformAndroid::ignore_apk_file(void *p_userdata, const Strin
Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const SharedObject &p_so) {
ERR_FAIL_COND_V_MSG(!p_so.path.get_file().begins_with("lib"), FAILED,
"Android .so file names must start with \"lib\", but got: " + p_so.path);
- Vector<String> abis = get_abis();
+ Vector<ABI> abis = get_abis();
CustomExportData *export_data = static_cast<CustomExportData *>(p_userdata);
bool exported = false;
for (int i = 0; i < p_so.tags.size(); ++i) {
- int abi_index = abis.find(p_so.tags[i]);
+ int abi_index = -1;
+ for (int j = 0; j < abis.size(); ++j) {
+ if (abis[j].abi == p_so.tags[i] || abis[j].arch == p_so.tags[i]) {
+ abi_index = j;
+ break;
+ }
+ }
if (abi_index != -1) {
exported = true;
String base = "res://android/build/libs";
String type = export_data->debug ? "debug" : "release";
- String abi = abis[abi_index];
+ String abi = abis[abi_index].abi;
String filename = p_so.path.get_file();
String dst_path = base.path_join(type).path_join(abi).path_join(filename);
Vector<uint8_t> data = FileAccess::get_file_as_array(p_so.path);
@@ -745,7 +756,7 @@ Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const Shared
}
}
ERR_FAIL_COND_V_MSG(!exported, FAILED,
- "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + String(" ").join(abis));
+ "Cannot determine architecture for library \"" + p_so.path + "\". One of the supported architectures must be used as a tag:" + join_abis(abis, " ", true));
return OK;
}
@@ -791,7 +802,7 @@ void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset>
}
void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug) {
- print_verbose("Building temporary manifest..");
+ print_verbose("Building temporary manifest...");
String manifest_text =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n"
@@ -1656,11 +1667,11 @@ void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<Editor
}
}
-Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) {
- Vector<String> abis = get_abis();
- Vector<String> enabled_abis;
+Vector<EditorExportPlatformAndroid::ABI> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExportPreset> &p_preset) {
+ Vector<ABI> abis = get_abis();
+ Vector<ABI> enabled_abis;
for (int i = 0; i < abis.size(); ++i) {
- bool is_enabled = p_preset->get("architectures/" + abis[i]);
+ bool is_enabled = p_preset->get("architectures/" + abis[i].abi);
if (is_enabled) {
enabled_abis.push_back(abis[i]);
}
@@ -1671,9 +1682,10 @@ Vector<String> EditorExportPlatformAndroid::get_enabled_abis(const Ref<EditorExp
void EditorExportPlatformAndroid::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
r_features->push_back("etc2");
- Vector<String> abis = get_enabled_abis(p_preset);
+ Vector<ABI> abis = get_enabled_abis(p_preset);
for (int i = 0; i < abis.size(); ++i) {
- r_features->push_back(abis[i]);
+ r_features->push_back(abis[i].arch);
+ r_features->push_back(abis[i].abi);
}
}
@@ -1697,9 +1709,9 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
// Android supports multiple architectures in an app bundle, so
// we expose each option as a checkbox in the export dialog.
- const Vector<String> abis = get_abis();
+ const Vector<ABI> abis = get_abis();
for (int i = 0; i < abis.size(); ++i) {
- const String abi = abis[i];
+ const String abi = abis[i].abi;
// All Android devices supporting Vulkan run 64-bit Android,
// so there is usually no point in exporting for 32-bit Android.
const bool is_default = abi == "arm64-v8a";
@@ -2479,7 +2491,7 @@ void EditorExportPlatformAndroid::_clear_assets_directory() {
// Clear the APK assets directory
if (da_res->dir_exists(APK_ASSETS_DIRECTORY)) {
- print_verbose("Clearing APK assets directory..");
+ print_verbose("Clearing APK assets directory...");
Ref<DirAccess> da_assets = DirAccess::open(APK_ASSETS_DIRECTORY);
da_assets->erase_contents_recursive();
da_res->remove(APK_ASSETS_DIRECTORY);
@@ -2487,7 +2499,7 @@ void EditorExportPlatformAndroid::_clear_assets_directory() {
// Clear the AAB assets directory
if (da_res->dir_exists(AAB_ASSETS_DIRECTORY)) {
- print_verbose("Clearing AAB assets directory..");
+ print_verbose("Clearing AAB assets directory...");
Ref<DirAccess> da_assets = DirAccess::open(AAB_ASSETS_DIRECTORY);
da_assets->erase_contents_recursive();
da_res->remove(AAB_ASSETS_DIRECTORY);
@@ -2516,13 +2528,24 @@ void EditorExportPlatformAndroid::_remove_copied_libs() {
da->remove(GDNATIVE_LIBS_PATH);
}
-String EditorExportPlatformAndroid::join_list(List<String> parts, const String &separator) const {
+String EditorExportPlatformAndroid::join_list(const List<String> &p_parts, const String &p_separator) {
+ String ret;
+ for (int i = 0; i < p_parts.size(); ++i) {
+ if (i > 0) {
+ ret += p_separator;
+ }
+ ret += p_parts[i];
+ }
+ return ret;
+}
+
+String EditorExportPlatformAndroid::join_abis(const Vector<EditorExportPlatformAndroid::ABI> &p_parts, const String &p_separator, bool p_use_arch) {
String ret;
- for (int i = 0; i < parts.size(); ++i) {
+ for (int i = 0; i < p_parts.size(); ++i) {
if (i > 0) {
- ret += separator;
+ ret += p_separator;
}
- ret += parts[i];
+ ret += (p_use_arch) ? p_parts[i].arch : p_parts[i].abi;
}
return ret;
}
@@ -2544,7 +2567,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
bool use_custom_build = bool(p_preset->get("custom_build/use_custom_build"));
bool p_give_internet = p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG);
bool apk_expansion = p_preset->get("apk_expansion/enable");
- Vector<String> enabled_abis = get_enabled_abis(p_preset);
+ Vector<ABI> enabled_abis = get_enabled_abis(p_preset);
print_verbose("Exporting for Android...");
print_verbose("- debug build: " + bool_to_string(p_debug));
@@ -2553,7 +2576,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
print_verbose("- sign build: " + bool_to_string(should_sign));
print_verbose("- custom build enabled: " + bool_to_string(use_custom_build));
print_verbose("- apk expansion enabled: " + bool_to_string(apk_expansion));
- print_verbose("- enabled abis: " + String(",").join(enabled_abis));
+ print_verbose("- enabled abis: " + join_abis(enabled_abis, ",", false));
print_verbose("- export filter: " + itos(p_preset->get_export_filter()));
print_verbose("- include filter: " + p_preset->get_include_filter());
print_verbose("- exclude filter: " + p_preset->get_exclude_filter());
@@ -2592,10 +2615,10 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
}
if (use_custom_build) {
- print_verbose("Starting custom build..");
+ print_verbose("Starting custom build...");
//test that installed build version is alright
{
- print_verbose("Checking build version..");
+ print_verbose("Checking build version...");
Ref<FileAccess> f = FileAccess::open("res://android/.build_version", FileAccess::READ);
if (f.is_null()) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Trying to build from a custom built template, but no version info for it exists. Please reinstall from the 'Project' menu."));
@@ -2628,7 +2651,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
_clear_assets_directory();
_remove_copied_libs();
if (!apk_expansion) {
- print_verbose("Exporting project files..");
+ print_verbose("Exporting project files...");
CustomExportData user_data;
user_data.assets_directory = assets_directory;
user_data.debug = p_debug;
@@ -2642,14 +2665,14 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
fa->store_string(JSON::stringify(user_data.libs, "\t"));
}
} else {
- print_verbose("Saving apk expansion file..");
+ print_verbose("Saving apk expansion file...");
err = save_apk_expansion_file(p_preset, p_debug, p_path);
if (err != OK) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Could not write expansion package file!"));
return err;
}
}
- print_verbose("Storing command line flags..");
+ print_verbose("Storing command line flags...");
store_file_at_path(assets_directory + "/_cl_", command_line_flags);
print_verbose("Updating ANDROID_HOME environment to " + sdk_path);
@@ -2676,7 +2699,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (!target_sdk_version.is_valid_int()) {
target_sdk_version = itos(DEFAULT_TARGET_SDK_VERSION);
}
- String enabled_abi_string = String("|").join(enabled_abis);
+ String enabled_abi_string = join_abis(enabled_abis, "|", false);
String sign_flag = should_sign ? "true" : "false";
String zipalign_flag = "true";
@@ -2802,7 +2825,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
return OK;
}
// This is the start of the Legacy build system
- print_verbose("Starting legacy build system..");
+ print_verbose("Starting legacy build system...");
if (p_debug) {
src_apk = p_preset->get("custom_template/debug");
} else {
@@ -2861,7 +2884,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
String apk_expansion_pkey = p_preset->get("apk_expansion/public_key");
- Vector<String> invalid_abis(enabled_abis);
+ Vector<ABI> invalid_abis(enabled_abis);
while (ret == UNZ_OK) {
//get filename
unz_file_info info;
@@ -2924,7 +2947,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
if (file.ends_with(".so")) {
bool enabled = false;
for (int i = 0; i < enabled_abis.size(); ++i) {
- if (file.begins_with("lib/" + enabled_abis[i] + "/")) {
+ if (file.begins_with("lib/" + enabled_abis[i].abi + "/")) {
invalid_abis.erase(enabled_abis[i]);
enabled = true;
break;
@@ -2966,8 +2989,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
}
if (!invalid_abis.is_empty()) {
- String unsupported_arch = String(", ").join(invalid_abis);
- add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), unsupported_arch));
+ add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), vformat(TTR("Missing libraries in the export template for the selected architectures: %s. Please build a template with all required libraries, or uncheck the missing architectures in the export preset."), join_abis(invalid_abis, ", ", false)));
CLEANUP_AND_RETURN(ERR_FILE_NOT_FOUND);
}
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index 46012bd46c..c8fcb761fe 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -99,7 +99,22 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
static zip_fileinfo get_zip_fileinfo();
- static Vector<String> get_abis();
+ struct ABI {
+ String abi;
+ String arch;
+
+ bool operator==(const ABI &p_a) const {
+ return p_a.abi == abi;
+ }
+
+ ABI(const String &p_abi, const String &p_arch) {
+ abi = p_abi;
+ arch = p_arch;
+ }
+ ABI() {}
+ };
+
+ static Vector<ABI> get_abis();
/// List the gdap files in the directory specified by the p_path parameter.
static Vector<String> list_gdap_files(const String &p_path);
@@ -152,7 +167,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
const Ref<Image> &foreground,
const Ref<Image> &background);
- static Vector<String> get_enabled_abis(const Ref<EditorExportPreset> &p_preset);
+ static Vector<ABI> get_enabled_abis(const Ref<EditorExportPreset> &p_preset);
public:
typedef Error (*EditorExportSaveFunction)(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);
@@ -228,7 +243,8 @@ public:
void _remove_copied_libs();
- String join_list(List<String> parts, const String &separator) const;
+ static String join_list(const List<String> &p_parts, const String &p_separator);
+ static String join_abis(const Vector<ABI> &p_parts, const String &p_separator, bool p_use_arch);
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index 0346625e4b..e1d9dc4cde 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,10 +1,10 @@
ext.versions = [
- androidGradlePlugin: '7.0.3',
+ androidGradlePlugin: '7.2.1',
compileSdk : 32,
- minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
- targetSdk : 32, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
+ minSdk : 19, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION'
+ targetSdk : 32, // Also update 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION'
buildTools : '32.0.0',
- kotlinVersion : '1.6.21',
+ kotlinVersion : '1.7.0',
fragmentVersion : '1.3.6',
nexusPublishVersion: '1.1.0',
javaVersion : 11,
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
index 489a81fc1a..46a334ef38 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/GodotEditor.kt
@@ -37,10 +37,12 @@ import android.os.Build
import android.os.Bundle
import android.os.Debug
import android.os.Environment
+import android.util.Log
import android.widget.Toast
import androidx.window.layout.WindowMetricsCalculator
import org.godotengine.godot.FullScreenGodotApp
import org.godotengine.godot.utils.PermissionsUtil
+import org.godotengine.godot.utils.ProcessPhoenix
import java.util.*
import kotlin.math.min
@@ -56,12 +58,17 @@ import kotlin.math.min
open class GodotEditor : FullScreenGodotApp() {
companion object {
+ private val TAG = GodotEditor::class.java.simpleName
+
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 EDITOR_ARG_SHORT = "-e"
+
private const val PROJECT_MANAGER_ARG = "--project-manager"
+ private const val PROJECT_MANAGER_ARG_SHORT = "-p"
}
private val commandLineParams = ArrayList<String>()
@@ -105,13 +112,13 @@ open class GodotEditor : FullScreenGodotApp() {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (isInMultiWindowMode || isLargeScreen)
for (arg in args) {
- if (EDITOR_ARG == arg) {
+ if (EDITOR_ARG == arg || EDITOR_ARG_SHORT == arg) {
targetClass = GodotEditor::class.java
launchAdjacent = false
break
}
- if (PROJECT_MANAGER_ARG == arg) {
+ if (PROJECT_MANAGER_ARG == arg || PROJECT_MANAGER_ARG_SHORT == arg) {
targetClass = GodotProjectManager::class.java
launchAdjacent = false
break
@@ -125,7 +132,13 @@ open class GodotEditor : FullScreenGodotApp() {
if (launchAdjacent) {
newInstance.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT)
}
- startActivity(newInstance)
+ if (targetClass == javaClass) {
+ Log.d(TAG, "Restarting $targetClass")
+ ProcessPhoenix.triggerRebirth(this, newInstance)
+ } else {
+ Log.d(TAG, "Starting $targetClass")
+ startActivity(newInstance)
+ }
}
// Get the screen's density scale
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
index ffed3a254e..41dfb87909 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml
index 79b5aadf2a..1f77e2fc34 100644
--- a/platform/android/java/lib/AndroidManifest.xml
+++ b/platform/android/java/lib/AndroidManifest.xml
@@ -4,9 +4,6 @@
android:versionCode="1"
android:versionName="1.0">
- <!-- Should match the mindSdk and targetSdk values in platform/android/java/app/config.gradle -->
- <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="32" />
-
<application>
<!-- Records the version of the Godot library -->
diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle
index c9e2a5d7d2..841656a240 100644
--- a/platform/android/java/lib/build.gradle
+++ b/platform/android/java/lib/build.gradle
@@ -176,11 +176,10 @@ android {
}
}
- // TODO: Enable when issues with AGP 7.1+ are resolved (https://github.com/GodotVR/godot_openxr/issues/187).
-// publishing {
-// singleVariant("templateRelease") {
-// withSourcesJar()
-// withJavadocJar()
-// }
-// }
+ publishing {
+ singleVariant("templateRelease") {
+ withSourcesJar()
+ withJavadocJar()
+ }
+ }
}
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 92e5e59496..a002a37ab9 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -299,7 +299,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
plugin.onRegisterPluginWithGodotNative();
}
- setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
+ setKeepScreenOn(Boolean.parseBoolean(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
});
// Include the returned non-null views in the Godot view hierarchy.
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 7925b54fc4..804dbaf165 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
@@ -127,7 +127,9 @@ public class GodotEditText extends EditText {
edit.setText("");
edit.append(text);
if (msg.arg2 != -1) {
- edit.setSelection(msg.arg1, msg.arg2);
+ int selectionStart = Math.min(msg.arg1, edit.length());
+ int selectionEnd = Math.min(msg.arg2, edit.length());
+ edit.setSelection(selectionStart, selectionEnd);
edit.mInputWrapper.setSelection(true);
} else {
edit.mInputWrapper.setSelection(false);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
index a7a57621de..cde8d7cdae 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
@@ -77,7 +77,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
}
private fun contextClickRouter(event: MotionEvent) {
- if (scaleInProgress) {
+ if (scaleInProgress || nextDownIsDoubleTap) {
return
}
@@ -134,40 +134,24 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
}
private fun onActionUp(event: MotionEvent): Boolean {
+ if (event.actionMasked == MotionEvent.ACTION_CANCEL && pointerCaptureInProgress) {
+ // Don't dispatch the ACTION_CANCEL while a capture is in progress
+ return true
+ }
+
val sourceMouseRelative = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
event.isFromSource(InputDevice.SOURCE_MOUSE_RELATIVE)
} else {
false
}
- when {
- pointerCaptureInProgress -> {
- return if (event.actionMasked == MotionEvent.ACTION_CANCEL) {
- // Don't dispatch the ACTION_CANCEL while a capture is in progress
- true
- } else {
- GodotInputHandler.handleMouseEvent(
- MotionEvent.ACTION_UP,
- event.buttonState,
- event.x,
- event.y,
- 0f,
- 0f,
- false,
- sourceMouseRelative
- )
- pointerCaptureInProgress = false
- true
- }
- }
- dragInProgress -> {
- GodotInputHandler.handleMotionEvent(event)
- dragInProgress = false
- return true
- }
- contextClickInProgress -> {
+
+ if (pointerCaptureInProgress || dragInProgress || contextClickInProgress) {
+ if (contextClickInProgress || GodotInputHandler.isMouseEvent(event)) {
+ // This may be an ACTION_BUTTON_RELEASE event which we don't handle,
+ // so we convert it to an ACTION_UP event.
GodotInputHandler.handleMouseEvent(
- event.actionMasked,
- 0,
+ MotionEvent.ACTION_UP,
+ event.buttonState,
event.x,
event.y,
0f,
@@ -175,11 +159,16 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
false,
sourceMouseRelative
)
- contextClickInProgress = false
- return true
+ } else {
+ GodotInputHandler.handleTouchEvent(event)
}
- else -> return false
+ pointerCaptureInProgress = false
+ dragInProgress = false
+ contextClickInProgress = false
+ return true
}
+
+ return false
}
private fun onActionMove(event: MotionEvent): Boolean {
@@ -242,7 +231,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
val x = terminusEvent.x
val y = terminusEvent.y
- if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled) {
+ if (terminusEvent.pointerCount >= 2 && panningAndScalingEnabled && !pointerCaptureInProgress) {
GodotLib.pan(x, y, distanceX / 5f, distanceY / 5f)
} else {
GodotInputHandler.handleMotionEvent(terminusEvent)
@@ -251,7 +240,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
}
override fun onScale(detector: ScaleGestureDetector?): Boolean {
- if (detector == null || !panningAndScalingEnabled) {
+ if (detector == null || !panningAndScalingEnabled || pointerCaptureInProgress) {
return false
}
GodotLib.magnify(
@@ -263,7 +252,7 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
}
override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean {
- if (detector == null || !panningAndScalingEnabled) {
+ if (detector == null || !panningAndScalingEnabled || pointerCaptureInProgress) {
return false
}
scaleInProgress = true
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 d2f3c5aed2..2f26497cc8 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
@@ -245,7 +245,7 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
}
return true;
}
- } else if (isMouseEvent(event)) {
+ } else {
return handleMouseEvent(event);
}
@@ -473,6 +473,9 @@ public class GodotInputHandler implements InputManager.InputDeviceListener {
}
static boolean handleMouseEvent(int eventAction, int buttonsMask, float x, float y, float deltaX, float deltaY, boolean doubleClick, boolean sourceMouseRelative) {
+ // We don't handle ACTION_BUTTON_PRESS and ACTION_BUTTON_RELEASE events as they typically
+ // follow ACTION_DOWN and ACTION_UP events. As such, handling them would result in duplicate
+ // stream of events to the engine.
switch (eventAction) {
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index b5cb9d341d..c2c25601d7 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -71,6 +71,39 @@ static Vector3 gravity;
static Vector3 magnetometer;
static Vector3 gyroscope;
+static void _terminate(JNIEnv *env, bool p_restart = false) {
+ step.set(-1); // Ensure no further steps are attempted and no further events are sent
+
+ // lets cleanup
+ if (java_class_wrapper) {
+ memdelete(java_class_wrapper);
+ }
+ if (input_handler) {
+ delete input_handler;
+ }
+ // Whether restarting is handled by 'Main::cleanup()'
+ bool restart_on_cleanup = false;
+ if (os_android) {
+ restart_on_cleanup = os_android->is_restart_on_exit_set();
+ os_android->main_loop_end();
+ Main::cleanup();
+ delete os_android;
+ }
+ if (godot_io_java) {
+ delete godot_io_java;
+ }
+ if (godot_java) {
+ if (!restart_on_cleanup) {
+ if (p_restart) {
+ godot_java->restart(env);
+ } else {
+ godot_java->force_quit(env);
+ }
+ }
+ delete godot_java;
+ }
+}
+
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jclass clazz, jint p_height) {
@@ -104,23 +137,7 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) {
- // lets cleanup
- if (java_class_wrapper) {
- memdelete(java_class_wrapper);
- }
- if (godot_io_java) {
- delete godot_io_java;
- }
- if (godot_java) {
- delete godot_java;
- }
- if (input_handler) {
- delete input_handler;
- }
- if (os_android) {
- os_android->main_loop_end();
- delete os_android;
- }
+ _terminate(env, false);
}
JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline) {
@@ -196,9 +213,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en
}
} else {
// Rendering context recreated because it was lost; restart app to let it reload everything
- step.set(-1); // Ensure no further steps are attempted and no further events are sent
- os_android->main_loop_end();
- godot_java->restart(env);
+ _terminate(env, true);
}
}
}
@@ -249,7 +264,7 @@ JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env,
bool should_swap_buffers = false;
if (os_android->main_loop_iterate(&should_swap_buffers)) {
- godot_java->force_quit(env);
+ _terminate(env, false);
}
return should_swap_buffers;
diff --git a/platform/android/java_godot_view_wrapper.cpp b/platform/android/java_godot_view_wrapper.cpp
index 762840a4b1..378a467772 100644
--- a/platform/android/java_godot_view_wrapper.cpp
+++ b/platform/android/java_godot_view_wrapper.cpp
@@ -68,7 +68,7 @@ void GodotJavaViewWrapper::request_pointer_capture() {
}
void GodotJavaViewWrapper::release_pointer_capture() {
- if (_request_pointer_capture != nullptr) {
+ if (_release_pointer_capture != nullptr) {
JNIEnv *env = get_jni_env();
ERR_FAIL_NULL(env);
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 4469c7a0f7..97fa90b1d2 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -162,11 +162,16 @@ Vector<String> OS_Android::get_granted_permissions() const {
}
Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path, String *r_resolved_path) {
- p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW);
+ String path = p_path;
+ if (!FileAccess::exists(path)) {
+ path = p_path.get_file();
+ }
+
+ p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + ".");
if (r_resolved_path != nullptr) {
- *r_resolved_path = p_path;
+ *r_resolved_path = path;
}
return OK;
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index 498977ad49..5a7123b833 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -135,7 +135,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegis
}
// Retrieve the current list of gdnative libraries.
- Array singletons = Array();
+ Array singletons;
if (ProjectSettings::get_singleton()->has_setting("gdnative/singletons")) {
singletons = GLOBAL_GET("gdnative/singletons");
}