summaryrefslogtreecommitdiff
path: root/platform/android
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android')
-rw-r--r--platform/android/AndroidManifest.xml.template167
-rw-r--r--platform/android/SCsub11
-rw-r--r--platform/android/audio_driver_jandroid.cpp8
-rw-r--r--platform/android/audio_driver_opensl.cpp11
-rw-r--r--platform/android/audio_driver_opensl.h3
-rw-r--r--platform/android/detect.py49
-rw-r--r--platform/android/dir_access_jandroid.cpp1
-rw-r--r--platform/android/export/export.cpp273
-rw-r--r--platform/android/godot_android.cpp2
-rw-r--r--platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.pngbin715 -> 462 bytes
-rw-r--r--platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.pngbin361 -> 127 bytes
-rw-r--r--platform/android/java/res/drawable/icon.pngbin11155 -> 7569 bytes
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java2
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java2
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java16
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java8
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java2
-rw-r--r--platform/android/java_class_wrapper.cpp5
-rw-r--r--platform/android/java_glue.cpp4
-rw-r--r--platform/android/logo.pngbin1742 -> 1461 bytes
-rw-r--r--platform/android/os_android.cpp74
-rw-r--r--platform/android/os_android.h3
-rw-r--r--platform/android/run_icon.pngbin636 -> 324 bytes
-rw-r--r--platform/android/thread_jandroid.cpp2
25 files changed, 292 insertions, 352 deletions
diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template
index 13d10b5026..81f4c15849 100644
--- a/platform/android/AndroidManifest.xml.template
+++ b/platform/android/AndroidManifest.xml.template
@@ -32,174 +32,9 @@
$$ADD_APPLICATION_CHUNKS$$
</application>
- <uses-feature android:glEsVersion="0x00030000" android:required="true" />
+ <uses-feature android:glEsVersion="0x00020000" android:required="true" />
$$ADD_PERMISSION_CHUNKS$$
-<uses-permission android:name="godot.ACCESS_CHECKIN_PROPERTIES"/>
-<uses-permission android:name="godot.ACCESS_COARSE_LOCATION"/>
-<uses-permission android:name="godot.ACCESS_FINE_LOCATION"/>
-<uses-permission android:name="godot.ACCESS_LOCATION_EXTRA_COMMANDS"/>
-<uses-permission android:name="godot.ACCESS_MOCK_LOCATION"/>
-<uses-permission android:name="godot.ACCESS_NETWORK_STATE"/>
-<uses-permission android:name="godot.ACCESS_SURFACE_FLINGER"/>
-<uses-permission android:name="godot.ACCESS_WIFI_STATE"/>
-<uses-permission android:name="godot.ACCOUNT_MANAGER"/>
-<uses-permission android:name="godot.ADD_VOICEMAIL"/>
-<uses-permission android:name="godot.AUTHENTICATE_ACCOUNTS"/>
-<uses-permission android:name="godot.BATTERY_STATS"/>
-<uses-permission android:name="godot.BIND_ACCESSIBILITY_SERVICE"/>
-<uses-permission android:name="godot.BIND_APPWIDGET"/>
-<uses-permission android:name="godot.BIND_DEVICE_ADMIN"/>
-<uses-permission android:name="godot.BIND_INPUT_METHOD"/>
-<uses-permission android:name="godot.BIND_NFC_SERVICE"/>
-<uses-permission android:name="godot.BIND_NOTIFICATION_LISTENER_SERVICE"/>
-<uses-permission android:name="godot.BIND_PRINT_SERVICE"/>
-<uses-permission android:name="godot.BIND_REMOTEVIEWS"/>
-<uses-permission android:name="godot.BIND_TEXT_SERVICE"/>
-<uses-permission android:name="godot.BIND_VPN_SERVICE"/>
-<uses-permission android:name="godot.BIND_WALLPAPER"/>
-<uses-permission android:name="godot.BLUETOOTH"/>
-<uses-permission android:name="godot.BLUETOOTH_ADMIN"/>
-<uses-permission android:name="godot.BLUETOOTH_PRIVILEGED"/>
-<uses-permission android:name="godot.BRICK"/>
-<uses-permission android:name="godot.BROADCAST_PACKAGE_REMOVED"/>
-<uses-permission android:name="godot.BROADCAST_SMS"/>
-<uses-permission android:name="godot.BROADCAST_STICKY"/>
-<uses-permission android:name="godot.BROADCAST_WAP_PUSH"/>
-<uses-permission android:name="godot.CALL_PHONE"/>
-<uses-permission android:name="godot.CALL_PRIVILEGED"/>
-<uses-permission android:name="godot.CAMERA"/>
-<uses-permission android:name="godot.CAPTURE_AUDIO_OUTPUT"/>
-<uses-permission android:name="godot.CAPTURE_SECURE_VIDEO_OUTPUT"/>
-<uses-permission android:name="godot.CAPTURE_VIDEO_OUTPUT"/>
-<uses-permission android:name="godot.CHANGE_COMPONENT_ENABLED_STATE"/>
-<uses-permission android:name="godot.CHANGE_CONFIGURATION"/>
-<uses-permission android:name="godot.CHANGE_NETWORK_STATE"/>
-<uses-permission android:name="godot.CHANGE_WIFI_MULTICAST_STATE"/>
-<uses-permission android:name="godot.CHANGE_WIFI_STATE"/>
-<uses-permission android:name="godot.CLEAR_APP_CACHE"/>
-<uses-permission android:name="godot.CLEAR_APP_USER_DATA"/>
-<uses-permission android:name="godot.CONTROL_LOCATION_UPDATES"/>
-<uses-permission android:name="godot.DELETE_CACHE_FILES"/>
-<uses-permission android:name="godot.DELETE_PACKAGES"/>
-<uses-permission android:name="godot.DEVICE_POWER"/>
-<uses-permission android:name="godot.DIAGNOSTIC"/>
-<uses-permission android:name="godot.DISABLE_KEYGUARD"/>
-<uses-permission android:name="godot.DUMP"/>
-<uses-permission android:name="godot.EXPAND_STATUS_BAR"/>
-<uses-permission android:name="godot.FACTORY_TEST"/>
-<uses-permission android:name="godot.FLASHLIGHT"/>
-<uses-permission android:name="godot.FORCE_BACK"/>
-<uses-permission android:name="godot.GET_ACCOUNTS"/>
-<uses-permission android:name="godot.GET_PACKAGE_SIZE"/>
-<uses-permission android:name="godot.GET_TASKS"/>
-<uses-permission android:name="godot.GET_TOP_ACTIVITY_INFO"/>
-<uses-permission android:name="godot.GLOBAL_SEARCH"/>
-<uses-permission android:name="godot.HARDWARE_TEST"/>
-<uses-permission android:name="godot.INJECT_EVENTS"/>
-<uses-permission android:name="godot.INSTALL_LOCATION_PROVIDER"/>
-<uses-permission android:name="godot.INSTALL_PACKAGES"/>
-<uses-permission android:name="godot.INSTALL_SHORTCUT"/>
-<uses-permission android:name="godot.INTERNAL_SYSTEM_WINDOW"/>
-<uses-permission android:name="godot.INTERNET"/>
-<uses-permission android:name="godot.KILL_BACKGROUND_PROCESSES"/>
-<uses-permission android:name="godot.LOCATION_HARDWARE"/>
-<uses-permission android:name="godot.MANAGE_ACCOUNTS"/>
-<uses-permission android:name="godot.MANAGE_APP_TOKENS"/>
-<uses-permission android:name="godot.MANAGE_DOCUMENTS"/>
-<uses-permission android:name="godot.MASTER_CLEAR"/>
-<uses-permission android:name="godot.MEDIA_CONTENT_CONTROL"/>
-<uses-permission android:name="godot.MODIFY_AUDIO_SETTINGS"/>
-<uses-permission android:name="godot.MODIFY_PHONE_STATE"/>
-<uses-permission android:name="godot.MOUNT_FORMAT_FILESYSTEMS"/>
-<uses-permission android:name="godot.MOUNT_UNMOUNT_FILESYSTEMS"/>
-<uses-permission android:name="godot.NFC"/>
-<uses-permission android:name="godot.PERSISTENT_ACTIVITY"/>
-<uses-permission android:name="godot.PROCESS_OUTGOING_CALLS"/>
-<uses-permission android:name="godot.READ_CALENDAR"/>
-<uses-permission android:name="godot.READ_CALL_LOG"/>
-<uses-permission android:name="godot.READ_CONTACTS"/>
-<uses-permission android:name="godot.READ_EXTERNAL_STORAGE"/>
-<uses-permission android:name="godot.READ_FRAME_BUFFER"/>
-<uses-permission android:name="godot.READ_HISTORY_BOOKMARKS"/>
-<uses-permission android:name="godot.READ_INPUT_STATE"/>
-<uses-permission android:name="godot.READ_LOGS"/>
-<uses-permission android:name="godot.READ_PHONE_STATE"/>
-<uses-permission android:name="godot.READ_PROFILE"/>
-<uses-permission android:name="godot.READ_SMS"/>
-<uses-permission android:name="godot.READ_SOCIAL_STREAM"/>
-<uses-permission android:name="godot.READ_SYNC_SETTINGS"/>
-<uses-permission android:name="godot.READ_SYNC_STATS"/>
-<uses-permission android:name="godot.READ_USER_DICTIONARY"/>
-<uses-permission android:name="godot.REBOOT"/>
-<uses-permission android:name="godot.RECEIVE_BOOT_COMPLETED"/>
-<uses-permission android:name="godot.RECEIVE_MMS"/>
-<uses-permission android:name="godot.RECEIVE_SMS"/>
-<uses-permission android:name="godot.RECEIVE_WAP_PUSH"/>
-<uses-permission android:name="godot.RECORD_AUDIO"/>
-<uses-permission android:name="godot.REORDER_TASKS"/>
-<uses-permission android:name="godot.RESTART_PACKAGES"/>
-<uses-permission android:name="godot.SEND_RESPOND_VIA_MESSAGE"/>
-<uses-permission android:name="godot.SEND_SMS"/>
-<uses-permission android:name="godot.SET_ACTIVITY_WATCHER"/>
-<uses-permission android:name="godot.SET_ALARM"/>
-<uses-permission android:name="godot.SET_ALWAYS_FINISH"/>
-<uses-permission android:name="godot.SET_ANIMATION_SCALE"/>
-<uses-permission android:name="godot.SET_DEBUG_APP"/>
-<uses-permission android:name="godot.SET_ORIENTATION"/>
-<uses-permission android:name="godot.SET_POINTER_SPEED"/>
-<uses-permission android:name="godot.SET_PREFERRED_APPLICATIONS"/>
-<uses-permission android:name="godot.SET_PROCESS_LIMIT"/>
-<uses-permission android:name="godot.SET_TIME"/>
-<uses-permission android:name="godot.SET_TIME_ZONE"/>
-<uses-permission android:name="godot.SET_WALLPAPER"/>
-<uses-permission android:name="godot.SET_WALLPAPER_HINTS"/>
-<uses-permission android:name="godot.SIGNAL_PERSISTENT_PROCESSES"/>
-<uses-permission android:name="godot.STATUS_BAR"/>
-<uses-permission android:name="godot.SUBSCRIBED_FEEDS_READ"/>
-<uses-permission android:name="godot.SUBSCRIBED_FEEDS_WRITE"/>
-<uses-permission android:name="godot.SYSTEM_ALERT_WINDOW"/>
-<uses-permission android:name="godot.TRANSMIT_IR"/>
-<uses-permission android:name="godot.UNINSTALL_SHORTCUT"/>
-<uses-permission android:name="godot.UPDATE_DEVICE_STATS"/>
-<uses-permission android:name="godot.USE_CREDENTIALS"/>
-<uses-permission android:name="godot.USE_SIP"/>
-<uses-permission android:name="godot.VIBRATE"/>
-<uses-permission android:name="godot.WAKE_LOCK"/>
-<uses-permission android:name="godot.WRITE_APN_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_CALENDAR"/>
-<uses-permission android:name="godot.WRITE_CALL_LOG"/>
-<uses-permission android:name="godot.WRITE_CONTACTS"/>
-<uses-permission android:name="godot.WRITE_EXTERNAL_STORAGE"/>
-<uses-permission android:name="godot.WRITE_GSERVICES"/>
-<uses-permission android:name="godot.WRITE_HISTORY_BOOKMARKS"/>
-<uses-permission android:name="godot.WRITE_PROFILE"/>
-<uses-permission android:name="godot.WRITE_SECURE_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_SMS"/>
-<uses-permission android:name="godot.WRITE_SOCIAL_STREAM"/>
-<uses-permission android:name="godot.WRITE_SYNC_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_USER_DICTIONARY"/>
-<uses-permission android:name="godot.custom.0"/>
-<uses-permission android:name="godot.custom.1"/>
-<uses-permission android:name="godot.custom.2"/>
-<uses-permission android:name="godot.custom.3"/>
-<uses-permission android:name="godot.custom.4"/>
-<uses-permission android:name="godot.custom.5"/>
-<uses-permission android:name="godot.custom.6"/>
-<uses-permission android:name="godot.custom.7"/>
-<uses-permission android:name="godot.custom.8"/>
-<uses-permission android:name="godot.custom.9"/>
-<uses-permission android:name="godot.custom.10"/>
-<uses-permission android:name="godot.custom.11"/>
-<uses-permission android:name="godot.custom.12"/>
-<uses-permission android:name="godot.custom.13"/>
-<uses-permission android:name="godot.custom.14"/>
-<uses-permission android:name="godot.custom.15"/>
-<uses-permission android:name="godot.custom.16"/>
-<uses-permission android:name="godot.custom.17"/>
-<uses-permission android:name="godot.custom.18"/>
-<uses-permission android:name="godot.custom.19"/>
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="27"/>
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 8c08289932..31fee5722c 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -2,6 +2,8 @@
import shutil
from compat import open_utf8
+from distutils.version import LooseVersion
+from detect import get_ndk_version
Import('env')
@@ -53,7 +55,7 @@ if len(env.android_flat_dirs) > 0:
gradle_maven_flat_text = gradle_maven_flat_text[:-1]
gradle_maven_flat_text += "\n\t}\n"
-
+
gradle_maven_repos_text = ""
gradle_maven_repos_text += gradle_maven_flat_text
@@ -99,6 +101,9 @@ for x in env.android_jni_dirs:
gradle_asset_dirs_text = ""
+for x in env.android_asset_dirs:
+ gradle_asset_dirs_text += ",'" + x.replace("\\", "/") + "'"
+
gradle_default_config_text = ""
minSdk = 18
@@ -166,3 +171,7 @@ if lib_arch_dir != '':
out_dir = '#platform/android/java/libs/' + lib_type_dir + '/' + lib_arch_dir
env_android.Command(out_dir + '/libgodot_android.so', '#bin/libgodot' + env['SHLIBSUFFIX'], Move("$TARGET", "$SOURCE"))
+ ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
+ if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
+ stl_lib_path = str(env['ANDROID_NDK_ROOT']) + '/sources/cxx-stl/llvm-libc++/libs/' + lib_arch_dir + '/libc++_shared.so'
+ env_android.Command(out_dir + '/libc++_shared.so', stl_lib_path, Copy("$TARGET", "$SOURCE")) \ No newline at end of file
diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp
index 3d80e76707..46bd691290 100644
--- a/platform/android/audio_driver_jandroid.cpp
+++ b/platform/android/audio_driver_jandroid.cpp
@@ -78,13 +78,11 @@ Error AudioDriverAndroid::init() {
// __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
JNIEnv *env = ThreadAndroid::get_env();
- int mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
+ int mix_rate = GLOBAL_DEF_RST("audio/mix_rate", 44100);
- int latency = GLOBAL_DEF("audio/output_latency", 25);
+ int latency = GLOBAL_DEF_RST("audio/output_latency", 25);
unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000);
- if (OS::get_singleton()->is_stdout_verbose()) {
- print_line("audio buffer size: " + itos(buffer_size));
- }
+ print_verbose("Audio buffer size: " + itos(buffer_size));
audioBuffer = env->CallObjectMethod(io, _init_audio, mix_rate, buffer_size);
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index e6bd3ff253..28e3ea962f 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -42,7 +42,8 @@ void AudioDriverOpenSL::_buffer_callback(
/* SLuint32 eventFlags,
const void * pBuffer,
SLuint32 bufferSize,
- SLuint32 dataUsed*/) {
+ SLuint32 dataUsed*/
+) {
bool mix = true;
@@ -145,9 +146,6 @@ void AudioDriverOpenSL::start() {
res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void *)&EngineItf);
ERR_FAIL_COND(res != SL_RESULT_SUCCESS);
- /* Initialize arrays required[] and iidArray[] */
- SLboolean required[MAX_NUMBER_INTERFACES];
- SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
{
const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB };
@@ -187,10 +185,7 @@ void AudioDriverOpenSL::start() {
//cntxt.pDataBase = (void*)&pcmData;
//cntxt.pData = cntxt.pDataBase;
//cntxt.size = sizeof(pcmData);
- /* Set arrays required[] and iidArray[] for SEEK interface
- (PlayItf is implicit) */
- required[0] = SL_BOOLEAN_TRUE;
- iidArray[0] = SL_IID_BUFFERQUEUE;
+
/* Create the music player */
{
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index 2022bad02a..88cb122414 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -74,7 +74,8 @@ class AudioDriverOpenSL : public AudioDriver {
/* SLuint32 eventFlags,
const void * pBuffer,
SLuint32 bufferSize,
- SLuint32 dataUsed*/);
+ SLuint32 dataUsed*/
+ );
static void _buffer_callbacks(
SLAndroidSimpleBufferQueueItf queueItf,
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 971368db17..953a2fa6d2 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -128,7 +128,7 @@ def configure(env):
env.extra_suffix = ".armv7" + env.extra_suffix
elif env["android_arch"] == "arm64v8":
if get_platform(env["ndk_platform"]) < 21:
- print("WARNING: android_arch=arm64v8 is not supported by ndk_platform lower than andorid-21; setting ndk_platform=android-21")
+ print("WARNING: android_arch=arm64v8 is not supported by ndk_platform lower than android-21; setting ndk_platform=android-21")
env["ndk_platform"] = "android-21"
env['ARCH'] = 'arch-arm64'
target_subpath = "aarch64-linux-android-4.9"
@@ -139,8 +139,13 @@ def configure(env):
## Build type
if (env["target"].startswith("release")):
- env.Append(LINKFLAGS=['-O2'])
- env.Append(CPPFLAGS=['-O2', '-DNDEBUG', '-ffast-math', '-funsafe-math-optimizations', '-fomit-frame-pointer'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Append(LINKFLAGS=['-O2'])
+ env.Append(CPPFLAGS=['-O2', '-DNDEBUG', '-ffast-math', '-funsafe-math-optimizations', '-fomit-frame-pointer'])
+ else: #optimize for size
+ env.Append(CPPFLAGS=['-Os', '-DNDEBUG'])
+ env.Append(LINKFLAGS=['-Os'])
+
if (can_vectorize):
env.Append(CPPFLAGS=['-ftree-vectorize'])
if (env["target"] == "release_debug"):
@@ -199,18 +204,26 @@ def configure(env):
## Compile flags
+ if env['android_stl']:
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/include"])
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++abi/include"])
+ env.Append(CXXFLAGS=['-frtti',"-std=gnu++14"])
+ else:
+ env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions', '-DNO_SAFE_CAST'])
+
ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"])
if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
print("Using NDK unified headers")
sysroot = env["ANDROID_NDK_ROOT"] + "/sysroot"
- env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include"])
+ env.Append(CPPFLAGS=["--sysroot="+sysroot])
env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath])
+ env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/android/support/include"])
# For unified headers this define has to be set manually
env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(get_platform(env['ndk_platform']))])
else:
print("Using NDK deprecated headers")
env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"])
-
+
env.Append(CPPFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split())
env.Append(CPPFLAGS='-DNO_STATVFS -DGLES_ENABLED'.split())
@@ -241,23 +254,25 @@ def configure(env):
env.Append(CPPFLAGS=target_opts)
env.Append(CPPFLAGS=common_opts)
- if env['android_stl']:
- env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/gnu-libstdc++/4.9/include"])
- env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + arch_subpath + "/include"])
- env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + arch_subpath])
- env.Append(LIBS=["gnustl_static"])
- else:
- env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions', '-DNO_SAFE_CAST'])
-
## Link flags
-
- env['LINKFLAGS'] = ['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel']
+ if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"):
+ if LooseVersion(ndk_version) >= LooseVersion("17.1.4828580"):
+ env.Append(LINKFLAGS=['-Wl,--exclude-libs,libgcc.a','-Wl,--exclude-libs,libatomic.a','-nostdlib++'])
+ else:
+ env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/"+arch_subpath+"/libandroid_support.a"])
+ env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/llvm-libc++/libs/"+arch_subpath+"/"])
+ env.Append(LINKFLAGS=[env["ANDROID_NDK_ROOT"] +"/sources/cxx-stl/llvm-libc++/libs/"+arch_subpath+"/libc++_shared.so"])
+ else:
+ env.Append(LINKFLAGS=['-shared', '--sysroot=' + lib_sysroot, '-Wl,--warn-shared-textrel'])
+ if mt_link:
+ env.Append(LINKFLAGS=['-Wl,--threads'])
+
if env["android_arch"] == "armv7":
env.Append(LINKFLAGS='-Wl,--fix-cortex-a8'.split())
env.Append(LINKFLAGS='-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now'.split())
env.Append(LINKFLAGS='-Wl,-soname,libgodot_android.so -Wl,--gc-sections'.split())
- if mt_link:
- env.Append(LINKFLAGS=['-Wl,--threads'])
+
env.Append(LINKFLAGS=target_opts)
env.Append(LINKFLAGS=common_opts)
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index 3e40b59de9..ee5ae156b7 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -153,7 +153,6 @@ String DirAccessJAndroid::get_current_dir() {
bool DirAccessJAndroid::file_exists(String p_file) {
- JNIEnv *env = ThreadAndroid::get_env();
String sd;
if (current_dir == "")
sd = p_file;
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 9e6377f4fe..5c8d9e078f 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -228,7 +228,7 @@ class EditorExportAndroid : public EditorExportPlatform {
};
Vector<Device> devices;
- bool devices_changed;
+ volatile bool devices_changed;
Mutex *device_lock;
Thread *device_thread;
volatile bool quit_request;
@@ -257,7 +257,6 @@ class EditorExportAndroid : public EditorExportPlatform {
if (dpos == -1)
continue;
d = d.substr(0, dpos).strip_edges();
- //print_line("found device: "+d);
ldevices.push_back(d);
}
@@ -345,8 +344,6 @@ class EditorExportAndroid : public EditorExportPlatform {
}
d.name = vendor + " " + device;
- //print_line("name: "+d.name);
- //print_line("description: "+d.description);
}
ndevices.push_back(d);
@@ -528,11 +525,9 @@ class EditorExportAndroid : public EditorExportPlatform {
bool exported = false;
for (int i = 0; i < p_so.tags.size(); ++i) {
// shared objects can be fat (compatible with multiple ABIs)
- int start_pos = 0;
int abi_index = abis.find(p_so.tags[i]);
if (abi_index != -1) {
exported = true;
- start_pos = abi_index + 1;
String abi = abis[abi_index];
String dst_path = "lib/" + abi + "/" + p_so.path.get_file();
Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path);
@@ -570,7 +565,7 @@ class EditorExportAndroid : public EditorExportPlatform {
// const int CHUNK_RESOURCEIDS = 0x00080180;
const int CHUNK_STRINGS = 0x001C0001;
// const int CHUNK_XML_END_NAMESPACE = 0x00100101;
- // const int CHUNK_XML_END_TAG = 0x00100103;
+ const int CHUNK_XML_END_TAG = 0x00100103;
// const int CHUNK_XML_START_NAMESPACE = 0x00100100;
const int CHUNK_XML_START_TAG = 0x00100102;
// const int CHUNK_XML_TEXT = 0x00100104;
@@ -601,24 +596,28 @@ class EditorExportAndroid : public EditorExportPlatform {
bool screen_support_large = p_preset->get("screen/support_large");
bool screen_support_xlarge = p_preset->get("screen/support_xlarge");
- String user_perms[MAX_USER_PERMISSIONS];
-
- for (int i = 0; i < MAX_USER_PERMISSIONS; i++) {
-
- user_perms[i] = p_preset->get("user_permissions/" + itos(i));
- }
-
- Set<String> perms;
+ Vector<String> perms;
const char **aperms = android_perms;
while (*aperms) {
bool enabled = p_preset->get("permissions/" + String(*aperms).to_lower());
if (enabled)
- perms.insert(String(*aperms));
+ perms.push_back("android.permission." + String(*aperms));
aperms++;
}
+ for (int i = 0; i < MAX_USER_PERMISSIONS; i++) {
+ String user_perm = p_preset->get("user_permissions/" + itos(i));
+ if (user_perm.strip_edges() != "" && user_perm.strip_edges() != "False")
+ perms.push_back(user_perm.strip_edges());
+ }
+
+ if (p_give_internet) {
+ if (perms.find("android.permission.INTERNET") == -1)
+ perms.push_back("android.permission.INTERNET");
+ }
+
while (ofs < (uint32_t)p_manifest.size()) {
uint32_t chunk = decode_uint32(&p_manifest[ofs]);
@@ -663,25 +662,20 @@ class EditorExportAndroid : public EditorExportPlatform {
ucstring.resize(len + 1);
for (uint32_t j = 0; j < len; j++) {
uint16_t c = decode_uint16(&p_manifest[string_at + 2 + 2 * j]);
- ucstring[j] = c;
+ ucstring.write[j] = c;
}
string_end = MAX(string_at + 2 + 2 * len, string_end);
- ucstring[len] = 0;
- string_table[i] = ucstring.ptr();
+ ucstring.write[len] = 0;
+ string_table.write[i] = ucstring.ptr();
}
-
- //print_line("String "+itos(i)+": "+string_table[i]);
}
for (uint32_t i = string_end; i < (ofs + size); i++) {
stable_extra.push_back(p_manifest[i]);
}
- //printf("stable extra: %i\n",int(stable_extra.size()));
string_table_ends = ofs + size;
- //print_line("STABLE SIZE: "+itos(size)+" ACTUAL: "+itos(string_table_ends));
-
} break;
case CHUNK_XML_START_TAG: {
@@ -712,79 +706,132 @@ class EditorExportAndroid : public EditorExportPlatform {
//replace project information
if (tname == "manifest" && attrname == "package") {
-
- print_line("FOUND package");
- string_table[attr_value] = get_package_name(package_name);
+ string_table.write[attr_value] = get_package_name(package_name);
}
- if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionCode") {
-
- print_line("FOUND versionCode");
- encode_uint32(version_code, &p_manifest[iofs + 16]);
+ if (tname == "manifest" && attrname == "versionCode") {
+ encode_uint32(version_code, &p_manifest.write[iofs + 16]);
}
- if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionName") {
-
- print_line("FOUND versionName");
+ if (tname == "manifest" && attrname == "versionName") {
if (attr_value == 0xFFFFFFFF) {
WARN_PRINT("Version name in a resource, should be plaintext")
} else
- string_table[attr_value] = version_name;
+ string_table.write[attr_value] = version_name;
}
- if (tname == "activity" && /*nspace=="android" &&*/ attrname == "screenOrientation") {
+ if (tname == "activity" && attrname == "screenOrientation") {
- encode_uint32(orientation == 0 ? 0 : 1, &p_manifest[iofs + 16]);
+ encode_uint32(orientation == 0 ? 0 : 1, &p_manifest.write[iofs + 16]);
}
- if (tname == "uses-feature" && /*nspace=="android" &&*/ attrname == "glEsVersion") {
- print_line("version number: " + itos(decode_uint32(&p_manifest[iofs + 16])));
- }
+ if (tname == "supports-screens") {
- if (tname == "uses-permission" && /*nspace=="android" &&*/ attrname == "name") {
+ if (attrname == "smallScreens") {
- if (value.begins_with("godot.custom")) {
+ encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
- int which = value.get_slice(".", 2).to_int();
- if (which >= 0 && which < MAX_USER_PERMISSIONS && user_perms[which].strip_edges() != "") {
+ } else if (attrname == "normalScreens") {
- string_table[attr_value] = user_perms[which].strip_edges();
- }
+ encode_uint32(screen_support_normal ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
- } else if (value.begins_with("godot.")) {
- String perm = value.get_slice(".", 1);
+ } else if (attrname == "largeScreens") {
- if (perms.has(perm) || (p_give_internet && perm == "INTERNET")) {
+ encode_uint32(screen_support_large ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
- print_line("PERM: " + perm);
- string_table[attr_value] = "android.permission." + perm;
- }
+ } else if (attrname == "xlargeScreens") {
+
+ encode_uint32(screen_support_xlarge ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
}
}
- if (tname == "supports-screens") {
+ iofs += 20;
+ }
- if (attrname == "smallScreens") {
+ } break;
+ case CHUNK_XML_END_TAG: {
+ int iofs = ofs + 8;
+ uint32_t name = decode_uint32(&p_manifest[iofs + 12]);
+ String tname = string_table[name];
- encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ if (tname == "manifest") {
- } else if (attrname == "normalScreens") {
+ // save manifest ending so we can restore it
+ Vector<uint8_t> manifest_end;
+ uint32_t manifest_cur_size = p_manifest.size();
+ uint32_t node_size = size;
- encode_uint32(screen_support_normal ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ manifest_end.resize(p_manifest.size() - ofs);
+ memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
- } else if (attrname == "largeScreens") {
+ int32_t attr_name_string = string_table.find("name");
+ ERR_EXPLAIN("Template does not have 'name' attribute");
+ ERR_FAIL_COND(attr_name_string == -1);
- encode_uint32(screen_support_large ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ int32_t ns_android_string = string_table.find("android");
+ ERR_EXPLAIN("Template does not have 'android' namespace");
+ ERR_FAIL_COND(ns_android_string == -1);
- } else if (attrname == "xlargeScreens") {
+ int32_t attr_uses_permission_string = string_table.find("uses-permission");
+ if (attr_uses_permission_string == -1) {
+ string_table.push_back("uses-permission");
+ attr_uses_permission_string = string_table.size() - 1;
+ }
- encode_uint32(screen_support_xlarge ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]);
+ for (int i = 0; i < perms.size(); ++i) {
+ print_line("Adding permission " + perms[i]);
+
+ manifest_cur_size += 56 + 24; // node + end node
+ p_manifest.resize(manifest_cur_size);
+
+ // Add permission to the string pool
+ int32_t perm_string = string_table.find(perms[i]);
+ if (perm_string == -1) {
+ string_table.push_back(perms[i]);
+ perm_string = 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(56, &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(1, &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
+
+ // 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(perm_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(perm_string, &p_manifest.write[ofs + 52]); // typedvalue reference
+
+ ofs += 56;
+
+ // 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
+
+ ofs += 24;
}
- iofs += 20;
+ // copy footer back in
+ memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size());
}
-
} break;
}
@@ -798,25 +845,25 @@ class EditorExportAndroid : public EditorExportPlatform {
for (uint32_t i = 0; i < string_table_begins; i++) {
- ret[i] = p_manifest[i];
+ ret.write[i] = p_manifest[i];
}
ofs = 0;
for (int i = 0; i < string_table.size(); i++) {
- encode_uint32(ofs, &ret[string_table_begins + i * 4]);
+ encode_uint32(ofs, &ret.write[string_table_begins + i * 4]);
ofs += string_table[i].length() * 2 + 2 + 2;
- //print_line("ofs: "+itos(i)+": "+itos(ofs));
}
+
ret.resize(ret.size() + ofs);
- uint8_t *chars = &ret[ret.size() - ofs];
+ string_data_offset = ret.size() - ofs;
+ uint8_t *chars = &ret.write[string_data_offset];
for (int i = 0; i < string_table.size(); i++) {
String s = string_table[i];
- //print_line("savint string :"+s);
encode_uint16(s.length(), chars);
chars += 2;
- for (int j = 0; j < s.length(); j++) { //include zero?
+ for (int j = 0; j < s.length(); j++) {
encode_uint16(s[j], chars);
chars += 2;
}
@@ -828,6 +875,7 @@ class EditorExportAndroid : public EditorExportPlatform {
ret.push_back(stable_extra[i]);
}
+ //pad
while (ret.size() % 4)
ret.push_back(0);
@@ -836,15 +884,15 @@ class EditorExportAndroid : public EditorExportPlatform {
uint32_t extra = (p_manifest.size() - string_table_ends);
ret.resize(new_stable_end + extra);
for (uint32_t i = 0; i < extra; i++)
- ret[new_stable_end + i] = p_manifest[string_table_ends + i];
+ ret.write[new_stable_end + i] = p_manifest[string_table_ends + i];
while (ret.size() % 4)
ret.push_back(0);
- encode_uint32(ret.size(), &ret[4]); //update new file size
+ encode_uint32(ret.size(), &ret.write[4]); //update new file size
- encode_uint32(new_stable_end - 8, &ret[12]); //update new string table size
-
- //print_line("file size: "+itos(ret.size()));
+ encode_uint32(new_stable_end - 8, &ret.write[12]); //update new string table size
+ encode_uint32(string_table.size(), &ret.write[16]); //update new number of strings
+ encode_uint32(string_data_offset - 8, &ret.write[28]); //update new string data offset
p_manifest = ret;
}
@@ -866,9 +914,9 @@ class EditorExportAndroid : public EditorExportPlatform {
Vector<uint8_t> str8;
str8.resize(len + 1);
for (uint32_t i = 0; i < len; i++) {
- str8[i] = p_bytes[offset + i];
+ str8.write[i] = p_bytes[offset + i];
}
- str8[len] = 0;
+ str8.write[len] = 0;
String str;
str.parse_utf8((const char *)str8.ptr());
return str;
@@ -887,7 +935,6 @@ class EditorExportAndroid : public EditorExportPlatform {
void _fix_resources(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest) {
const int UTF8_FLAG = 0x00000100;
- print_line("*******************GORRRGLE***********************");
uint32_t string_block_len = decode_uint32(&p_manifest[16]);
uint32_t string_count = decode_uint32(&p_manifest[20]);
@@ -932,18 +979,18 @@ class EditorExportAndroid : public EditorExportPlatform {
for (uint32_t i = 0; i < string_table_begins; i++) {
- ret[i] = p_manifest[i];
+ ret.write[i] = p_manifest[i];
}
int ofs = 0;
for (int i = 0; i < string_table.size(); i++) {
- encode_uint32(ofs, &ret[string_table_begins + i * 4]);
+ encode_uint32(ofs, &ret.write[string_table_begins + i * 4]);
ofs += string_table[i].length() * 2 + 2 + 2;
}
ret.resize(ret.size() + ofs);
- uint8_t *chars = &ret[ret.size() - ofs];
+ uint8_t *chars = &ret.write[ret.size() - ofs];
for (int i = 0; i < string_table.size(); i++) {
String s = string_table[i];
@@ -962,19 +1009,19 @@ class EditorExportAndroid : public EditorExportPlatform {
ret.push_back(0);
//change flags to not use utf8
- encode_uint32(string_flags & ~0x100, &ret[28]);
+ encode_uint32(string_flags & ~0x100, &ret.write[28]);
//change length
- encode_uint32(ret.size() - 12, &ret[16]);
+ encode_uint32(ret.size() - 12, &ret.write[16]);
//append the rest...
int rest_from = 12 + string_block_len;
int rest_to = ret.size();
int rest_len = (p_manifest.size() - rest_from);
ret.resize(ret.size() + (p_manifest.size() - rest_from));
for (int i = 0; i < rest_len; i++) {
- ret[rest_to + i] = p_manifest[rest_from + i];
+ ret.write[rest_to + i] = p_manifest[rest_from + i];
}
//finally update the size
- encode_uint32(ret.size(), &ret[4]);
+ encode_uint32(ret.size(), &ret.write[4]);
p_manifest = ret;
//printf("end\n");
@@ -1017,16 +1064,15 @@ public:
virtual void get_export_options(List<ExportOption> *r_options) {
- /*r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/api", PROPERTY_HINT_ENUM, "OpenGL ES 2.0,OpenGL ES 3.0"), 1));*/
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true));
- 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::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::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"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name"), "org.godotengine.$genname"));
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "com.example.$genname"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "screen/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait"), 0));
@@ -1036,10 +1082,10 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
for (int 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_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), ""));
}
- r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "keystore"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false));
@@ -1064,8 +1110,6 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "user_permissions/" + itos(i)), false));
}
-
- //r_options->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
}
virtual String get_name() const {
@@ -1083,7 +1127,10 @@ public:
virtual bool poll_devices() {
bool dc = devices_changed;
- devices_changed = false;
+ if (dc) {
+ // don't clear unless we're reporting true, to avoid race
+ devices_changed = false;
+ }
return dc;
}
@@ -1165,8 +1212,8 @@ public:
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
}
- print_line("Installing into device (please wait..): " + devices[p_device].name);
- ep.step("Installing to Device (please wait..)..", 2);
+ print_line("Installing to device (please wait...): " + devices[p_device].name);
+ ep.step("Installing to device (please wait...)", 2);
args.clear();
args.push_back("-s");
@@ -1264,12 +1311,28 @@ public:
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+ String err;
r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String();
+ if (p_preset->get("custom_package/debug") != "") {
+ if (FileAccess::exists(p_preset->get("custom_package/debug"))) {
+ r_missing_templates = false;
+ } else {
+ err += "Custom debug package not found.\n";
+ }
+ }
+
+ if (p_preset->get("custom_package/release") != "") {
+ if (FileAccess::exists(p_preset->get("custom_package/release"))) {
+ r_missing_templates = false;
+ } else {
+ err += "Custom release package not found.\n";
+ }
+ }
+
bool valid = !r_missing_templates;
String adb = EditorSettings::get_singleton()->get("export/android/adb");
- String err;
if (!FileAccess::exists(adb)) {
@@ -1528,8 +1591,11 @@ public:
String apkfname = "main." + itos(version_code) + "." + get_package_name(package_name) + ".obb";
String fullpath = p_path.get_base_dir().plus_file(apkfname);
err = save_pack(p_preset, fullpath);
+
if (err != OK) {
+ unzClose(pkg);
EditorNode::add_io_error("Could not write expansion package file: " + apkfname);
+
return OK;
}
@@ -1572,7 +1638,7 @@ public:
//add comandline
Vector<uint8_t> clf;
clf.resize(4);
- encode_uint32(cl.size(), &clf[0]);
+ encode_uint32(cl.size(), &clf.write[0]);
for (int i = 0; i < cl.size(); i++) {
print_line(itos(i) + " param: " + cl[i]);
@@ -1582,8 +1648,8 @@ public:
if (!length)
continue;
clf.resize(base + 4 + length);
- encode_uint32(length, &clf[base]);
- copymem(&clf[base + 4], txt.ptr(), length);
+ encode_uint32(length, &clf.write[base]);
+ copymem(&clf.write[base + 4], txt.ptr(), length);
}
zip_fileinfo zipfi = get_zip_fileinfo();
@@ -1775,6 +1841,9 @@ public:
r_features->push_back("Android");
}
+ virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, Set<String> &p_features) {
+ }
+
EditorExportAndroid() {
Ref<Image> img = memnew(Image(_android_logo));
@@ -1786,9 +1855,9 @@ public:
run_icon->create_from_image(img);
device_lock = Mutex::create();
- device_thread = Thread::create(_device_poll_thread, this);
devices_changed = true;
quit_request = false;
+ device_thread = Thread::create(_device_poll_thread, this);
}
~EditorExportAndroid() {
@@ -1811,7 +1880,7 @@ void register_android_exporter() {
EDITOR_DEF("export/android/jarsigner", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/jarsigner", PROPERTY_HINT_GLOBAL_FILE, exe_ext));
EDITOR_DEF("export/android/debug_keystore", "");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "keystore"));
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"));
EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey");
EDITOR_DEF("export/android/debug_keystore_pass", "android");
EDITOR_DEF("export/android/force_system_user", false);
diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp
index 0e5f4fb93a..061e05f5ee 100644
--- a/platform/android/godot_android.cpp
+++ b/platform/android/godot_android.cpp
@@ -928,7 +928,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerMethod(JNIEnv *e
jmethodID mid = env->GetMethodID(cls, mname.ascii().get_data(), cs.ascii().get_data());
if (!mid) {
- print_line("FAILED GETTING METHOD ID " + mname);
+ print_line("RegisterMethod: Failed getting method ID: " + mname);
}
s->add_method(mname, mid, types, get_jni_type(retval));
diff --git a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png
index 94bc406416..372b763ec5 100644
--- a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png
index ef6fe4e836..c61c440636 100644
--- a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png
index 29c4a7b8fc..6ad9b43117 100644
--- a/platform/android/java/res/drawable/icon.png
+++ b/platform/android/java/res/drawable/icon.png
Binary files differ
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 8a2d789dc5..ef798fc790 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -297,7 +297,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
runOnUiThread(new Runnable() {
@Override
public void run() {
- view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/driver/keep_screen_on")));
+ view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
}
});
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
index afe5f81b6d..5d94e77cd7 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
@@ -66,7 +66,6 @@ abstract public class ConsumeTask {
}
final String token = _token;
new AsyncTask<String, String, String>() {
-
@Override
protected String doInBackground(String... params) {
try {
@@ -89,7 +88,6 @@ abstract public class ConsumeTask {
error(param);
}
}
-
}
.execute();
}
diff --git a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
index 766989f953..aaf18c74bf 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
@@ -58,17 +58,15 @@ abstract public class HandlePurchaseTask {
public void handlePurchaseRequest(int resultCode, Intent data) {
//Log.d("XXX", "Handling purchase response");
- //int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
- PaymentsCache pc = new PaymentsCache(context);
-
- String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
- //Log.d("XXX", "Purchase data:" + purchaseData);
- String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
- //Log.d("XXX", "Purchase signature:" + dataSignature);
-
if (resultCode == Activity.RESULT_OK) {
-
try {
+ //int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
+ PaymentsCache pc = new PaymentsCache(context);
+
+ String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
+ //Log.d("XXX", "Purchase data:" + purchaseData);
+ String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
+ //Log.d("XXX", "Purchase signature:" + dataSignature);
//Log.d("SARLANGA", purchaseData);
JSONObject jo = new JSONObject(purchaseData);
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
index b7bf2362cc..d4c7380424 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
@@ -113,7 +113,6 @@ public class PaymentsManager {
public void requestPurchase(final String sku, String transactionId) {
new PurchaseTask(mService, Godot.getInstance()) {
-
@Override
protected void error(String message) {
godotPaymentV3.callbackFail(message);
@@ -128,7 +127,6 @@ public class PaymentsManager {
protected void alreadyOwned() {
godotPaymentV3.callbackAlreadyOwned(sku);
}
-
}
.purchase(sku, transactionId);
}
@@ -139,7 +137,6 @@ public class PaymentsManager {
public void consumeUnconsumedPurchases() {
new ReleaseAllConsumablesTask(mService, activity) {
-
@Override
protected void success(String sku, String receipt, String signature, String token) {
godotPaymentV3.callbackSuccessProductMassConsumed(receipt, signature, sku);
@@ -208,14 +205,12 @@ public class PaymentsManager {
public void processPurchaseResponse(int resultCode, Intent data) {
new HandlePurchaseTask(activity) {
-
@Override
protected void success(final String sku, final String signature, final String ticket) {
godotPaymentV3.callbackSuccess(ticket, signature, sku);
if (auto_consume) {
new ConsumeTask(mService, activity) {
-
@Override
protected void success(String ticket) {
}
@@ -245,12 +240,10 @@ public class PaymentsManager {
public void validatePurchase(String purchaseToken, final String sku) {
new ValidateTask(activity, godotPaymentV3) {
-
@Override
protected void success() {
new ConsumeTask(mService, activity) {
-
@Override
protected void success(String ticket) {
godotPaymentV3.callbackSuccess(ticket, null, sku);
@@ -283,7 +276,6 @@ public class PaymentsManager {
public void consume(final String sku) {
new ConsumeTask(mService, activity) {
-
@Override
protected void success(String ticket) {
godotPaymentV3.callbackSuccessProductMassConsumed(ticket, "", sku);
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
index e00e37f9d1..eccc6f671b 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
@@ -88,7 +88,6 @@ abstract public class ReleaseAllConsumablesTask {
String signature = mySignatures.get(i);
//Log.d("godot", "A punto de consumir un item con token:" + token + "\n" + receipt);
new GenericConsumeTask(context, mService, sku, receipt, signature, token) {
-
@Override
public void onSuccess(String sku, String receipt, String signature, String token) {
ReleaseAllConsumablesTask.this.success(sku, receipt, signature, token);
diff --git a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
index 1eb9d001e0..0626e50bb1 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
@@ -63,7 +63,6 @@ abstract public class ValidateTask {
public void validatePurchase(final String sku) {
new AsyncTask<String, String, String>() {
-
private ProgressDialog dialog;
@Override
@@ -113,7 +112,6 @@ abstract public class ValidateTask {
error(e.getMessage());
}
}
-
}
.execute();
}
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp
index 446a5911e5..022ccb7d89 100644
--- a/platform/android/java_class_wrapper.cpp
+++ b/platform/android/java_class_wrapper.cpp
@@ -554,7 +554,6 @@ bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, St
jstring name2 = (jstring)env->CallObjectMethod(obj, Class_getName);
String str_type = env->GetStringUTFChars(name2, NULL);
- print_line("name: " + str_type);
env->DeleteLocalRef(name2);
uint32_t t = 0;
@@ -1191,9 +1190,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
env->DeleteLocalRef(obj);
env->DeleteLocalRef(param_types);
env->DeleteLocalRef(return_type);
-
- //args[i] = _jobject_to_variant(env, obj);
- //print_line("\targ"+itos(i)+": "+Variant::get_type_name(args[i].get_type()));
};
env->DeleteLocalRef(methods);
@@ -1210,7 +1206,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) {
jstring name = (jstring)env->CallObjectMethod(obj, Field_getName);
String str_field = env->GetStringUTFChars(name, NULL);
env->DeleteLocalRef(name);
- print_line("FIELD: " + str_field);
int mods = env->CallIntMethod(obj, Field_getModifiers);
if ((mods & 0x8) && (mods & 0x10) && (mods & 0x1)) { //static final public!
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index e6240ad9e9..8bb1c38345 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -880,7 +880,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo
const char **cmdline = NULL;
int cmdlen = 0;
- bool use_apk_expansion = false;
if (p_cmdline) {
cmdlen = env->GetArrayLength(p_cmdline);
if (cmdlen) {
@@ -891,9 +890,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo
jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i);
const char *rawString = env->GetStringUTFChars(string, 0);
- if (rawString && strcmp(rawString, "--main-pack") == 0) {
- use_apk_expansion = true;
- }
cmdline[i] = rawString;
}
diff --git a/platform/android/logo.png b/platform/android/logo.png
index fcf684c026..ba2a0e366a 100644
--- a/platform/android/logo.png
+++ b/platform/android/logo.png
Binary files differ
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 9188f09f21..74c40bde72 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -62,12 +62,19 @@ public:
int OS_Android::get_video_driver_count() const {
- return 1;
+ return 2;
}
const char *OS_Android::get_video_driver_name(int p_driver) const {
- return "GLES2";
+ switch (p_driver) {
+ case VIDEO_DRIVER_GLES3:
+ return "GLES3";
+ case VIDEO_DRIVER_GLES2:
+ return "GLES2";
+ }
+ ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
+ ERR_FAIL_V(NULL);
}
int OS_Android::get_audio_driver_count() const {
@@ -124,28 +131,63 @@ void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
gl_extensions = p_gl_extensions;
}
+int OS_Android::get_current_video_driver() const {
+ return video_driver_index;
+}
+
Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
bool use_gl3 = get_gl_version_code_func() >= 0x00030000;
use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3");
- use_gl2 = !use_gl3;
-
- if (gfx_init_func)
- gfx_init_func(gfx_init_ud, use_gl2);
+ bool gl_initialization_error = false;
+
+ while (true) {
+ if (use_gl3) {
+ if (RasterizerGLES3::is_viable() == OK) {
+ if (gfx_init_func)
+ gfx_init_func(gfx_init_ud, false);
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ } else {
+ if (GLOBAL_GET("rendering/quality/driver/driver_fallback") == "Best") {
+ p_video_driver = VIDEO_DRIVER_GLES2;
+ use_gl3 = false;
+ continue;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ } else {
+ if (RasterizerGLES2::is_viable() == OK) {
+ if (gfx_init_func)
+ gfx_init_func(gfx_init_ud, true);
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ } else {
+ gl_initialization_error = true;
+ break;
+ }
+ }
+ }
- if (use_gl2) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- } else {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
+ 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");
+ return ERR_UNAVAILABLE;
}
+ video_driver_index = p_video_driver;
+
visual_server = memnew(VisualServerRaster);
/* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, false));
};*/
+
visual_server->init();
// visual_server->cursor_set_visible(false, 0);
@@ -331,8 +373,6 @@ void OS_Android::process_event(Ref<InputEvent> p_event) {
void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
- //print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size()));
-
switch (p_what) {
case 0: { //gesture begin
@@ -351,8 +391,8 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
touch.resize(p_points.size());
for (int i = 0; i < p_points.size(); i++) {
- touch[i].id = p_points[i].id;
- touch[i].pos = p_points[i].pos;
+ touch.write[i].id = p_points[i].id;
+ touch.write[i].pos = p_points[i].pos;
}
//send touch
@@ -393,7 +433,7 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
ev->set_position(p_points[idx].pos);
ev->set_relative(p_points[idx].pos - touch[i].pos);
input->parse_input_event(ev);
- touch[i].pos = p_points[idx].pos;
+ touch.write[i].pos = p_points[idx].pos;
}
} break;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index ac901d4832..c4220906a3 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -137,6 +137,7 @@ private:
AlertFunc alert_func;
//power_android *power_manager;
+ int video_driver_index;
public:
// functions used by main to initialize/deintialize the OS
@@ -146,6 +147,8 @@ public:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual int get_current_video_driver() const;
+
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png
index e53f8e9da5..b687c9ac31 100644
--- a/platform/android/run_icon.png
+++ b/platform/android/run_icon.png
Binary files differ
diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp
index e85813605f..b13baf69c2 100644
--- a/platform/android/thread_jandroid.cpp
+++ b/platform/android/thread_jandroid.cpp
@@ -132,7 +132,7 @@ JNIEnv *ThreadAndroid::get_env() {
}
JNIEnv *env = NULL;
- int status = java_vm->AttachCurrentThread(&env, NULL);
+ java_vm->AttachCurrentThread(&env, NULL);
return env;
}