diff options
Diffstat (limited to 'platform/android')
94 files changed, 1199 insertions, 838 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub index 65172a12c0..fd2a774c71 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -12,12 +12,12 @@ android_files = [ 'file_access_jandroid.cpp', 'dir_access_jandroid.cpp', 'thread_jandroid.cpp', + 'net_socket_android.cpp', 'audio_driver_jandroid.cpp', 'java_godot_lib_jni.cpp', 'java_class_wrapper.cpp', 'java_godot_wrapper.cpp', 'java_godot_io_wrapper.cpp', - #'power_android.cpp' ] env_android = env.Clone() diff --git a/platform/android/api/api.cpp b/platform/android/api/api.cpp new file mode 100644 index 0000000000..7efb545524 --- /dev/null +++ b/platform/android/api/api.cpp @@ -0,0 +1,86 @@ +/*************************************************************************/ +/* api.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +#include "api.h" + +#include "core/engine.h" +#include "java_class_wrapper.h" + +#if !defined(ANDROID_ENABLED) +static JavaClassWrapper *java_class_wrapper = NULL; +#endif + +void register_android_api() { + +#if !defined(ANDROID_ENABLED) + java_class_wrapper = memnew(JavaClassWrapper); // Dummy +#endif + + ClassDB::register_class<JavaClass>(); + ClassDB::register_class<JavaClassWrapper>(); + Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", JavaClassWrapper::get_singleton())); +} + +void unregister_android_api() { + +#if !defined(ANDROID_ENABLED) + memdelete(java_class_wrapper); +#endif +} + +void JavaClassWrapper::_bind_methods() { + + ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap); +} + +#if !defined(ANDROID_ENABLED) + +Variant JavaClass::call(const StringName &, const Variant **, int, Callable::CallError &) { + return Variant(); +} + +JavaClass::JavaClass() { +} + +Variant JavaObject::call(const StringName &, const Variant **, int, Callable::CallError &) { + return Variant(); +} + +JavaClassWrapper *JavaClassWrapper::singleton = NULL; + +Ref<JavaClass> JavaClassWrapper::wrap(const String &) { + return Ref<JavaClass>(); +} + +JavaClassWrapper::JavaClassWrapper() { + singleton = this; +} + +#endif diff --git a/platform/android/power_android.h b/platform/android/api/api.h index 6cb745b6c0..c7296d92a7 100644 --- a/platform/android/power_android.h +++ b/platform/android/api/api.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_android.h */ +/* api.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -28,53 +28,5 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POWER_ANDROID_H -#define POWER_ANDROID_H - -#include "core/os/os.h" - -#include <android/native_window_jni.h> - -class PowerAndroid { - - struct LocalReferenceHolder { - JNIEnv *m_env; - const char *m_func; - }; - -private: - static struct LocalReferenceHolder refs; - static JNIEnv *env; - static jmethodID mid; - static jobject context; - static jstring action; - static jclass cls; - static jobject filter; - static jobject intent; - static jstring iname; - static jmethodID imid; - static jstring bname; - static jmethodID bmid; - - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - bool GetPowerInfo_Android(); - bool UpdatePowerInfo(); - -public: - static int s_active; - - PowerAndroid(); - virtual ~PowerAndroid(); - static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env); - static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func); - static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_ANDROID_H +void register_android_api(); +void unregister_android_api(); diff --git a/platform/android/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h index e9471a1897..48b581958b 100644 --- a/platform/android/java_class_wrapper.h +++ b/platform/android/api/java_class_wrapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -32,16 +32,22 @@ #define JAVA_CLASS_WRAPPER_H #include "core/reference.h" + +#ifdef ANDROID_ENABLED #include <android/log.h> #include <jni.h> +#endif +#ifdef ANDROID_ENABLED class JavaObject; +#endif class JavaClass : public Reference { GDCLASS(JavaClass, Reference); - enum ArgumentType { +#ifdef ANDROID_ENABLED + enum ArgumentType{ ARG_TYPE_VOID, ARG_TYPE_BOOLEAN, @@ -107,12 +113,12 @@ class JavaClass : public Reference { break; case ARG_TYPE_FLOAT | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_FLOAT: - r_type = Variant::REAL; + r_type = Variant::FLOAT; likelihood = 1.0; break; case ARG_TYPE_DOUBLE | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_DOUBLE: - r_type = Variant::REAL; + r_type = Variant::FLOAT; likelihood = 0.5; break; case ARG_TYPE_STRING: r_type = Variant::STRING; break; @@ -120,48 +126,49 @@ class JavaClass : public Reference { case ARG_ARRAY_BIT | ARG_TYPE_VOID: r_type = Variant::NIL; break; case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: r_type = Variant::ARRAY; break; case ARG_ARRAY_BIT | ARG_TYPE_BYTE: - r_type = Variant::POOL_BYTE_ARRAY; + r_type = Variant::PACKED_BYTE_ARRAY; likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_CHAR: - r_type = Variant::POOL_BYTE_ARRAY; + r_type = Variant::PACKED_BYTE_ARRAY; likelihood = 0.5; break; case ARG_ARRAY_BIT | ARG_TYPE_SHORT: - r_type = Variant::POOL_INT_ARRAY; + r_type = Variant::PACKED_INT32_ARRAY; likelihood = 0.3; break; case ARG_ARRAY_BIT | ARG_TYPE_INT: - r_type = Variant::POOL_INT_ARRAY; + r_type = Variant::PACKED_INT32_ARRAY; likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_LONG: - r_type = Variant::POOL_INT_ARRAY; + r_type = Variant::PACKED_INT32_ARRAY; likelihood = 0.5; break; case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: - r_type = Variant::POOL_REAL_ARRAY; + r_type = Variant::PACKED_FLOAT32_ARRAY; likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: - r_type = Variant::POOL_REAL_ARRAY; + r_type = Variant::PACKED_FLOAT32_ARRAY; likelihood = 0.5; break; - case ARG_ARRAY_BIT | ARG_TYPE_STRING: r_type = Variant::POOL_STRING_ARRAY; break; + case ARG_ARRAY_BIT | ARG_TYPE_STRING: r_type = Variant::PACKED_STRING_ARRAY; break; case ARG_ARRAY_BIT | ARG_TYPE_CLASS: r_type = Variant::ARRAY; break; } } _FORCE_INLINE_ static bool _convert_object_to_variant(JNIEnv *env, jobject obj, Variant &var, uint32_t p_sig); - bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error, Variant &ret); + bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret); friend class JavaClassWrapper; Map<StringName, List<MethodInfo> > methods; jclass _class; +#endif public: - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); JavaClass(); }; @@ -170,22 +177,27 @@ class JavaObject : public Reference { GDCLASS(JavaObject, Reference); +#ifdef ANDROID_ENABLED Ref<JavaClass> base_class; friend class JavaClass; jobject instance; +#endif public: - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); +#ifdef ANDROID_ENABLED JavaObject(const Ref<JavaClass> &p_base, jobject *p_instance); ~JavaObject(); +#endif }; class JavaClassWrapper : public Object { GDCLASS(JavaClassWrapper, Object); +#ifdef ANDROID_ENABLED Map<String, Ref<JavaClass> > class_cache; friend class JavaClass; jclass activityClass; @@ -211,6 +223,7 @@ class JavaClassWrapper : public Object { jobject classLoader; bool _get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig); +#endif static JavaClassWrapper *singleton; @@ -222,7 +235,11 @@ public: Ref<JavaClass> wrap(const String &p_class); +#ifdef ANDROID_ENABLED JavaClassWrapper(jobject p_activity = NULL); +#else + JavaClassWrapper(); +#endif }; #endif // JAVA_CLASS_WRAPPER_H diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index bcef5b0c85..5a8e3b94da 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h index f92ef06052..d3d1641c20 100644 --- a/platform/android/audio_driver_jandroid.h +++ b/platform/android/audio_driver_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index 711088c158..6e9864c803 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -208,8 +208,8 @@ void AudioDriverOpenSL::_record_buffer_callback(SLAndroidSimpleBufferQueueItf qu for (int i = 0; i < rec_buffer.size(); i++) { int32_t sample = rec_buffer[i] << 16; - capture_buffer_write(sample); - capture_buffer_write(sample); // call twice to convert to Stereo + input_buffer_write(sample); + input_buffer_write(sample); // call twice to convert to Stereo } SLresult res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t)); @@ -280,7 +280,7 @@ Error AudioDriverOpenSL::capture_init_device() { const int rec_buffer_frames = 2048; rec_buffer.resize(rec_buffer_frames); - capture_buffer_init(rec_buffer_frames); + input_buffer_init(rec_buffer_frames); res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t)); ERR_FAIL_COND_V(res != SL_RESULT_SUCCESS, ERR_CANT_OPEN); diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h index 2981073cec..57d9b30af6 100644 --- a/platform/android/audio_driver_opensl.h +++ b/platform/android/audio_driver_opensl.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 8c464465ca..f52b511522 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -110,7 +110,6 @@ String DirAccessJAndroid::get_drive(int p_drive) { Error DirAccessJAndroid::change_dir(String p_dir) { JNIEnv *env = ThreadAndroid::get_env(); - p_dir = p_dir.simplify_path(); if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == "")) return OK; diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index cdea93ff4c..caeb4b58b9 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 6d021ad33a..50bf671a84 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -30,6 +30,7 @@ #include "export.h" +#include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" #include "core/os/dir_access.h" @@ -37,7 +38,9 @@ #include "core/os/os.h" #include "core/project_settings.h" #include "core/version.h" +#include "drivers/png/png_driver_common.h" #include "editor/editor_export.h" +#include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "platform/android/logo.gen.h" @@ -195,16 +198,40 @@ static const char *android_perms[] = { }; struct LauncherIcon { - const char *option_id; const char *export_path; + int dimensions; }; -static const LauncherIcon launcher_icons[] = { - { "launcher_icons/xxxhdpi_192x192", "res/drawable-xxxhdpi-v4/icon.png" }, - { "launcher_icons/xxhdpi_144x144", "res/drawable-xxhdpi-v4/icon.png" }, - { "launcher_icons/xhdpi_96x96", "res/drawable-xhdpi-v4/icon.png" }, - { "launcher_icons/hdpi_72x72", "res/drawable-hdpi-v4/icon.png" }, - { "launcher_icons/mdpi_48x48", "res/drawable-mdpi-v4/icon.png" } +static const int icon_densities_count = 6; +static const char *launcher_icon_option = "launcher_icons/main_192x192"; +static const char *launcher_adaptive_icon_foreground_option = "launcher_icons/adaptive_foreground_432x432"; +static const char *launcher_adaptive_icon_background_option = "launcher_icons/adaptive_background_432x432"; + +static const LauncherIcon launcher_icons[icon_densities_count] = { + { "res/mipmap-xxxhdpi-v4/icon.png", 192 }, + { "res/mipmap-xxhdpi-v4/icon.png", 144 }, + { "res/mipmap-xhdpi-v4/icon.png", 96 }, + { "res/mipmap-hdpi-v4/icon.png", 72 }, + { "res/mipmap-mdpi-v4/icon.png", 48 }, + { "res/mipmap/icon.png", 192 } +}; + +static const LauncherIcon launcher_adaptive_icon_foregrounds[icon_densities_count] = { + { "res/mipmap-xxxhdpi-v4/icon_foreground.png", 432 }, + { "res/mipmap-xxhdpi-v4/icon_foreground.png", 324 }, + { "res/mipmap-xhdpi-v4/icon_foreground.png", 216 }, + { "res/mipmap-hdpi-v4/icon_foreground.png", 162 }, + { "res/mipmap-mdpi-v4/icon_foreground.png", 108 }, + { "res/mipmap/icon_foreground.png", 432 } +}; + +static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_count] = { + { "res/mipmap-xxxhdpi-v4/icon_background.png", 432 }, + { "res/mipmap-xxhdpi-v4/icon_background.png", 324 }, + { "res/mipmap-xhdpi-v4/icon_background.png", 216 }, + { "res/mipmap-hdpi-v4/icon_background.png", 162 }, + { "res/mipmap-mdpi-v4/icon_background.png", 108 }, + { "res/mipmap/icon_background.png", 432 } }; class EditorExportPlatformAndroid : public EditorExportPlatform { @@ -310,7 +337,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { Vector<String> props = dp.split("\n"); String vendor; String device; - d.description + "Device ID: " + d.id + "\n"; + d.description = "Device ID: " + d.id + "\n"; d.api_level = 0; for (int j = 0; j < props.size(); j++) { @@ -358,7 +385,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { ea->device_lock->unlock(); } - uint64_t sleep = OS::get_singleton()->get_power_state() == OS::POWERSTATE_ON_BATTERY ? 1000 : 100; + uint64_t sleep = 200; uint64_t wait = 3000000; uint64_t time = OS::get_singleton()->get_ticks_usec(); while (OS::get_singleton()->get_ticks_usec() - time < wait) { @@ -583,7 +610,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { static Error save_apk_so(void *p_userdata, const SharedObject &p_so) { if (!p_so.path.get_file().begins_with("lib")) { String err = "Android .so file names must start with \"lib\", but got: " + p_so.path; - ERR_PRINTS(err); + ERR_PRINT(err); return FAILED; } APKExportData *ed = (APKExportData *)p_userdata; @@ -604,7 +631,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { 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_PRINTS(err); + ERR_PRINT(err); return FAILED; } return OK; @@ -615,9 +642,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { String dst_path = p_path.replace_first("res://", "assets/"); store_in_apk(ed, dst_path, p_data, _should_compress_asset(p_path, p_data) ? Z_DEFLATED : 0); - if (ed->ep->step("File: " + p_path, 3 + p_file * 100 / p_total)) { - return ERR_SKIP; - } return OK; } @@ -659,14 +683,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int orientation = p_preset->get("screen/orientation"); - bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES3" && - !ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2"); bool screen_support_small = p_preset->get("screen/support_small"); bool screen_support_normal = p_preset->get("screen/support_normal"); bool screen_support_large = p_preset->get("screen/support_large"); bool screen_support_xlarge = p_preset->get("screen/support_xlarge"); - int xr_mode_index = p_preset->get("graphics/xr_mode"); + int xr_mode_index = p_preset->get("xr_features/xr_mode"); Vector<String> perms; @@ -679,7 +701,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { aperms++; } - PoolStringArray user_perms = p_preset->get("permissions/custom_permissions"); + PackedStringArray user_perms = p_preset->get("permissions/custom_permissions"); for (int i = 0; i < user_perms.size(); i++) { String user_perm = user_perms[i].strip_edges(); @@ -815,11 +837,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } } - if (tname == "uses-feature" && attrname == "glEsVersion") { - - encode_uint32(min_gles3 ? 0x00030000 : 0x00020000, &p_manifest.write[iofs + 16]); - } - // FIXME: `attr_value != 0xFFFFFFFF` below added as a stopgap measure for GH-32553, // but the issue should be debugged further and properly addressed. if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") { @@ -845,135 +862,174 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { uint32_t name = decode_uint32(&p_manifest[iofs + 12]); String tname = string_table[name]; - int dof_index = p_preset->get("graphics/degrees_of_freedom"); // 0: none, 1: 3dof and 6dof, 2: 6dof + if (tname == "uses-feature") { + Vector<String> feature_names; + Vector<bool> feature_required_list; + Vector<int> feature_versions; + + if (xr_mode_index == 1 /* XRMode.OVR */) { + // Check for degrees of freedom + int dof_index = p_preset->get("xr_features/degrees_of_freedom"); // 0: none, 1: 3dof and 6dof, 2: 6dof + + if (dof_index > 0) { + feature_names.push_back("android.hardware.vr.headtracking"); + feature_required_list.push_back(dof_index == 2); + 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) { + feature_names.push_back("oculus.software.handtracking"); + feature_required_list.push_back(hand_tracking_index == 2); + feature_versions.push_back(-1); // no version attribute should be added. - if (tname == "uses-feature" && dof_index > 0) { - if (xr_mode_index == 0) { - WARN_PRINT("VR DOF feature setting is only valid for oculus HMDs with an XR mode set to VR"); + if (perms.find("oculus.permission.handtracking") == -1) { + perms.push_back("oculus.permission.handtracking"); + } + } } - ofs += 24; // skip over end tag - // save manifest ending so we can restore it - Vector<uint8_t> manifest_end; - uint32_t manifest_cur_size = p_manifest.size(); + if (feature_names.size() > 0) { + ofs += 24; // skip over end tag - manifest_end.resize(p_manifest.size() - ofs); - memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size()); + // save manifest ending so we can restore it + Vector<uint8_t> manifest_end; + uint32_t manifest_cur_size = p_manifest.size(); - int32_t attr_name_string = string_table.find("name"); - ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute."); + manifest_end.resize(p_manifest.size() - ofs); + memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size()); - int32_t ns_android_string = string_table.find("http://schemas.android.com/apk/res/android"); - if (ns_android_string == -1) { - string_table.push_back("http://schemas.android.com/apk/res/android"); - ns_android_string = string_table.size() - 1; - } + int32_t attr_name_string = string_table.find("name"); + ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute."); - int32_t attr_uses_permission_string = string_table.find("uses-feature"); - if (attr_uses_permission_string == -1) { - string_table.push_back("uses-feature"); - attr_uses_permission_string = string_table.size() - 1; - } + int32_t ns_android_string = string_table.find("http://schemas.android.com/apk/res/android"); + if (ns_android_string == -1) { + string_table.push_back("http://schemas.android.com/apk/res/android"); + ns_android_string = string_table.size() - 1; + } - int32_t attr_required_string = string_table.find("required"); - if (attr_required_string == -1) { - string_table.push_back("required"); - attr_required_string = string_table.size() - 1; - } + int32_t attr_uses_feature_string = string_table.find("uses-feature"); + if (attr_uses_feature_string == -1) { + string_table.push_back("uses-feature"); + attr_uses_feature_string = string_table.size() - 1; + } - int32_t attr_version_string = string_table.find("version"); - if (attr_version_string == -1) { - string_table.push_back("version"); - attr_version_string = string_table.size() - 1; - } + int32_t attr_required_string = string_table.find("required"); + if (attr_required_string == -1) { + string_table.push_back("required"); + attr_required_string = string_table.size() - 1; + } - String required_value_string; - if (dof_index == 1) { - required_value_string = "false"; - } else if (dof_index == 2) { - required_value_string = "true"; - } else { - ERR_FAIL_MSG("Unknown DoF index: " + itos(dof_index) + "."); - } - int32_t required_value = string_table.find(required_value_string); - if (required_value == -1) { - string_table.push_back(required_value_string); - required_value = string_table.size() - 1; - } + for (int i = 0; i < feature_names.size(); i++) { + String feature_name = feature_names[i]; + bool feature_required = feature_required_list[i]; + int feature_version = feature_versions[i]; + bool has_version_attribute = feature_version != -1; - int32_t version_value = string_table.find("1"); - if (version_value == -1) { - string_table.push_back("1"); - version_value = string_table.size() - 1; - } + print_line("Adding feature " + feature_name); - int32_t feature_string = string_table.find("android.hardware.vr.headtracking"); - if (feature_string == -1) { - string_table.push_back("android.hardware.vr.headtracking"); - feature_string = string_table.size() - 1; - } + int32_t feature_string = string_table.find(feature_name); + if (feature_string == -1) { + string_table.push_back(feature_name); + feature_string = string_table.size() - 1; + } - { - manifest_cur_size += 96 + 20; // node and three attrs + end node - p_manifest.resize(manifest_cur_size); + String required_value_string = feature_required ? "true" : "false"; + int32_t required_value = string_table.find(required_value_string); + if (required_value == -1) { + string_table.push_back(required_value_string); + required_value = string_table.size() - 1; + } - // start tag - encode_uint16(0x102, &p_manifest.write[ofs]); // type - encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize - encode_uint32(96, &p_manifest.write[ofs + 4]); // size - encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno - encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment - encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns - encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name - encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start - encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size - encode_uint16(3, &p_manifest.write[ofs + 28]); // num_attrs - encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index - encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index - encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index + int32_t attr_version_string = -1; + int32_t version_value = -1; + int tag_size; + int attr_count; + if (has_version_attribute) { + attr_version_string = string_table.find("version"); + if (attr_version_string == -1) { + string_table.push_back("version"); + attr_version_string = string_table.size() - 1; + } - // android:name attribute - encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns - encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name' - encode_uint32(feature_string, &p_manifest.write[ofs + 44]); // raw_value - encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size - p_manifest.write[ofs + 50] = 0; // typedvalue_always0 - p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string) - encode_uint32(feature_string, &p_manifest.write[ofs + 52]); // typedvalue reference - - // android:required attribute - encode_uint32(ns_android_string, &p_manifest.write[ofs + 56]); // ns - encode_uint32(attr_required_string, &p_manifest.write[ofs + 60]); // 'name' - encode_uint32(required_value, &p_manifest.write[ofs + 64]); // raw_value - encode_uint16(8, &p_manifest.write[ofs + 68]); // typedvalue_size - p_manifest.write[ofs + 70] = 0; // typedvalue_always0 - p_manifest.write[ofs + 71] = 0x03; // typedvalue_type (string) - encode_uint32(required_value, &p_manifest.write[ofs + 72]); // typedvalue reference - - // android:version attribute - encode_uint32(ns_android_string, &p_manifest.write[ofs + 76]); // ns - encode_uint32(attr_version_string, &p_manifest.write[ofs + 80]); // 'name' - encode_uint32(version_value, &p_manifest.write[ofs + 84]); // raw_value - encode_uint16(8, &p_manifest.write[ofs + 88]); // typedvalue_size - p_manifest.write[ofs + 90] = 0; // typedvalue_always0 - p_manifest.write[ofs + 91] = 0x03; // typedvalue_type (string) - encode_uint32(version_value, &p_manifest.write[ofs + 92]); // typedvalue reference - - ofs += 96; + version_value = string_table.find(itos(feature_version)); + if (version_value == -1) { + string_table.push_back(itos(feature_version)); + version_value = string_table.size() - 1; + } - // end tag - encode_uint16(0x103, &p_manifest.write[ofs]); // type - encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize - encode_uint32(24, &p_manifest.write[ofs + 4]); // size - encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno - encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment - encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns - encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name + tag_size = 96; // node and three attrs + end node + attr_count = 3; + } else { + tag_size = 76; // node and two attrs + end node + attr_count = 2; + } + manifest_cur_size += tag_size + 24; + p_manifest.resize(manifest_cur_size); + + // start tag + encode_uint16(0x102, &p_manifest.write[ofs]); // type + encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize + encode_uint32(tag_size, &p_manifest.write[ofs + 4]); // size + encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno + encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment + encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns + encode_uint32(attr_uses_feature_string, &p_manifest.write[ofs + 20]); // name + encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start + encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size + encode_uint16(attr_count, &p_manifest.write[ofs + 28]); // num_attrs + encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index + encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index + encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index + + // android:name attribute + encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns + encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name' + encode_uint32(feature_string, &p_manifest.write[ofs + 44]); // raw_value + encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size + p_manifest.write[ofs + 50] = 0; // typedvalue_always0 + p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string) + encode_uint32(feature_string, &p_manifest.write[ofs + 52]); // typedvalue reference + + // android:required attribute + encode_uint32(ns_android_string, &p_manifest.write[ofs + 56]); // ns + encode_uint32(attr_required_string, &p_manifest.write[ofs + 60]); // 'name' + encode_uint32(required_value, &p_manifest.write[ofs + 64]); // raw_value + encode_uint16(8, &p_manifest.write[ofs + 68]); // typedvalue_size + p_manifest.write[ofs + 70] = 0; // typedvalue_always0 + p_manifest.write[ofs + 71] = 0x03; // typedvalue_type (string) + encode_uint32(required_value, &p_manifest.write[ofs + 72]); // typedvalue reference + + ofs += 76; + + if (has_version_attribute) { + // android:version attribute + encode_uint32(ns_android_string, &p_manifest.write[ofs]); // ns + encode_uint32(attr_version_string, &p_manifest.write[ofs + 4]); // 'name' + encode_uint32(version_value, &p_manifest.write[ofs + 8]); // raw_value + encode_uint16(8, &p_manifest.write[ofs + 12]); // typedvalue_size + p_manifest.write[ofs + 14] = 0; // typedvalue_always0 + p_manifest.write[ofs + 15] = 0x03; // typedvalue_type (string) + encode_uint32(version_value, &p_manifest.write[ofs + 16]); // typedvalue reference + + ofs += 20; + } - ofs += 24; + // end tag + encode_uint16(0x103, &p_manifest.write[ofs]); // type + encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize + encode_uint32(24, &p_manifest.write[ofs + 4]); // size + encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno + encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment + encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns + encode_uint32(attr_uses_feature_string, &p_manifest.write[ofs + 20]); // name + + ofs += 24; + } + memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size()); + ofs -= 24; // go back over back end } - memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size()); - ofs -= 24; // go back over back end } if (tname == "manifest") { @@ -1245,6 +1301,27 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { //printf("end\n"); } + void _process_launcher_icons(const String &p_processing_file_name, const Ref<Image> &p_source_image, const LauncherIcon p_icon, Vector<uint8_t> &p_data) { + if (p_processing_file_name == p_icon.export_path) { + Ref<Image> working_image = p_source_image; + + if (p_source_image->get_width() != p_icon.dimensions || p_source_image->get_height() != p_icon.dimensions) { + working_image = p_source_image->duplicate(); + working_image->resize(p_icon.dimensions, p_icon.dimensions, Image::Interpolation::INTERPOLATE_LANCZOS); + } + + Vector<uint8_t> png_buffer; + Error err = PNGDriverCommon::image_to_png(working_image, png_buffer); + if (err == OK) { + p_data.resize(png_buffer.size()); + memcpy(p_data.ptrw(), png_buffer.ptr(), p_data.size()); + } else { + String err_str = String("Failed to convert resized icon (") + p_processing_file_name + ") to png."; + WARN_PRINT(err_str.utf8().get_data()); + } + } + } + static Vector<String> get_enabled_abis(const Ref<EditorExportPreset> &p_preset) { Vector<String> abis = get_abis(); Vector<String> enabled_abis; @@ -1266,11 +1343,10 @@ public: String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); if (driver == "GLES2") { r_features->push_back("etc"); - } else if (driver == "GLES3") { + } + // FIXME: Review what texture formats are used for Vulkan. + if (driver == "Vulkan") { r_features->push_back("etc2"); - if (ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2")) { - r_features->push_back("etc"); - } } Vector<String> abis = get_enabled_abis(p_preset); @@ -1281,13 +1357,14 @@ public: virtual void get_export_options(List<ExportOption> *r_options) { - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_package/use_custom_build"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); 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")); @@ -1301,11 +1378,9 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/opengl_debug"), false)); - - for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), "")); - } - + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password"), "")); @@ -1323,7 +1398,7 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + abi), is_default)); } - r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "permissions/custom_permissions"), PoolStringArray())); + r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "permissions/custom_permissions"), PackedStringArray())); const char **perms = android_perms; while (*perms) { @@ -1341,7 +1416,7 @@ public: return "Android"; } - virtual Ref<Texture> get_logo() const { + virtual Ref<Texture2D> get_logo() const { return logo; } @@ -1396,20 +1471,22 @@ public: virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { ERR_FAIL_INDEX_V(p_device, devices.size(), ERR_INVALID_PARAMETER); + + String can_export_error; + bool can_export_missing_templates; + if (!can_export(p_preset, can_export_error, can_export_missing_templates)) { + EditorNode::add_io_error(can_export_error); + return ERR_UNCONFIGURED; + } + device_lock->lock(); EditorProgress ep("run", "Running on " + devices[p_device].name, 3); String adb = EditorSettings::get_singleton()->get("export/android/adb"); - if (adb == "") { - - EditorNode::add_io_error("ADB executable not configured in settings, can't run."); - device_lock->unlock(); - return ERR_UNCONFIGURED; - } // Export_temp APK. - if (ep.step("Exporting APK", 0)) { + if (ep.step("Exporting APK...", 0)) { device_lock->unlock(); return ERR_SKIP; } @@ -1459,7 +1536,7 @@ public: } print_line("Installing to device (please wait...): " + devices[p_device].name); - if (ep.step("Installing to device (please wait...)", 2)) { + if (ep.step("Installing to device, please wait...", 2)) { CLEANUP_AND_RETURN(ERR_SKIP); } @@ -1526,7 +1603,7 @@ public: } } - if (ep.step("Running on Device...", 3)) { + if (ep.step("Running on device...", 3)) { CLEANUP_AND_RETURN(ERR_SKIP); } args.clear(); @@ -1554,36 +1631,41 @@ public: #undef CLEANUP_AND_RETURN } - virtual Ref<Texture> get_run_icon() const { + virtual Ref<Texture2D> get_run_icon() const { return run_icon; } virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { String err; + bool valid = false; - if (!bool(p_preset->get("custom_package/use_custom_build"))) { + // Look for export templates (first official, and if defined custom templates). - r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String(); + if (!bool(p_preset->get("custom_template/use_custom_build"))) { + bool dvalid = exists_export_template("android_debug.apk", &err); + bool rvalid = exists_export_template("android_release.apk", &err); - if (p_preset->get("custom_package/debug") != "") { - if (FileAccess::exists(p_preset->get("custom_package/debug"))) { - r_missing_templates = false; - } else { + if (p_preset->get("custom_template/debug") != "") { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { err += TTR("Custom debug template not found.") + "\n"; } } - - if (p_preset->get("custom_package/release") != "") { - if (FileAccess::exists(p_preset->get("custom_package/release"))) { - r_missing_templates = false; - } else { + if (p_preset->get("custom_template/release") != "") { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { err += TTR("Custom release template not found.") + "\n"; } } + + valid = dvalid || rvalid; + } else { + valid = exists_export_template("android_source.zip", &err); } + r_missing_templates = !valid; - bool valid = !r_missing_templates; + // Validate the rest of the configuration. String adb = EditorSettings::get_singleton()->get("export/android/adb"); @@ -1612,7 +1694,7 @@ public: } } - if (bool(p_preset->get("custom_package/use_custom_build"))) { + if (bool(p_preset->get("custom_template/use_custom_build"))) { String sdk_path = EditorSettings::get_singleton()->get("export/android/custom_build_sdk_path"); if (sdk_path == "") { err += TTR("Custom build requires a valid Android SDK path in Editor Settings.") + "\n"; @@ -1785,7 +1867,7 @@ public: new_file += "//CHUNK_" + text + "_BEGIN\n"; if (!found) { - ERR_PRINTS("No end marker found in build.gradle for chunk: " + text); + ERR_PRINT("No end marker found in build.gradle for chunk: " + text); f->seek(pos); } else { @@ -1821,7 +1903,7 @@ public: new_file += "//DIR_" + text + "_BEGIN\n"; if (!found) { - ERR_PRINTS("No end marker found in build.gradle for dir: " + text); + ERR_PRINT("No end marker found in build.gradle for dir: " + text); f->seek(pos); } else { //add chunk lines @@ -1880,7 +1962,7 @@ public: new_file += "<!--CHUNK_" + text + "_BEGIN-->\n"; if (!found) { - ERR_PRINTS("No end marker found in AndroidManifest.xml for chunk: " + text); + ERR_PRINT("No end marker found in AndroidManifest.xml for chunk: " + text); f->seek(pos); } else { //add chunk lines @@ -1896,10 +1978,10 @@ public: } } else if (l.strip_edges().begins_with("<application")) { - String last_tag = "android:icon=\"@drawable/icon\""; + String last_tag = "android:icon=\"@mipmap/icon\""; int last_tag_pos = l.find(last_tag); if (last_tag_pos == -1) { - ERR_PRINTS("Not adding application attributes as the expected tag was not found in '<application': " + last_tag); + ERR_PRINT("Not adding application attributes as the expected tag was not found in '<application': " + last_tag); new_file += l + "\n"; } else { String base = l.substr(0, last_tag_pos + last_tag.length()); @@ -1933,7 +2015,7 @@ public: EditorProgress ep("export", "Exporting for Android", 105, true); - if (bool(p_preset->get("custom_package/use_custom_build"))) { //custom build + if (bool(p_preset->get("custom_template/use_custom_build"))) { //custom build //re-generate build.gradle and AndroidManifest.xml { //test that installed build version is alright @@ -1968,10 +2050,13 @@ public: build_command = build_path.plus_file(build_command); + String package_name = get_package_name(p_preset->get("package/unique_name")); + List<String> cmdline; cmdline.push_back("build"); - cmdline.push_back("-p"); - cmdline.push_back(build_path); + cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name. + cmdline.push_back("-p"); // argument to specify the start directory. + cmdline.push_back(build_path); // start directory. /*{ used for debug int ec; String pipe; @@ -1998,9 +2083,9 @@ public: } else { if (p_debug) - src_apk = p_preset->get("custom_package/debug"); + src_apk = p_preset->get("custom_template/debug"); else - src_apk = p_preset->get("custom_package/release"); + src_apk = p_preset->get("custom_template/release"); src_apk = src_apk.strip_edges(); if (src_apk == "") { @@ -2023,7 +2108,7 @@ public: FileAccess *src_f = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - if (ep.step("Creating APK", 0)) { + if (ep.step("Creating APK...", 0)) { return ERR_SKIP; } @@ -2072,6 +2157,35 @@ public: Vector<String> enabled_abis = get_enabled_abis(p_preset); + String project_icon_path = ProjectSettings::get_singleton()->get("application/config/icon"); + + // Prepare images to be resized for the icons. If some image ends up being uninitialized, the default image from the export template will be used. + Ref<Image> launcher_icon_image; + Ref<Image> launcher_adaptive_icon_foreground_image; + Ref<Image> launcher_adaptive_icon_background_image; + + launcher_icon_image.instance(); + launcher_adaptive_icon_foreground_image.instance(); + launcher_adaptive_icon_background_image.instance(); + + // Regular icon: user selection -> project icon -> default. + String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges(); + if (path.empty() || ImageLoader::load_image(path, launcher_icon_image) != OK) { + ImageLoader::load_image(project_icon_path, launcher_icon_image); + } + + // Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default). + path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges(); + if (path.empty() || ImageLoader::load_image(path, launcher_adaptive_icon_foreground_image) != OK) { + launcher_adaptive_icon_foreground_image = launcher_icon_image; + } + + // Adaptive background: user selection -> default. + path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges(); + if (!path.empty()) { + ImageLoader::load_image(path, launcher_adaptive_icon_background_image); + } + while (ret == UNZ_OK) { //get filename @@ -2094,41 +2208,22 @@ public: //write if (file == "AndroidManifest.xml") { - _fix_manifest(p_preset, data, p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG)); } if (file == "resources.arsc") { - _fix_resources(p_preset, data); } - if (file == "res/drawable-nodpi-v4/icon.png") { - bool found = false; - for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { - String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges(); - if (icon_path != "" && icon_path.ends_with(".png")) { - FileAccess *f = FileAccess::open(icon_path, FileAccess::READ); - if (f) { - data.resize(f->get_len()); - f->get_buffer(data.ptrw(), data.size()); - memdelete(f); - found = true; - break; - } - } + for (int i = 0; i < icon_densities_count; ++i) { + if (launcher_icon_image.is_valid() && !launcher_icon_image->empty()) { + _process_launcher_icons(file, launcher_icon_image, launcher_icons[i], data); } - if (!found) { - - String appicon = ProjectSettings::get_singleton()->get("application/config/icon"); - if (appicon != "" && appicon.ends_with(".png")) { - FileAccess *f = FileAccess::open(appicon, FileAccess::READ); - if (f) { - data.resize(f->get_len()); - f->get_buffer(data.ptrw(), data.size()); - memdelete(f); - } - } + if (launcher_adaptive_icon_foreground_image.is_valid() && !launcher_adaptive_icon_foreground_image->empty()) { + _process_launcher_icons(file, launcher_adaptive_icon_foreground_image, launcher_adaptive_icon_foregrounds[i], data); + } + if (launcher_adaptive_icon_background_image.is_valid() && !launcher_adaptive_icon_background_image->empty()) { + _process_launcher_icons(file, launcher_adaptive_icon_background_image, launcher_adaptive_icon_backgrounds[i], data); } } @@ -2175,7 +2270,7 @@ public: ret = unzGoToNextFile(pkg); } - if (ep.step("Adding Files...", 1)) { + if (ep.step("Adding files...", 1)) { CLEANUP_AND_RETURN(ERR_SKIP); } Error err = OK; @@ -2227,20 +2322,7 @@ public: } } - if (!err) { - APKExportData ed; - ed.ep = &ep; - ed.apk = unaligned_apk; - for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { - String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges(); - if (icon_path != "" && icon_path.ends_with(".png") && FileAccess::exists(icon_path)) { - Vector<uint8_t> data = FileAccess::get_file_as_array(icon_path); - store_in_apk(&ed, launcher_icons[i].export_path, data); - } - } - } - - int xr_mode_index = p_preset->get("graphics/xr_mode"); + int xr_mode_index = p_preset->get("xr_features/xr_mode"); if (xr_mode_index == 1 /* XRMode.OVR */) { cl.push_back("--xr_mode_ovr"); } else { diff --git a/platform/android/export/export.h b/platform/android/export/export.h index 42f3e70450..ce786cc8b6 100644 --- a/platform/android/export/export.h +++ b/platform/android/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp index f8a2c73a1e..965342b364 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index b8e78627ec..6b5ec541fd 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp index d4c2a23aa0..db3aa4255e 100644 --- a/platform/android/file_access_jandroid.cpp +++ b/platform/android/file_access_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/file_access_jandroid.h b/platform/android/file_access_jandroid.h index 9429100d65..b361c64922 100644 --- a/platform/android/file_access_jandroid.h +++ b/platform/android/file_access_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index ba01ec313b..4d2eb1ef65 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -15,7 +15,6 @@ android:largeScreens="true" android:xlargeScreens="true" /> - <!-- glEsVersion is modified by the exporter, changing this value here has no effect. --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> @@ -27,7 +26,7 @@ <!-- Any tag in this line after android:icon will be erased when doing custom builds. --> <!-- If you want to add tags manually, do before it. --> <!-- WARNING: This should stay on a single line until the parsing code is improved. See GH-32414. --> - <application android:label="@string/godot_project_name_string" android:allowBackup="false" tools:ignore="GoogleAppIndexingWarning" android:icon="@drawable/icon" > + <application android:label="@string/godot_project_name_string" android:allowBackup="false" tools:ignore="GoogleAppIndexingWarning" android:icon="@mipmap/icon" > <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. --> <!-- Do these changes in the export preset. Adding new ones is fine. --> diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 9f64c3dc8a..2e4f2ffab0 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -33,6 +33,8 @@ allprojects { } dependencies { + implementation libraries.supportCoreUtils + if (rootProject.findProject(":lib")) { implementation project(":lib") } else { @@ -51,7 +53,7 @@ android { defaultConfig { // Feel free to modify the application id to your own. - applicationId "com.godot.game" + applicationId getExportPackageName() minSdkVersion versions.minSdk targetSdkVersion versions.targetSdk //CHUNK_ANDROID_DEFAULTCONFIG_BEGIN diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 20c3123221..5550d3099d 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -4,9 +4,21 @@ ext.versions = [ minSdk : 18, targetSdk : 28, buildTools : '28.0.3', + supportCoreUtils : '28.0.0' ] ext.libraries = [ - androidGradlePlugin : "com.android.tools.build:gradle:$versions.androidGradlePlugin" + androidGradlePlugin : "com.android.tools.build:gradle:$versions.androidGradlePlugin", + supportCoreUtils : "com.android.support:support-core-utils:$versions.supportCoreUtils" ] + +ext.getExportPackageName = { -> + // Retrieve the app id from the project property set by the Godot build command. + String appId = project.hasProperty("export_package_name") ? project.property("export_package_name") : "" + // Check if the app id is valid, otherwise use the default. + if (appId == null || appId.isEmpty()) { + appId = "com.godot.game" + } + return appId +} 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 d7469a8765..eb884404cd 100644 --- a/platform/android/java/app/src/com/godot/game/GodotApp.java +++ b/platform/android/java/app/src/com/godot/game/GodotApp.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index 517fc403b2..b133585f99 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -11,7 +11,7 @@ </application> <instrumentation - android:icon="@drawable/icon" + android:icon="@mipmap/icon" android:label="@string/godot_project_name_string" android:name=".GodotInstrumentation" android:targetPackage="org.godotengine.godot" /> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 13a14422ed..eb97484b9c 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.library' dependencies { - implementation "com.android.support:support-core-utils:28.0.0" + implementation libraries.supportCoreUtils } def pathToRootDir = "../../../../" diff --git a/platform/android/java/lib/res/drawable-nodpi/icon.png b/platform/android/java/lib/res/drawable-nodpi/icon.png Binary files differdeleted file mode 100644 index 6ad9b43117..0000000000 --- a/platform/android/java/lib/res/drawable-nodpi/icon.png +++ /dev/null diff --git a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml new file mode 100644 index 0000000000..1ed4037035 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@mipmap/icon_background"/> + <foreground android:drawable="@mipmap/icon_foreground"/> +</adaptive-icon>
\ No newline at end of file diff --git a/platform/android/java/lib/res/mipmap-hdpi/icon.png b/platform/android/java/lib/res/mipmap-hdpi/icon.png Binary files differnew file mode 100644 index 0000000000..cc6e113e89 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-hdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-hdpi/icon_background.png b/platform/android/java/lib/res/mipmap-hdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..78445c0181 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-hdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-hdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-hdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..75e409ff74 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-hdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-mdpi/icon.png b/platform/android/java/lib/res/mipmap-mdpi/icon.png Binary files differnew file mode 100644 index 0000000000..e1968fe142 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-mdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-mdpi/icon_background.png b/platform/android/java/lib/res/mipmap-mdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..5813f751ed --- /dev/null +++ b/platform/android/java/lib/res/mipmap-mdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-mdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-mdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..982b69be1e --- /dev/null +++ b/platform/android/java/lib/res/mipmap-mdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-xhdpi/icon.png b/platform/android/java/lib/res/mipmap-xhdpi/icon.png Binary files differnew file mode 100644 index 0000000000..9281d8da48 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xhdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-xhdpi/icon_background.png b/platform/android/java/lib/res/mipmap-xhdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..4269c822a7 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xhdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-xhdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-xhdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..726b267ad6 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xhdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-xxhdpi/icon.png b/platform/android/java/lib/res/mipmap-xxhdpi/icon.png Binary files differnew file mode 100644 index 0000000000..7a6b67d273 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxhdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-xxhdpi/icon_background.png b/platform/android/java/lib/res/mipmap-xxhdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..5e8b518d17 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxhdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-xxhdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-xxhdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..b0c727f74c --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxhdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-xxxhdpi/icon.png b/platform/android/java/lib/res/mipmap-xxxhdpi/icon.png Binary files differnew file mode 100644 index 0000000000..0881245802 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxxhdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-xxxhdpi/icon_background.png b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..004b6fd508 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-xxxhdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..72e6f92b6e --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap/icon.png b/platform/android/java/lib/res/mipmap/icon.png Binary files differnew file mode 100644 index 0000000000..0881245802 --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon.png diff --git a/platform/android/java/lib/res/mipmap/icon_background.png b/platform/android/java/lib/res/mipmap/icon_background.png Binary files differnew file mode 100644 index 0000000000..5813f751ed --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon_background.png diff --git a/platform/android/java/lib/res/mipmap/icon_foreground.png b/platform/android/java/lib/res/mipmap/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..982b69be1e --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon_foreground.png diff --git a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java index 588d9ae646..594cae774b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ 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 4dae2dcc53..021214b627 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -96,6 +96,7 @@ import java.util.Locale; import javax.microedition.khronos.opengles.GL10; import org.godotengine.godot.input.GodotEditText; import org.godotengine.godot.payments.PaymentsManager; +import org.godotengine.godot.utils.GodotNetUtils; import org.godotengine.godot.utils.PermissionsUtil; import org.godotengine.godot.xr.XRMode; @@ -243,6 +244,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo private Sensor mGyroscope; public static GodotIO io; + public static GodotNetUtils netUtils; static SingletonBase[] singletons = new SingletonBase[MAX_SINGLETONS]; static int singleton_count = 0; @@ -285,8 +287,6 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo */ @Keep private void onVideoInit() { - boolean use_gl3 = getGLESVersionCode() >= 0x00030000; - final FrameLayout layout = new FrameLayout(this); layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); setContentView(layout); @@ -297,7 +297,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo // ...add to FrameLayout layout.addView(edittext); - mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl); + mView = new GodotView(this, xrMode, use_32_bits, use_debug_opengl); layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); edittext.setView(mView); io.setEdit(edittext); @@ -502,6 +502,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo io = new GodotIO(this); io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID); GodotLib.io = io; + netUtils = new GodotNetUtils(this); mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java index e7e2a3f808..1fb242d0bc 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java index 8e10710c9f..7e74e8a80d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ 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 04566cf62c..68ce40ba10 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -491,9 +491,9 @@ public class GodotIO { return (int)(metrics.density * 160f); } - public void showKeyboard(String p_existing_text) { + public void showKeyboard(String p_existing_text, int p_max_input_length) { if (edit != null) - edit.showKeyboard(p_existing_text); + edit.showKeyboard(p_existing_text, p_max_input_length); //InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE); //inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java index 0466f380e8..965e616ef3 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java index 67dce172dc..e0b46673ba 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -100,6 +100,16 @@ public class GodotLib { public static native void hover(int type, int x, int y); /** + * Forward double_tap events from the main thread to the GL thread. + */ + public static native void doubletap(int x, int y); + + /** + * Forward scroll events from the main thread to the GL thread. + */ + public static native void scroll(int x, int y); + + /** * Forward accelerometer sensor events from the main thread to the GL thread. * @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent) */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java index 1432cd3a67..93265d509f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java index 56ba88656e..26fa033f12 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java index 5511e5d782..8d3c2ae319 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -32,8 +32,10 @@ package org.godotengine.godot; import android.annotation.SuppressLint; import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; +import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; +import org.godotengine.godot.input.GodotGestureHandler; import org.godotengine.godot.input.GodotInputHandler; import org.godotengine.godot.utils.GLUtils; import org.godotengine.godot.xr.XRMode; @@ -68,16 +70,17 @@ public class GodotView extends GLSurfaceView { private final Godot activity; private final GodotInputHandler inputHandler; + private final GestureDetector detector; private final GodotRenderer godotRenderer; - public GodotView(Godot activity, XRMode xrMode, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl) { + public GodotView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) { super(activity); - GLUtils.use_gl3 = p_use_gl3; GLUtils.use_32 = p_use_32_bits; GLUtils.use_debug_opengl = p_use_debug_opengl; this.activity = activity; this.inputHandler = new GodotInputHandler(this); + this.detector = new GestureDetector(activity, new GodotGestureHandler(this)); this.godotRenderer = new GodotRenderer(); init(xrMode, false, 16, 0); } @@ -90,6 +93,7 @@ public class GodotView extends GLSurfaceView { @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); + this.detector.onTouchEvent(event); return activity.gotTouchEvent(event); } 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 45b739baa0..e901b4b36d 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 @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -32,6 +32,7 @@ package org.godotengine.godot.input; import android.content.Context; import android.os.Handler; import android.os.Message; +import android.text.InputFilter; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.inputmethod.EditorInfo; @@ -104,6 +105,7 @@ public class GodotEditText extends EditText { edit.append(text); edit.mInputWrapper.setOriginText(text); edit.addTextChangedListener(edit.mInputWrapper); + setMaxInputLength(edit, msg.arg1); final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(edit, 0); } @@ -120,6 +122,16 @@ public class GodotEditText extends EditText { } } + private void setMaxInputLength(EditText p_edit_text, int p_max_input_length) { + if (p_max_input_length > 0) { + InputFilter[] filters = new InputFilter[1]; + filters[0] = new InputFilter.LengthFilter(p_max_input_length); + p_edit_text.setFilters(filters); + } else { + p_edit_text.setFilters(new InputFilter[] {}); + } + } + // =========================================================== // Getter & Setter // =========================================================== @@ -149,12 +161,13 @@ public class GodotEditText extends EditText { // =========================================================== // Methods // =========================================================== - public void showKeyboard(String p_existing_text) { + public void showKeyboard(String p_existing_text, int p_max_input_length) { this.mOriginText = p_existing_text; final Message msg = new Message(); msg.what = HANDLER_OPEN_IME_KEYBOARD; msg.obj = this; + msg.arg1 = p_max_input_length; sHandler.sendMessage(msg); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java new file mode 100644 index 0000000000..1a38a9c3d2 --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -0,0 +1,106 @@ +/*************************************************************************/ +/* GodotGestureHandler.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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.godot.input; + +import android.util.Log; +import android.view.GestureDetector; +import android.view.MotionEvent; +import org.godotengine.godot.GodotLib; +import org.godotengine.godot.GodotView; + +/** + * Handles gesture input related events for the {@link GodotView} view. + * https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener + */ +public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener { + + private final GodotView godotView; + + public GodotGestureHandler(GodotView godotView) { + this.godotView = godotView; + } + + private void queueEvent(Runnable task) { + godotView.queueEvent(task); + } + + @Override + public boolean onDown(MotionEvent event) { + super.onDown(event); + //Log.i("GodotGesture", "onDown"); + return true; + } + + @Override + public boolean onSingleTapConfirmed(MotionEvent event) { + super.onSingleTapConfirmed(event); + return true; + } + + @Override + public void onLongPress(MotionEvent event) { + //Log.i("GodotGesture", "onLongPress"); + } + + @Override + public boolean onDoubleTap(MotionEvent event) { + //Log.i("GodotGesture", "onDoubleTap"); + final int x = Math.round(event.getX()); + final int y = Math.round(event.getY()); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.doubletap(x, y); + } + }); + return true; + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + //Log.i("GodotGesture", "onScroll"); + final int x = Math.round(distanceX); + final int y = Math.round(distanceY); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.scroll(x, y); + } + }); + return true; + } + + @Override + public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { + //Log.i("GodotGesture", "onFling"); + return 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 2756ca6c83..b2b88088e8 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 @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 9b372c75e3..3a154f1bf3 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java index ff95bfb0c5..0c1bdb32aa 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java index 4c1050c948..95cc48f536 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java index 1a914967a2..23d693cc8c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java index 8a2facbcfb..84a7eda6e0 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java index c079c55854..90b958266b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java index 9adc85e521..09c9349124 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java index daca6ef5ae..a101780511 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java index 17a2a197ad..dbb6b8a783 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java index 4c551d1d21..bc0e565774 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java index b61007faa3..c78e8c1c66 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java index 6c95494f8b..9d29551f89 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -44,7 +44,6 @@ public class GLUtils { public static final boolean DEBUG = false; - public static boolean use_gl3 = false; public static boolean use_32 = false; public static boolean use_debug_opengl = false; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java new file mode 100644 index 0000000000..011d426c7e --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java @@ -0,0 +1,83 @@ +/*************************************************************************/ +/* GodotNetUtils.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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.godot.utils; + +import android.content.Context; +import android.net.wifi.WifiManager; +import android.util.Log; +import org.godotengine.godot.Godot; + +/** + * This class handles Android-specific networking functions. + * For now, it only provides access to WifiManager.MulticastLock, which is needed on some devices + * to receive broadcast and multicast packets. + */ +public class GodotNetUtils { + + /* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */ + private WifiManager.MulticastLock multicastLock; + + public GodotNetUtils(Godot p_activity) { + if (PermissionsUtil.hasManifestPermission(p_activity, "android.permission.CHANGE_WIFI_MULTICAST_STATE")) { + WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + multicastLock = wifi.createMulticastLock("GodotMulticastLock"); + multicastLock.setReferenceCounted(true); + } + } + + /** + * Acquire the multicast lock. This is required on some devices to receive broadcast/multicast packets. + * This is done automatically by Godot when enabling broadcast or joining a multicast group on a socket. + */ + public void multicastLockAcquire() { + if (multicastLock == null) + return; + try { + multicastLock.acquire(); + } catch (RuntimeException e) { + Log.e("Godot", "Exception during multicast lock acquire: " + e); + } + } + + /** + * Release the multicast lock. + * This is done automatically by Godot when the lock is no longer needed by a socket. + */ + public void multicastLockRelease() { + if (multicastLock == null) + return; + try { + multicastLock.release(); + } catch (RuntimeException e) { + Log.e("Godot", "Exception during multicast lock release: " + e); + } + } +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java index 02ae753b3e..68f9a83597 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java index 2c4a444e5a..7cf32b00fe 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* PermissionsUtil.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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.godot.utils; import android.Manifest; @@ -71,7 +101,7 @@ public final class PermissionsUtil { return false; } - if (manifestPermissions == null || manifestPermissions.length == 0) + if (manifestPermissions.length == 0) return true; List<String> dangerousPermissions = new ArrayList<>(); @@ -111,8 +141,8 @@ public final class PermissionsUtil { e.printStackTrace(); return new String[0]; } - if (manifestPermissions == null || manifestPermissions.length == 0) - return new String[0]; + if (manifestPermissions.length == 0) + return manifestPermissions; List<String> dangerousPermissions = new ArrayList<>(); for (String manifestPermission : manifestPermissions) { @@ -132,6 +162,24 @@ public final class PermissionsUtil { } /** + * Check if the given permission is in the AndroidManifest.xml file. + * @param activity the caller activity for this method. + * @param permission the permession to look for in the manifest file. + * @return "true" if the permission is in the manifest file of the activity, "false" otherwise. + */ + public static boolean hasManifestPermission(Godot activity, String permission) { + try { + for (String p : getManifestPermissions(activity)) { + if (permission.equals(p)) + return true; + } + } catch (PackageManager.NameNotFoundException e) { + } + + return false; + } + + /** * Returns the permissions defined in the AndroidManifest.xml file. * @param activity the caller activity for this method. * @return manifest permissions list @@ -140,6 +188,8 @@ public final class PermissionsUtil { private static String[] getManifestPermissions(Godot activity) throws PackageManager.NameNotFoundException { PackageManager packageManager = activity.getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS); + if (packageInfo.requestedPermissions == null) + return new String[0]; return packageInfo.requestedPermissions; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java index b9fe0dd0c9..25fa10647d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java index 5896b23ac3..982e43f9d1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java index ff836a31ca..9209d6ccf2 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java index 5f6da8c672..36f4416df2 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java index f1e38c35d8..b2aa130f37 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java index 3836967f86..8409e37f8f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -45,6 +45,8 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { private int[] mValue = new int[1]; + // FIXME: Add support for Vulkan. + /* This EGL config specification is used to specify 2.0 rendering. * We use a minimum size of 4 bits for red/green/blue, but will * perform actual matching in chooseConfig() below. @@ -59,15 +61,6 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE }; - private static int[] s_configAttribs3 = { - EGL10.EGL_RED_SIZE, 4, - EGL10.EGL_GREEN_SIZE, 4, - EGL10.EGL_BLUE_SIZE, 4, - // EGL10.EGL_DEPTH_SIZE, 16, - // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //apparently there is no EGL_OPENGL_ES3_BIT - EGL10.EGL_NONE - }; public RegularConfigChooser(int r, int g, int b, int a, int depth, int stencil) { mRedSize = r; @@ -83,7 +76,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { /* Get the number of minimally matching EGL configurations */ int[] num_config = new int[1]; - egl.eglChooseConfig(display, GLUtils.use_gl3 ? s_configAttribs3 : s_configAttribs2, null, 0, num_config); + egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); int numConfigs = num_config[0]; @@ -94,7 +87,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { /* Allocate then read the array of minimally matching EGL configs */ EGLConfig[] configs = new EGLConfig[numConfigs]; - egl.eglChooseConfig(display, GLUtils.use_gl3 ? s_configAttribs3 : s_configAttribs2, configs, numConfigs, num_config); + egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); if (GLUtils.DEBUG) { GLUtils.printConfigs(egl, display, configs); diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java index 4f1e9a696b..f2b4c95a2c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -52,24 +52,17 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory { public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { String driver_name = GodotLib.getGlobal("rendering/quality/driver/driver_name"); - if (GLUtils.use_gl3 && !driver_name.equals("GLES3")) { - GLUtils.use_gl3 = false; - } - if (GLUtils.use_gl3) - Log.w(TAG, "creating OpenGL ES 3.0 context :"); - else - Log.w(TAG, "creating OpenGL ES 2.0 context :"); + // FIXME: Add support for Vulkan. + Log.w(TAG, "creating OpenGL ES 2.0 context :"); GLUtils.checkEglError(TAG, "Before eglCreateContext", egl); EGLContext context; if (GLUtils.use_debug_opengl) { int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE }; - int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE }; - context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, GLUtils.use_gl3 ? attrib_list3 : attrib_list2); + context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); } else { int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; - int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE }; - context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, GLUtils.use_gl3 ? attrib_list3 : attrib_list2); + context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); } GLUtils.checkEglError(TAG, "After eglCreateContext", egl); return context; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java index f5718ef2b3..71fcf06020 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index 2bed1f0892..9e9b17fb99 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -28,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "java_class_wrapper.h" +#include "api/java_class_wrapper.h" #include "string_android.h" #include "thread_jandroid.h" -bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error, Variant &ret) { +bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret) { Map<StringName, List<MethodInfo> >::Element *M = methods.find(p_method); if (!M) @@ -44,20 +44,20 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, for (List<MethodInfo>::Element *E = M->get().front(); E; E = E->next()) { if (!p_instance && !E->get()._static) { - r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; continue; } int pc = E->get().param_types.size(); if (pc > p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = pc; continue; } if (pc < p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = pc; continue; } @@ -97,7 +97,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, case ARG_TYPE_DOUBLE: { if (!p_args[i]->is_num()) - arg_expected = Variant::REAL; + arg_expected = Variant::FLOAT; } break; case ARG_TYPE_STRING: { @@ -141,7 +141,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, } if (arg_expected != Variant::NIL) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = i; r_error.expected = arg_expected; valid = false; @@ -158,7 +158,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, if (!method) return true; //no version convinces - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; jvalue *argv = NULL; @@ -405,7 +405,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, } } - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; bool success = true; switch (method->return_type) { @@ -501,7 +501,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, if (!_convert_object_to_variant(env, obj, ret, method->return_type)) { ret = Variant(); - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; success = false; } env->DeleteLocalRef(obj); @@ -517,7 +517,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, return success; } -Variant JavaClass::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant JavaClass::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { Variant ret; bool found = _call_method(NULL, p_method, p_args, p_argcount, r_error, ret); @@ -533,7 +533,7 @@ JavaClass::JavaClass() { ///////////////////// -Variant JavaObject::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant JavaObject::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { return Variant(); } @@ -546,11 +546,6 @@ JavaObject::~JavaObject() { //////////////////// -void JavaClassWrapper::_bind_methods() { - - ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap); -} - bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig) { jstring name2 = (jstring)env->CallObjectMethod(obj, Class_getName); diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index ade7c03d58..8d075f8e97 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -53,7 +53,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc _get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;"); _get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I"); _get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;"); - _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;)V"); + _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;I)V"); _hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V"); _set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V"); _get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;"); @@ -135,11 +135,11 @@ bool GodotIOJavaWrapper::has_vk() { return (_show_keyboard != 0) && (_hide_keyboard != 0); } -void GodotIOJavaWrapper::show_vk(const String &p_existing) { +void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length) { if (_show_keyboard) { JNIEnv *env = ThreadAndroid::get_env(); jstring jStr = env->NewStringUTF(p_existing.utf8().get_data()); - env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr); + env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length); } } diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index 100e50fd66..7dfed52187 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -73,7 +73,7 @@ public: int get_screen_dpi(); String get_unique_id(); bool has_vk(); - void show_vk(const String &p_existing); + void show_vk(const String &p_existing, int p_max_input_length); void hide_vk(); int get_vk_height(); void set_vk_height(int p_height); diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index a14e0a1960..900a452024 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -33,6 +33,7 @@ #include "java_godot_wrapper.h" #include "android/asset_manager_jni.h" +#include "api/java_class_wrapper.h" #include "audio_driver_jandroid.h" #include "core/engine.h" #include "core/os/keyboard.h" @@ -40,9 +41,9 @@ #include "dir_access_jandroid.h" #include "file_access_android.h" #include "file_access_jandroid.h" -#include "java_class_wrapper.h" #include "main/input_default.h" #include "main/main.h" +#include "net_socket_android.h" #include "os_android.h" #include "string_android.h" #include "thread_jandroid.h" @@ -98,7 +99,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.val.i = *p_arg; }; } break; - case Variant::REAL: { + case Variant::FLOAT: { if (force_jobject) { @@ -122,9 +123,9 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.val.l = jStr; v.obj = jStr; } break; - case Variant::POOL_STRING_ARRAY: { + case Variant::PACKED_STRING_ARRAY: { - PoolVector<String> sarray = *p_arg; + Vector<String> sarray = *p_arg; jobjectArray arr = env->NewObjectArray(sarray.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int j = 0; j < sarray.size(); j++) { @@ -181,35 +182,39 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.obj = jdict; } break; - case Variant::POOL_INT_ARRAY: { + case Variant::PACKED_INT32_ARRAY: { - PoolVector<int> array = *p_arg; + Vector<int> array = *p_arg; jintArray arr = env->NewIntArray(array.size()); - PoolVector<int>::Read r = array.read(); + const int *r = array.ptr(); env->SetIntArrayRegion(arr, 0, array.size(), r.ptr()); v.val.l = arr; v.obj = arr; } break; - case Variant::POOL_BYTE_ARRAY: { - PoolVector<uint8_t> array = *p_arg; + case Variant::PACKED_BYTE_ARRAY: { + Vector<uint8_t> array = *p_arg; jbyteArray arr = env->NewByteArray(array.size()); - PoolVector<uint8_t>::Read r = array.read(); + const uint8_t *r = array.ptr(); env->SetByteArrayRegion(arr, 0, array.size(), reinterpret_cast<const signed char *>(r.ptr())); v.val.l = arr; v.obj = arr; } break; - case Variant::POOL_REAL_ARRAY: { + case Variant::PACKED_FLOAT32_ARRAY: { - PoolVector<float> array = *p_arg; + Vector<float> array = *p_arg; jfloatArray arr = env->NewFloatArray(array.size()); - PoolVector<float>::Read r = array.read(); + const float *r = array.ptr(); env->SetFloatArrayRegion(arr, 0, array.size(), r.ptr()); v.val.l = arr; v.obj = arr; } break; +#ifndef _MSC_VER +#warning This is missing 64 bits arrays, I have no idea how to do it in JNI +#endif + default: { v.val.i = 0; @@ -254,7 +259,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jobjectArray arr = (jobjectArray)obj; int stringCount = env->GetArrayLength(arr); - PoolVector<String> sarr; + Vector<String> sarr; for (int i = 0; i < stringCount; i++) { jstring string = (jstring)env->GetObjectArrayElement(arr, i); @@ -284,10 +289,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jintArray arr = (jintArray)obj; int fCount = env->GetArrayLength(arr); - PoolVector<int> sarr; + Vector<int> sarr; sarr.resize(fCount); - PoolVector<int>::Write w = sarr.write(); + int *w = sarr.ptrw(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); w.release(); return sarr; @@ -297,10 +302,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jbyteArray arr = (jbyteArray)obj; int fCount = env->GetArrayLength(arr); - PoolVector<uint8_t> sarr; + Vector<uint8_t> sarr; sarr.resize(fCount); - PoolVector<uint8_t>::Write w = sarr.write(); + uint8_t *w = sarr.ptrw(); env->GetByteArrayRegion(arr, 0, fCount, reinterpret_cast<signed char *>(w.ptr())); w.release(); return sarr; @@ -318,10 +323,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jdoubleArray arr = (jdoubleArray)obj; int fCount = env->GetArrayLength(arr); - PoolRealArray sarr; + PackedFloat32Array sarr; sarr.resize(fCount); - PoolRealArray::Write w = sarr.write(); + real_t *w = sarr.ptrw(); for (int i = 0; i < fCount; i++) { @@ -336,10 +341,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jfloatArray arr = (jfloatArray)obj; int fCount = env->GetArrayLength(arr); - PoolRealArray sarr; + PackedFloat32Array sarr; sarr.resize(fCount); - PoolRealArray::Write w = sarr.write(); + real_t *w = sarr.ptrw(); for (int i = 0; i < fCount; i++) { @@ -373,7 +378,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;"); jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys); - PoolStringArray keys = _jobject_to_variant(env, arr); + PackedStringArray keys = _jobject_to_variant(env, arr); env->DeleteLocalRef(arr); jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;"); @@ -410,30 +415,30 @@ class JNISingleton : public Object { Map<StringName, MethodData> method_map; public: - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { ERR_FAIL_COND_V(!instance, Variant()); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; Map<StringName, MethodData>::Element *E = method_map.find(p_method); if (!E) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } int ac = E->get().argtypes.size(); if (ac < p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = ac; return Variant(); } if (ac > p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = ac; return Variant(); } @@ -442,7 +447,7 @@ public: if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = i; r_error.expected = E->get().argtypes[i]; } @@ -486,7 +491,7 @@ public: ret = env->CallIntMethodA(instance, E->get().method, v); } break; - case Variant::REAL: { + case Variant::FLOAT: { ret = env->CallFloatMethodA(instance, E->get().method, v); } break; @@ -496,7 +501,7 @@ public: ret = jstring_to_string((jstring)o, env); env->DeleteLocalRef(o); } break; - case Variant::POOL_STRING_ARRAY: { + case Variant::PACKED_STRING_ARRAY: { jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v); @@ -504,35 +509,38 @@ public: env->DeleteLocalRef(arr); } break; - case Variant::POOL_INT_ARRAY: { + case Variant::PACKED_INT32_ARRAY: { jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v); int fCount = env->GetArrayLength(arr); - PoolVector<int> sarr; + Vector<int> sarr; sarr.resize(fCount); - PoolVector<int>::Write w = sarr.write(); + int *w = sarr.ptrw(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; - case Variant::POOL_REAL_ARRAY: { + case Variant::PACKED_FLOAT32_ARRAY: { jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v); int fCount = env->GetArrayLength(arr); - PoolVector<float> sarr; + Vector<float> sarr; sarr.resize(fCount); - PoolVector<float>::Write w = sarr.write(); + float *w = sarr.ptrw(); env->GetFloatArrayRegion(arr, 0, fCount, w.ptr()); w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; +#ifndef _MSC_VER +#warning This is missing 64 bits arrays, I have no idea how to do it in JNI +#endif case Variant::DICTIONARY: { jobject obj = env->CallObjectMethodA(instance, E->get().method, v); @@ -635,6 +643,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en DirAccessJAndroid::setup(godot_io_java->get_instance()); AudioDriverAndroid::setup(godot_io_java->get_instance()); + NetSocketAndroid::setup(godot_java->get_member_object("netUtils", "Lorg/godotengine/godot/utils/GodotNetUtils;", env)); os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion); @@ -737,7 +746,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo } java_class_wrapper = memnew(JavaClassWrapper(godot_java->get_activity())); - Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", java_class_wrapper)); _initialize_java_modules(); } @@ -833,6 +841,20 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jo os_android->process_hover(p_type, Point2(p_x, p_y)); } +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jobject obj, jint p_x, jint p_y) { + if (step == 0) + return; + + os_android->process_double_tap(Point2(p_x, p_y)); +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jobject obj, jint p_x, jint p_y) { + if (step == 0) + return; + + os_android->process_scroll(Point2(p_x, p_y)); +} + /* * Android Key codes. */ @@ -1231,13 +1253,13 @@ static Variant::Type get_jni_type(const String &p_type) { { "void", Variant::NIL }, { "boolean", Variant::BOOL }, { "int", Variant::INT }, - { "float", Variant::REAL }, - { "double", Variant::REAL }, + { "float", Variant::FLOAT }, + { "double", Variant::FLOAT }, { "java.lang.String", Variant::STRING }, - { "[I", Variant::POOL_INT_ARRAY }, - { "[B", Variant::POOL_BYTE_ARRAY }, - { "[F", Variant::POOL_REAL_ARRAY }, - { "[Ljava.lang.String;", Variant::POOL_STRING_ARRAY }, + { "[I", Variant::PACKED_INT32_ARRAY }, + { "[B", Variant::PACKED_BYTE_ARRAY }, + { "[F", Variant::PACKED_FLOAT32_ARRAY }, + { "[Ljava.lang.String;", Variant::PACKED_STRING_ARRAY }, { "org.godotengine.godot.Dictionary", Variant::DICTIONARY }, { NULL, Variant::NIL } }; @@ -1355,7 +1377,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en env->DeleteLocalRef(obj); }; - Variant::CallError err; + Callable::CallError err; obj->call(str_method, (const Variant **)vptr, count, err); // something diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h index a564bbd4a1..71d4547f65 100644 --- a/platform/android/java_godot_lib_jni.h +++ b/platform/android/java_godot_lib_jni.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -46,6 +46,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jobject obj, jint p_type, jint p_x, jint p_y); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jobject obj, jint p_x, jint p_y); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jobject obj, jint p_x, jint p_y); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value); diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp index e3e613d30b..9ac91b8ef6 100644 --- a/platform/android/java_godot_wrapper.cpp +++ b/platform/android/java_godot_wrapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -99,13 +99,6 @@ jobject GodotJavaWrapper::get_class_loader() { } } -void GodotJavaWrapper::gfx_init(bool gl2) { - // beats me what this once did, there was no code, - // but we're getting false if our GLES3 driver is initialised - // and true for our GLES2 driver - // Maybe we're supposed to communicate this back or store it? -} - void GodotJavaWrapper::on_video_init(JNIEnv *p_env) { if (_on_video_init) if (p_env == NULL) diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h index d23ff273cb..f378b1ea38 100644 --- a/platform/android/java_godot_wrapper.h +++ b/platform/android/java_godot_wrapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -71,7 +71,6 @@ public: jobject get_class_loader(); - void gfx_init(bool gl2); void on_video_init(JNIEnv *p_env = NULL); void restart(JNIEnv *p_env = NULL); void force_quit(JNIEnv *p_env = NULL); diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp new file mode 100644 index 0000000000..320bdd3817 --- /dev/null +++ b/platform/android/net_socket_android.cpp @@ -0,0 +1,136 @@ +/*************************************************************************/ +/* net_socket_android.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +#include "net_socket_android.h" + +#include "thread_jandroid.h" + +jobject NetSocketAndroid::net_utils = 0; +jclass NetSocketAndroid::cls = 0; +jmethodID NetSocketAndroid::_multicast_lock_acquire = 0; +jmethodID NetSocketAndroid::_multicast_lock_release = 0; + +void NetSocketAndroid::setup(jobject p_net_utils) { + + JNIEnv *env = ThreadAndroid::get_env(); + + net_utils = env->NewGlobalRef(p_net_utils); + + jclass c = env->GetObjectClass(net_utils); + cls = (jclass)env->NewGlobalRef(c); + + _multicast_lock_acquire = env->GetMethodID(cls, "multicastLockAcquire", "()V"); + _multicast_lock_release = env->GetMethodID(cls, "multicastLockRelease", "()V"); +} + +void NetSocketAndroid::multicast_lock_acquire() { + if (_multicast_lock_acquire) { + JNIEnv *env = ThreadAndroid::get_env(); + env->CallVoidMethod(net_utils, _multicast_lock_acquire); + } +} + +void NetSocketAndroid::multicast_lock_release() { + if (_multicast_lock_release) { + JNIEnv *env = ThreadAndroid::get_env(); + env->CallVoidMethod(net_utils, _multicast_lock_release); + } +} + +NetSocket *NetSocketAndroid::_create_func() { + return memnew(NetSocketAndroid); +} + +void NetSocketAndroid::make_default() { + _create = _create_func; +} + +NetSocketAndroid::NetSocketAndroid() : + wants_broadcast(false), + multicast_groups(0) { +} + +NetSocketAndroid::~NetSocketAndroid() { + close(); +} + +void NetSocketAndroid::close() { + NetSocketPosix::close(); + if (wants_broadcast) + multicast_lock_release(); + if (multicast_groups) + multicast_lock_release(); + wants_broadcast = false; + multicast_groups = 0; +} + +Error NetSocketAndroid::set_broadcasting_enabled(bool p_enabled) { + Error err = NetSocketPosix::set_broadcasting_enabled(p_enabled); + if (err != OK) + return err; + + if (p_enabled != wants_broadcast) { + if (p_enabled) { + multicast_lock_acquire(); + } else { + multicast_lock_release(); + } + + wants_broadcast = p_enabled; + } + + return OK; +} + +Error NetSocketAndroid::join_multicast_group(const IP_Address &p_multi_address, String p_if_name) { + Error err = NetSocketPosix::join_multicast_group(p_multi_address, p_if_name); + if (err != OK) + return err; + + if (!multicast_groups) + multicast_lock_acquire(); + multicast_groups++; + + return OK; +} + +Error NetSocketAndroid::leave_multicast_group(const IP_Address &p_multi_address, String p_if_name) { + Error err = NetSocketPosix::leave_multicast_group(p_multi_address, p_if_name); + if (err != OK) + return err; + + ERR_FAIL_COND_V(multicast_groups == 0, ERR_BUG); + + multicast_groups--; + if (!multicast_groups) + multicast_lock_release(); + + return OK; +} diff --git a/platform/android/net_socket_android.h b/platform/android/net_socket_android.h new file mode 100644 index 0000000000..4fc80d2de1 --- /dev/null +++ b/platform/android/net_socket_android.h @@ -0,0 +1,78 @@ +/*************************************************************************/ +/* net_socket_android.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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. */ +/*************************************************************************/ + +#ifndef NET_SOCKET_ANDROID_H +#define NET_SOCKET_ANDROID_H + +#include "drivers/unix/net_socket_posix.h" + +#include <jni.h> + +/** + * Specialized NetSocket implementation for Android. + * + * Some devices requires Android-specific code to acquire a MulticastLock + * before sockets are allowed to receive broadcast and multicast packets. + * This implementation calls into Java code and automatically acquire/release + * the lock when broadcasting is enabled/disabled on a socket, or that socket + * joins/leaves a multicast group. + */ +class NetSocketAndroid : public NetSocketPosix { + +private: + static jobject net_utils; + static jclass cls; + static jmethodID _multicast_lock_acquire; + static jmethodID _multicast_lock_release; + + bool wants_broadcast; + int multicast_groups; + + static void multicast_lock_acquire(); + static void multicast_lock_release(); + +protected: + static NetSocket *_create_func(); + +public: + static void make_default(); + static void setup(jobject p_net_utils); + + virtual void close(); + + virtual Error set_broadcasting_enabled(bool p_enabled); + virtual Error join_multicast_group(const IP_Address &p_multi_address, String p_if_name); + virtual Error leave_multicast_group(const IP_Address &p_multi_address, String p_if_name); + + NetSocketAndroid(); + ~NetSocketAndroid(); +}; + +#endif diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index defee8f1f1..15e3ac48c7 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -33,7 +33,6 @@ #include "core/io/file_access_buffered_fa.h" #include "core/project_settings.h" #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" #include "drivers/unix/dir_access_unix.h" #include "drivers/unix/file_access_unix.h" #include "file_access_android.h" @@ -43,6 +42,7 @@ #include "dir_access_jandroid.h" #include "file_access_jandroid.h" +#include "net_socket_android.h" #include <dlfcn.h> @@ -66,8 +66,6 @@ int OS_Android::get_video_driver_count() const { const char *OS_Android::get_video_driver_name(int p_driver) const { switch (p_driver) { - case VIDEO_DRIVER_GLES3: - return "GLES3"; case VIDEO_DRIVER_GLES2: return "GLES2"; } @@ -106,6 +104,8 @@ void OS_Android::initialize_core() { DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_RESOURCES); DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA); DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM); + + NetSocketAndroid::make_default(); } void OS_Android::set_opengl_extensions(const char *p_gl_extensions) { @@ -120,44 +120,21 @@ int OS_Android::get_current_video_driver() const { Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { - bool use_gl3 = godot_java->get_gles_version_code() >= 0x00030000; - use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3"); bool gl_initialization_error = false; - while (true) { - if (use_gl3) { - if (RasterizerGLES3::is_viable() == OK) { - godot_java->gfx_init(false); - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) { - p_video_driver = VIDEO_DRIVER_GLES2; - use_gl3 = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - godot_java->gfx_init(true); - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } + // FIXME: Add Vulkan support. Readd fallback code from Vulkan to GLES2? + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + gl_initialization_error = true; } if (gl_initialization_error) { OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n" "Please try updating your Android version.", - "Unable to initialize Video driver"); + "Unable to initialize video driver"); return ERR_UNAVAILABLE; } @@ -175,11 +152,6 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); input->set_fallback_mapping(godot_java->get_input_fallback_mapping()); - ///@TODO implement a subclass for Android and instantiate that instead - camera_server = memnew(CameraServer); - - //power_manager = memnew(PowerAndroid); - return OK; } @@ -196,8 +168,6 @@ void OS_Android::delete_main_loop() { void OS_Android::finalize() { - memdelete(camera_server); - memdelete(input); } @@ -504,6 +474,25 @@ void OS_Android::process_hover(int p_type, Point2 p_pos) { } } +void OS_Android::process_double_tap(Point2 p_pos) { + Ref<InputEventMouseButton> ev; + ev.instance(); + ev->set_position(p_pos); + ev->set_global_position(p_pos); + ev->set_pressed(false); + ev->set_doubleclick(true); + input->parse_input_event(ev); +} + +void OS_Android::process_scroll(Point2 p_pos) { + Ref<InputEventPanGesture> ev; + ev.instance(); + ev->set_position(p_pos); + ev->set_delta(p_pos - scroll_prev_pos); + input->parse_input_event(ev); + scroll_prev_pos = p_pos; +} + void OS_Android::process_accelerometer(const Vector3 &p_accelerometer) { input->set_accelerometer(p_accelerometer); @@ -541,10 +530,10 @@ int OS_Android::get_virtual_keyboard_height() const { // return 0; } -void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) { +void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) { if (godot_io_java->has_vk()) { - godot_io_java->show_vk(p_existing_text); + godot_io_java->show_vk(p_existing_text, p_max_input_length); } else { ERR_PRINT("Virtual keyboard not available"); @@ -733,7 +722,6 @@ void OS_Android::vibrate_handheld(int p_duration_ms) { bool OS_Android::_check_internal_feature_support(const String &p_feature) { if (p_feature == "mobile") { - //TODO support etc2 only if GLES3 driver is selected return true; } #if defined(__aarch64__) diff --git a/platform/android/os_android.h b/platform/android/os_android.h index a290c0cedd..ec6ffe5438 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ @@ -37,9 +37,7 @@ #include "core/os/main_loop.h" #include "drivers/unix/os_unix.h" #include "main/input_default.h" -//#include "power_android.h" #include "servers/audio_server.h" -#include "servers/camera_server.h" #include "servers/visual/rasterizer.h" class GodotJavaWrapper; @@ -71,6 +69,7 @@ public: private: Vector<TouchPos> touch; Point2 hover_prev_pos; // needed to calculate the relative position on hover events + Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events bool use_gl2; bool use_apk_expansion; @@ -79,8 +78,6 @@ private: VisualServer *visual_server; - CameraServer *camera_server; - mutable String data_dir_cache; //AudioDriverAndroid audio_driver_android; @@ -95,8 +92,6 @@ private: GodotJavaWrapper *godot_java; GodotIOJavaWrapper *godot_io_java; - //PowerAndroid *power_manager_func; - int video_driver_index; public: @@ -160,7 +155,7 @@ public: virtual bool has_touchscreen_ui_hint() const; virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2()); + virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1); virtual void hide_virtual_keyboard(); virtual int get_virtual_keyboard_height() const; @@ -190,6 +185,8 @@ public: void process_gyroscope(const Vector3 &p_gyroscope); void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points); void process_hover(int p_type, Point2 p_pos); + void process_double_tap(Point2 p_pos); + void process_scroll(Point2 p_pos); void process_joy_event(JoypadEvent p_event); void process_event(Ref<InputEvent> p_event); void init_video_mode(int p_video_width, int p_video_height); diff --git a/platform/android/platform_config.h b/platform/android/platform_config.h index ac58be8444..c5e896c4e1 100644 --- a/platform/android/platform_config.h +++ b/platform/android/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/power_android.cpp b/platform/android/power_android.cpp deleted file mode 100644 index 4d2fbfbf1a..0000000000 --- a/platform/android/power_android.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/*************************************************************************/ -/* power_android.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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. */ -/*************************************************************************/ - -/* -Adapted from corresponding SDL 2.0 code. -*/ - -/* - Simple DirectMedia Layer - Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. -*/ - -#include "power_android.h" - -#include "core/error_macros.h" - -static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) { - if (refholder->m_env) { - JNIEnv *env = refholder->m_env; - (*env)->PopLocalFrame(env, NULL); - --s_active; - } -} - -static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) { - struct LocalReferenceHolder refholder; - refholder.m_env = NULL; - refholder.m_func = func; - return refholder; -} - -static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env) { - const int capacity = 16; - if ((*env)->PushLocalFrame(env, capacity) < 0) { - return false; - } - ++s_active; - refholder->m_env = env; - return true; -} - -static SDL_bool LocalReferenceHolder_IsActive(void) { - return s_active > 0; -} - -ANativeWindow *Android_JNI_GetNativeWindow(void) { - ANativeWindow *anw; - jobject s; - JNIEnv *env = Android_JNI_GetEnv(); - - s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface); - anw = ANativeWindow_fromSurface(env, s); - (*env)->DeleteLocalRef(env, s); - - return anw; -} - -/* - * CODE CHUNK IMPORTED FROM SDL 2.0 - * returns 0 on success or -1 on error (others undefined then) - * returns truthy or falsy value in plugged, charged and battery - * returns the value in seconds and percent or -1 if not available - */ -int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent) { - env = Android_JNI_GetEnv(); - refs = LocalReferenceHolder_Setup(__FUNCTION__); - - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); - context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); - action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); - cls = (*env)->FindClass(env, "android/content/IntentFilter"); - mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); - filter = (*env)->NewObject(env, cls, mid, action); - (*env)->DeleteLocalRef(env, action); - mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); - intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); - (*env)->DeleteLocalRef(env, filter); - cls = (*env)->GetObjectClass(env, intent); - imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); -// Watch out for C89 scoping rules because of the macro -#define GET_INT_EXTRA(var, key) \ - int var; \ - iname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ - (*env)->DeleteLocalRef(env, iname); - bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); -// Watch out for C89 scoping rules because of the macro -#define GET_BOOL_EXTRA(var, key) \ - int var; \ - bname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ - (*env)->DeleteLocalRef(env, bname); - if (plugged) { - // Watch out for C89 scoping rules because of the macro - GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5) - if (plug == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - // 1 == BatteryManager.BATTERY_PLUGGED_AC - // 2 == BatteryManager.BATTERY_PLUGGED_USB - *plugged = (0 < plug) ? 1 : 0; - } - if (charged) { - // Watch out for C89 scoping rules because of the macro - GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5) - if (status == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - // 5 == BatteryManager.BATTERY_STATUS_FULL - *charged = (status == 5) ? 1 : 0; - } - if (battery) { - GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5) - *battery = present ? 1 : 0; - } - if (seconds) { - *seconds = -1; // not possible - } - if (percent) { - int level; - int scale; - // Watch out for C89 scoping rules because of the macro - { - GET_INT_EXTRA(level_temp, "level") // == BatteryManager.EXTRA_LEVEL (API 5) - level = level_temp; - } - // Watch out for C89 scoping rules because of the macro - { - GET_INT_EXTRA(scale_temp, "scale") // == BatteryManager.EXTRA_SCALE (API 5) - scale = scale_temp; - } - if ((level == -1) || (scale == -1)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - *percent = level * 100 / scale; - } - (*env)->DeleteLocalRef(env, intent); - LocalReferenceHolder_Cleanup(&refs); - - return 0; -} - -bool PowerAndroid::GetPowerInfo_Android() { - int battery; - int plugged; - int charged; - - if (Android_JNI_GetPowerInfo(&plugged, &charged, &battery, &this->nsecs_left, &this->percent_left) != -1) { - if (plugged) { - if (charged) { - this->power_state = OS::POWERSTATE_CHARGED; - } else if (battery) { - this->power_state = OS::POWERSTATE_CHARGING; - } else { - this->power_state = OS::POWERSTATE_NO_BATTERY; - this->nsecs_left = -1; - this->percent_left = -1; - } - } else { - this->power_state = OS::POWERSTATE_ON_BATTERY; - } - } else { - this->power_state = OS::POWERSTATE_UNKNOWN; - this->nsecs_left = -1; - this->percent_left = -1; - } - - return true; -} - -OS::PowerState PowerAndroid::get_power_state() { - if (GetPowerInfo_Android()) { - return power_state; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerAndroid::get_power_seconds_left() { - if (GetPowerInfo_Android()) { - return nsecs_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} - -int PowerAndroid::get_power_percent_left() { - if (GetPowerInfo_Android()) { - return percent_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} - -PowerAndroid::PowerAndroid() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerAndroid::~PowerAndroid() { -} diff --git a/platform/android/string_android.h b/platform/android/string_android.h index fe627a3e0c..51c488c8cc 100644 --- a/platform/android/string_android.h +++ b/platform/android/string_android.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp index 9df9e57b24..98b61ad755 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h index 0b6e1f4b4a..eb4725ae68 100644 --- a/platform/android/thread_jandroid.h +++ b/platform/android/thread_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 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 */ |