diff options
Diffstat (limited to 'platform/android')
32 files changed, 382 insertions, 618 deletions
diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template index 9d8eb951c4..81f4c15849 100644 --- a/platform/android/AndroidManifest.xml.template +++ b/platform/android/AndroidManifest.xml.template @@ -16,7 +16,8 @@ android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:launchMode="singleTask" android:screenOrientation="landscape" - android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize"> + android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize" + android:resizeableActivity="false"> <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -31,175 +32,10 @@ $$ADD_APPLICATION_CHUNKS$$ </application> - <uses-feature android:glEsVersion="0x00030000"/> + <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="23"/> +<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="27"/> </manifest> diff --git a/platform/android/SCsub b/platform/android/SCsub index d2285a82dd..a65dab9668 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -41,10 +41,8 @@ prog = None abspath = env.Dir(".").abspath -gradle_basein = open_utf8(abspath + "/build.gradle.template", "r") -gradle_baseout = open_utf8(abspath + "/java/build.gradle", "w") - -gradle_text = gradle_basein.read() +with open_utf8(abspath + "/build.gradle.template", "r") as gradle_basein: + gradle_text = gradle_basein.read() gradle_maven_flat_text = "" if len(env.android_flat_dirs) > 0: @@ -55,7 +53,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 @@ -101,6 +99,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 @@ -131,17 +132,19 @@ gradle_text = gradle_text.replace("$$GRADLE_DEFAULT_CONFIG$$", gradle_default_co gradle_text = gradle_text.replace("$$GRADLE_PLUGINS$$", gradle_plugins) gradle_text = gradle_text.replace("$$GRADLE_CLASSPATH$$", gradle_classpath) -gradle_baseout.write(gradle_text) -gradle_baseout.close() +with open_utf8(abspath + "/java/build.gradle", "w") as gradle_baseout: + gradle_baseout.write(gradle_text) -pp_basein = open_utf8(abspath + "/AndroidManifest.xml.template", "r") -pp_baseout = open_utf8(abspath + "/java/AndroidManifest.xml", "w") -manifest = pp_basein.read() +with open_utf8(abspath + "/AndroidManifest.xml.template", "r") as pp_basein: + manifest = pp_basein.read() + manifest = manifest.replace("$$ADD_APPLICATION_CHUNKS$$", env.android_manifest_chunk) manifest = manifest.replace("$$ADD_PERMISSION_CHUNKS$$", env.android_permission_chunk) manifest = manifest.replace("$$ADD_APPATTRIBUTE_CHUNKS$$", env.android_appattributes_chunk) -pp_baseout.write(manifest) + +with open_utf8(abspath + "/java/AndroidManifest.xml", "w") as pp_baseout: + pp_baseout.write(manifest) lib = env_android.add_shared_library("#bin/libgodot", [android_objects], SHLIBSUFFIX=env["SHLIBSUFFIX"]) diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index 7545ee88d0..b9f1f1eab0 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -78,15 +78,14 @@ 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)); } - __android_log_print(ANDROID_LOG_INFO, "godot", "Initializing audio! params: %i,%i ", mix_rate, buffer_size); audioBuffer = env->CallObjectMethod(io, _init_audio, mix_rate, buffer_size); ERR_FAIL_COND_V(audioBuffer == NULL, ERR_INVALID_PARAMETER); @@ -113,29 +112,10 @@ void AudioDriverAndroid::setup(jobject p_io) { jclass c = env->GetObjectClass(io); cls = (jclass)env->NewGlobalRef(c); - __android_log_print(ANDROID_LOG_INFO, "godot", "starting to attempt get methods"); - _init_audio = env->GetMethodID(cls, "audioInit", "(II)Ljava/lang/Object;"); - if (_init_audio != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _init_audio ok!!"); - } else { - __android_log_print(ANDROID_LOG_INFO, "godot", "audioinit ok!"); - } - _write_buffer = env->GetMethodID(cls, "audioWriteShortBuffer", "([S)V"); - if (_write_buffer != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _write_buffer ok!!"); - } - _quit = env->GetMethodID(cls, "audioQuit", "()V"); - if (_quit != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _quit ok!!"); - } - _pause = env->GetMethodID(cls, "audioPause", "(Z)V"); - if (_quit != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _pause ok!!"); - } } void AudioDriverAndroid::thread_func(JNIEnv *env) { @@ -144,7 +124,6 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) { if (cls) { cls = (jclass)env->NewGlobalRef(cls); - __android_log_print(ANDROID_LOG_INFO, "godot", "*******CLASS FOUND!!!"); } jfieldID fid = env->GetStaticFieldID(cls, "io", "Lorg/godotengine/godot/GodotIO;"); jobject ob = env->GetStaticObjectField(cls, fid); @@ -152,9 +131,6 @@ void AudioDriverAndroid::thread_func(JNIEnv *env) { jclass c = env->GetObjectClass(gob); jclass lcls = (jclass)env->NewGlobalRef(c); _write_buffer = env->GetMethodID(lcls, "audioWriteShortBuffer", "([S)V"); - if (_write_buffer != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _write_buffer ok!!"); - } while (!quit) { diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index 87a7d04e01..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; @@ -117,8 +118,6 @@ Error AudioDriverOpenSL::init() { ERR_FAIL_V(ERR_INVALID_PARAMETER); } - print_line("OpenSL Init OK!"); - return OK; } @@ -147,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 }; @@ -189,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 */ { @@ -273,4 +266,5 @@ AudioDriverOpenSL::AudioDriverOpenSL() { s_ad = this; mutex = Mutex::create(); //NULL; pause = false; + active = false; } 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/build.gradle.template b/platform/android/build.gradle.template index 7269e658b4..cc45fee95f 100644 --- a/platform/android/build.gradle.template +++ b/platform/android/build.gradle.template @@ -21,7 +21,6 @@ allprojects { } dependencies { - compile 'com.android.support:support-v4:27.+' // can be removed if minSdkVersion 16 and modify DownloadNotification.java & V14CustomNotification.java $$GRADLE_DEPENDENCIES$$ } diff --git a/platform/android/detect.py b/platform/android/detect.py index 892b1b6a85..ada36e2814 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -14,10 +14,13 @@ def get_name(): def can_build(): - return ("ANDROID_NDK_ROOT" in os.environ) +def get_platform(platform): + return int(platform.split("-")[1]) + + def get_opts(): from SCons.Variables import BoolVariable, EnumVariable @@ -124,6 +127,9 @@ def configure(env): else: 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") + env["ndk_platform"] = "android-21" env['ARCH'] = 'arch-arm64' target_subpath = "aarch64-linux-android-4.9" abi_subpath = "aarch64-linux-android" @@ -133,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"): @@ -160,12 +171,13 @@ def configure(env): elif (sys.platform.startswith('win')): if (platform.machine().endswith('64')): host_subpath = "windows-x86_64" - if env["android_arch"] == "arm64v8": - mt_link = False else: mt_link = False host_subpath = "windows" + if env["android_arch"] == "arm64v8": + mt_link = False + compiler_path = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/" + host_subpath + "/bin" gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath tools_path = gcc_toolchain_path + "/" + abi_subpath + "/bin" @@ -199,7 +211,7 @@ def configure(env): env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include"]) env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath]) # For unified headers this define has to be set manually - env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(int(env['ndk_platform'].split("-")[1]))]) + 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"]) @@ -254,10 +266,10 @@ def configure(env): env.Append(LINKFLAGS=target_opts) env.Append(LINKFLAGS=common_opts) - env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + '/toolchains/arm-linux-androideabi-4.9/prebuilt/' + + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/lib/gcc/' + abi_subpath + '/4.9.x']) env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + - '/toolchains/arm-linux-androideabi-4.9/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) + '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) env.Append(CPPPATH=['#platform/android']) env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT']) diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 5601dcc763..ee5ae156b7 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -130,7 +130,6 @@ Error DirAccessJAndroid::change_dir(String p_dir) { else new_dir = current_dir.plus_file(p_dir); - //print_line("new dir is: "+new_dir); //test if newdir exists new_dir = new_dir.simplify_path(); @@ -154,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; @@ -226,28 +224,14 @@ void DirAccessJAndroid::setup(jobject p_io) { JNIEnv *env = ThreadAndroid::get_env(); io = p_io; - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP7"); jclass c = env->GetObjectClass(io); cls = (jclass)env->NewGlobalRef(c); - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP8"); _dir_open = env->GetMethodID(cls, "dir_open", "(Ljava/lang/String;)I"); - if (_dir_open != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _dir_open ok!!"); - } _dir_next = env->GetMethodID(cls, "dir_next", "(I)Ljava/lang/String;"); - if (_dir_next != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _dir_next ok!!"); - } _dir_close = env->GetMethodID(cls, "dir_close", "(I)V"); - if (_dir_close != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _dir_close ok!!"); - } _dir_is_dir = env->GetMethodID(cls, "dir_is_dir", "(I)Z"); - if (_dir_is_dir != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _dir_is_dir ok!!"); - } //(*env)->CallVoidMethod(env,obj,aMethodID, myvar); } diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index b26d2a3aa4..9ad0219746 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,7 @@ class EditorExportAndroid : public EditorExportPlatform { if (dpos == -1) continue; d = d.substr(0, dpos).strip_edges(); - //print_line("found devuce: "+d); + //print_line("found device: "+d); ldevices.push_back(d); } @@ -301,8 +301,7 @@ class EditorExportAndroid : public EditorExportPlatform { args.push_back("-s"); args.push_back(d.id); args.push_back("shell"); - args.push_back("cat"); - args.push_back("/system/build.prop"); + args.push_back("getprop"); int ec; String dp; @@ -315,7 +314,14 @@ class EditorExportAndroid : public EditorExportPlatform { d.api_level = 0; for (int j = 0; j < props.size(); j++) { + // got information by `shell cat /system/build.prop` before and its format is "property=value" + // it's now changed to use `shell getporp` because of permission issue with Android 8.0 and above + // its format is "[property]: [value]" so changed it as like build.prop String p = props[j]; + p = p.replace("]: ", "="); + p = p.replace("[", ""); + p = p.replace("]", ""); + if (p.begins_with("ro.product.model=")) { device = p.get_slice("=", 1).strip_edges(); } else if (p.begins_with("ro.product.brand=")) { @@ -522,11 +528,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); @@ -552,6 +556,10 @@ class EditorExportAndroid : public EditorExportPlatform { return OK; } + static Error ignore_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { + return OK; + } + void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet) { // Leaving the unused types commented because looking these constants up @@ -560,7 +568,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; @@ -591,24 +599,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]); @@ -653,11 +665,11 @@ 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]); @@ -704,13 +716,13 @@ class EditorExportAndroid : public EditorExportPlatform { 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]); + encode_uint32(version_code, &p_manifest.write[iofs + 16]); } if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionName") { @@ -719,62 +731,126 @@ class EditorExportAndroid : public EditorExportPlatform { 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") { - 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 == "uses-permission" && /*nspace=="android" &&*/ attrname == "name") { + if (tname == "supports-screens") { - if (value.begins_with("godot.custom")) { + if (attrname == "smallScreens") { - int which = value.get_slice(".", 2).to_int(); - if (which >= 0 && which < MAX_USER_PERMISSIONS && user_perms[which].strip_edges() != "") { + encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); - string_table[attr_value] = user_perms[which].strip_edges(); - } + } else if (attrname == "normalScreens") { - } else if (value.begins_with("godot.")) { - String perm = value.get_slice(".", 1); + encode_uint32(screen_support_normal ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); - if (perms.has(perm) || (p_give_internet && perm == "INTERNET")) { + } else if (attrname == "largeScreens") { - print_line("PERM: " + perm); - string_table[attr_value] = "android.permission." + perm; - } + encode_uint32(screen_support_large ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); + + } 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") { + print_line("Found manifest end"); - } 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; + } + + for (int i = 0; i < perms.size(); ++i) { + print_line("Adding permission " + perms[i]); - encode_uint32(screen_support_xlarge ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]); + 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; } @@ -788,25 +864,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; } @@ -818,6 +894,7 @@ class EditorExportAndroid : public EditorExportPlatform { ret.push_back(stable_extra[i]); } + //pad while (ret.size() % 4) ret.push_back(0); @@ -826,13 +903,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 + 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 //print_line("file size: "+itos(ret.size())); @@ -856,9 +935,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; @@ -922,18 +1001,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]; @@ -952,19 +1031,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"); @@ -992,7 +1071,7 @@ public: public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - // Reenable when a GLES 2.0 backend is readded + // Re-enable when a GLES 2.0 backend is read /*int api = p_preset->get("graphics/api"); if (api == 0) r_features->push_back("etc"); @@ -1013,7 +1092,7 @@ public: 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,65535,1"), 1)); + 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"), "")); @@ -1073,7 +1152,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; } @@ -1143,7 +1225,7 @@ public: String package_name = p_preset->get("package/unique_name"); if (remove_prev) { - ep.step("Uninstalling..", 1); + ep.step("Uninstalling...", 1); print_line("Uninstalling previous version: " + devices[p_device].name); @@ -1222,7 +1304,7 @@ public: } } - ep.step("Running on Device..", 3); + ep.step("Running on Device...", 3); args.clear(); args.push_back("-s"); args.push_back(devices[p_device].id); @@ -1313,6 +1395,8 @@ public: virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) { + ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); + String src_apk; EditorProgress ep("export", "Exporting for Android", 105); @@ -1480,7 +1564,7 @@ public: ret = unzGoToNextFile(pkg); } - ep.step("Adding Files..", 1); + ep.step("Adding Files...", 1); Error err = OK; Vector<String> cl = cmdline.strip_edges().split(" "); for (int i = 0; i < cl.size(); i++) { @@ -1504,6 +1588,10 @@ public: cl.push_back(passwd); }*/ + APKExportData ed; + ed.ep = &ep; + ed.apk = unaligned_apk; + err = export_project_files(p_preset, ignore_apk_file, &ed, save_apk_so); } else { //all files @@ -1531,17 +1619,17 @@ public: err = export_project_files(p_preset, save_apk_file, &ed, save_apk_so); } + } - if (!err) { - APKExportData ed; - ed.ep = &ep; - ed.apk = unaligned_apk; - for (int 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); - } + if (!err) { + APKExportData ed; + ed.ep = &ep; + ed.apk = unaligned_apk; + for (int 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); } } } @@ -1556,7 +1644,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]); @@ -1566,8 +1654,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(); @@ -1610,14 +1698,14 @@ public: password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass"); user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user"); - ep.step("Signing Debug APK..", 103); + ep.step("Signing Debug APK...", 103); } else { keystore = release_keystore; password = release_password; user = release_username; - ep.step("Signing Release APK..", 103); + ep.step("Signing Release APK...", 103); } if (!FileAccess::exists(keystore)) { @@ -1627,9 +1715,9 @@ public: List<String> args; args.push_back("-digestalg"); - args.push_back("SHA1"); + args.push_back("SHA-256"); args.push_back("-sigalg"); - args.push_back("MD5withRSA"); + args.push_back("SHA256withRSA"); String tsa_url = EditorSettings::get_singleton()->get("export/android/timestamping_authority_url"); if (tsa_url != "") { args.push_back("-tsa"); @@ -1649,7 +1737,7 @@ public: return ERR_CANT_CREATE; } - ep.step("Verifying APK..", 104); + ep.step("Verifying APK...", 104); args.clear(); args.push_back("-verify"); @@ -1669,7 +1757,7 @@ public: static const int ZIP_ALIGNMENT = 4; - ep.step("Aligning APK..", 105); + ep.step("Aligning APK...", 105); unzFile tmp_unaligned = unzOpen2(unaligned_path.utf8().get_data(), &io); if (!tmp_unaligned) { @@ -1770,9 +1858,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() { diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp index 1a9d3af4ea..214e273d9b 100644 --- a/platform/android/file_access_jandroid.cpp +++ b/platform/android/file_access_jandroid.cpp @@ -190,43 +190,16 @@ void FileAccessJAndroid::setup(jobject p_io) { io = p_io; JNIEnv *env = ThreadAndroid::get_env(); - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP5"); - jclass c = env->GetObjectClass(io); - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP6"); cls = (jclass)env->NewGlobalRef(c); _file_open = env->GetMethodID(cls, "file_open", "(Ljava/lang/String;Z)I"); - if (_file_open != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _file_open ok!!"); - } _file_get_size = env->GetMethodID(cls, "file_get_size", "(I)I"); - if (_file_get_size != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _file_get_size ok!!"); - } _file_tell = env->GetMethodID(cls, "file_tell", "(I)I"); - if (_file_tell != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _file_tell ok!!"); - } _file_eof = env->GetMethodID(cls, "file_eof", "(I)Z"); - - if (_file_eof != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _file_eof ok!!"); - } _file_seek = env->GetMethodID(cls, "file_seek", "(II)V"); - if (_file_seek != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _file_seek ok!!"); - } _file_read = env->GetMethodID(cls, "file_read", "(II)[B"); - if (_file_read != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _file_read ok!!"); - } _file_close = env->GetMethodID(cls, "file_close", "(I)V"); - if (_file_close != 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*******GOT METHOD _file_close ok!!"); - } - - //(*env)->CallVoidMethod(env,obj,aMethodID, myvar); } FileAccessJAndroid::FileAccessJAndroid() { diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp index 64715b3683..0e5f4fb93a 100644 --- a/platform/android/godot_android.cpp +++ b/platform/android/godot_android.cpp @@ -76,14 +76,11 @@ public: virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - print_line("attempt to call " + String(p_method)); - r_error.error = Variant::CallError::CALL_OK; Map<StringName, MethodData>::Element *E = method_map.find(p_method); if (!E) { - print_line("no exists"); r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } @@ -91,7 +88,6 @@ public: int ac = E->get().argtypes.size(); if (ac < p_argcount) { - print_line("fewargs"); r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = ac; return Variant(); @@ -99,7 +95,6 @@ public: if (ac > p_argcount) { - print_line("manyargs"); r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = ac; return Variant(); @@ -181,26 +176,21 @@ public: } } - print_line("calling method!!"); - Variant ret; switch (E->get().ret_type) { case Variant::NIL: { - print_line("call void"); env->CallVoidMethodA(instance, E->get().method, v); } break; case Variant::BOOL: { ret = env->CallBooleanMethodA(instance, E->get().method, v); - print_line("call bool"); } break; case Variant::INT: { ret = env->CallIntMethodA(instance, E->get().method, v); - print_line("call int"); } break; case Variant::REAL: { @@ -255,13 +245,10 @@ public: } break; default: { - print_line("failure.."); ERR_FAIL_V(Variant()); } break; } - print_line("success"); - return ret; } @@ -389,7 +376,6 @@ static int engine_init_display(struct engine *engine, bool p_gl2) { eglQuerySurface(display, surface, EGL_WIDTH, &w); eglQuerySurface(display, surface, EGL_HEIGHT, &h); - print_line("INIT VIDEO MODE: " + itos(w) + "," + itos(h)); //engine->os->set_egl_extensions(eglQueryString(display,EGL_EXTENSIONS)); engine->os->init_video_mode(w, h); @@ -942,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 METHOID " + mname); + print_line("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 Binary files differindex 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 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 Binary files differindex 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 diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png Binary files differindex 29c4a7b8fc..6ad9b43117 100644 --- a/platform/android/java/res/drawable/icon.png +++ b/platform/android/java/res/drawable/icon.png diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java index 73e6f83bec..a9f674803c 100644 --- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java +++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java @@ -27,7 +27,6 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.os.Messenger; -import android.support.v4.app.NotificationCompat; /** * This class handles displaying the notification associated with the download @@ -49,9 +48,8 @@ public class DownloadNotification implements IDownloaderClient { private IDownloaderClient mClientProxy; final ICustomNotification mCustomNotification; - // NotificationCompat.Builder is used to support API < 16. This can be changed to Notification.Builder if minimum API >= 16. - private NotificationCompat.Builder mNotificationBuilder; - private NotificationCompat.Builder mCurrentNotificationBuilder; + private Notification.Builder mNotificationBuilder; + private Notification.Builder mCurrentNotificationBuilder; private CharSequence mLabel; private String mCurrentText; private PendingIntent mContentIntent; @@ -187,7 +185,7 @@ public class DownloadNotification implements IDownloaderClient { void setTimeRemaining(long timeRemaining); - NotificationCompat.Builder updateNotification(Context c); + Notification.Builder updateNotification(Context c); } /** @@ -220,7 +218,7 @@ public class DownloadNotification implements IDownloaderClient { mContext.getSystemService(Context.NOTIFICATION_SERVICE); mCustomNotification = CustomNotificationFactory .createCustomNotification(); - mNotificationBuilder = new NotificationCompat.Builder(ctx); + mNotificationBuilder = new Notification.Builder(ctx); mCurrentNotificationBuilder = mNotificationBuilder; } diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/V14CustomNotification.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/V14CustomNotification.java index 390bde96e9..56b2331e31 100644 --- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/V14CustomNotification.java +++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/V14CustomNotification.java @@ -22,7 +22,6 @@ import com.google.android.vending.expansion.downloader.Helpers; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; -import android.support.v4.app.NotificationCompat; public class V14CustomNotification implements DownloadNotification.ICustomNotification { @@ -54,14 +53,13 @@ public class V14CustomNotification implements DownloadNotification.ICustomNotifi mCurrentKB = currentBytes; } - void setProgress(NotificationCompat.Builder builder) { + void setProgress(Notification.Builder builder) { } @Override - public NotificationCompat.Builder updateNotification(Context c) { - // NotificationCompat.Builder is used to support API < 16. This can be changed to Notification.Builder if minimum API >= 16. - NotificationCompat.Builder builder = new NotificationCompat.Builder(c); + public Notification.Builder updateNotification(Context c) { + Notification.Builder builder = new Notification.Builder(c); builder.setContentTitle(mTitle); if (mTotalKB > 0 && -1 != mCurrentKB) { builder.setProgress((int) (mTotalKB >> 8), (int) (mCurrentKB >> 8), false); diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index b5b0afb9e0..ef798fc790 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -32,6 +32,7 @@ package org.godotengine.godot; import android.R; import android.app.Activity; +import android.content.pm.ConfigurationInfo; import android.os.Bundle; import android.view.MotionEvent; import android.view.View; @@ -150,21 +151,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { boolean found = false; - Log.d("XXX", "METHOD: %s\n" + method.getName()); for (String s : p_methods) { - Log.d("XXX", "METHOD CMP WITH: %s\n" + s); if (s.equals(method.getName())) { found = true; - Log.d("XXX", "METHOD CMP VALID"); break; } } if (!found) continue; - Log.d("XXX", "METHOD FOUND: %s\n" + method.getName()); - List<String> ptr = new ArrayList<String>(); Class[] paramTypes = method.getParameterTypes(); @@ -251,9 +247,11 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } }; - public void onVideoInit(boolean use_gl2) { + public void onVideoInit() { + + boolean use_gl3 = getGLESVersionCode() >= 0x00030000; - //mView = new GodotView(getApplication(),io,use_gl2); + //mView = new GodotView(getApplication(),io,use_gl3); //setContentView(mView); layout = new FrameLayout(this); @@ -266,7 +264,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC // ...add to FrameLayout layout.addView(edittext); - mView = new GodotView(getApplication(), io, use_gl2, use_32_bits, this); + mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, this); layout.addView(mView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); edittext.setView(mView); io.setEdit(edittext); @@ -281,7 +279,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC godot.mView.getWindowVisibleDisplayFrame(gameSize); final int keyboardHeight = fullSize.y - gameSize.bottom; - Log.d("GODOT", "setVirtualKeyboardHeight: " + keyboardHeight); GodotLib.setVirtualKeyboardHeight(keyboardHeight); } }); @@ -300,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"))); } }); } @@ -344,6 +341,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC return Godot._self; } + public int getGLESVersionCode() { + ActivityManager am = (ActivityManager)Godot.getInstance().getSystemService(Context.ACTIVITY_SERVICE); + ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo(); + return deviceInfo.reqGlEsVersion; + } + private String[] getCommandLine() { InputStream is; try { @@ -351,8 +354,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC byte[] len = new byte[4]; int r = is.read(len); if (r < 4) { - Log.d("XXX", "**ERROR** Wrong cmdline length.\n"); - Log.d("GODOT", "**ERROR** Wrong cmdline length.\n"); return new String[0]; } int argc = ((int)(len[3] & 0xFF) << 24) | ((int)(len[2] & 0xFF) << 16) | ((int)(len[1] & 0xFF) << 8) | ((int)(len[0] & 0xFF)); @@ -362,12 +363,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC r = is.read(len); if (r < 4) { - Log.d("GODOT", "**ERROR** Wrong cmdline param length.\n"); return new String[0]; } int strlen = ((int)(len[3] & 0xFF) << 24) | ((int)(len[2] & 0xFF) << 16) | ((int)(len[1] & 0xFF) << 8) | ((int)(len[0] & 0xFF)); if (strlen > 65535) { - Log.d("GODOT", "**ERROR** Wrong command len\n"); return new String[0]; } byte[] arg = new byte[strlen]; @@ -379,7 +378,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC return cmdline; } catch (Exception e) { e.printStackTrace(); - Log.d("GODOT", "**ERROR** Exception " + e.getClass().getName() + ":" + e.getMessage()); return new String[0]; } } @@ -393,18 +391,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC String[] new_cmdline; int cll = 0; if (command_line != null) { - Log.d("GODOT", "initializeGodot: command_line: is not null"); new_cmdline = new String[command_line.length + 2]; cll = command_line.length; for (int i = 0; i < command_line.length; i++) { new_cmdline[i] = command_line[i]; } } else { - Log.d("GODOT", "initializeGodot: command_line: is null"); new_cmdline = new String[2]; } - new_cmdline[cll] = "--main_pack"; + new_cmdline[cll] = "--main-pack"; new_cmdline[cll + 1] = expansion_pack_path; command_line = new_cmdline; } @@ -412,13 +408,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC io = new GodotIO(this); io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID); GodotLib.io = io; - Log.d("GODOT", "command_line is null? " + ((command_line == null) ? "yes" : "no")); - /*if(command_line != null){ - Log.d("GODOT", "Command Line:"); - for(int w=0;w <command_line.length;w++){ - Log.d("GODOT"," " + command_line[w]); - } - }*/ mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); @@ -447,8 +436,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override protected void onCreate(Bundle icicle) { - Log.d("GODOT", "** GODOT ACTIVITY CREATED HERE ***\n"); - super.onCreate(icicle); _self = this; Window window = getWindow(); @@ -509,7 +496,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC if (use_apk_expansion && main_pack_md5 != null && main_pack_key != null) { //check that environment is ok! if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - Log.d("GODOT", "**ERROR! No media mounted!"); //show popup and die } @@ -524,25 +510,20 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC File f = new File(expansion_pack_path); boolean pack_valid = true; - Log.d("GODOT", "**PACK** - Path " + expansion_pack_path); if (!f.exists()) { pack_valid = false; - Log.d("GODOT", "**PACK** - File does not exist"); } else if (obbIsCorrupted(expansion_pack_path, main_pack_md5)) { - Log.d("GODOT", "**PACK** - Expansion pack (obb) is corrupted"); pack_valid = false; try { f.delete(); } catch (Exception e) { - Log.d("GODOT", "**PACK** - Error deleting corrupted expansion pack (obb)"); } } if (!pack_valid) { - Log.d("GODOT", "Pack Invalid, try re-downloading."); Intent notifierIntent = new Intent(this, this.getClass()); notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | @@ -553,15 +534,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC int startResult; try { - Log.d("GODOT", "INITIALIZING DOWNLOAD"); startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( getApplicationContext(), pendingIntent, GodotDownloaderService.class); - Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult); if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { - Log.d("GODOT", "DOWNLOAD REQUIRED"); // This is where you do set up to display the download // progress (next step) mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, @@ -581,11 +559,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC return; } else { - Log.d("GODOT", "NO DOWNLOAD REQUIRED"); } } catch (NameNotFoundException e) { // TODO Auto-generated catch block - Log.d("GODOT", "Error downloading expansion package:" + e.getMessage()); } } } @@ -763,7 +739,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } } - System.out.printf("** BACK REQUEST!\n"); if (shouldQuit && mView != null) { mView.queueEvent(new Runnable() { @Override @@ -812,15 +787,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } String md5str = hexString.toString(); - //Log.d("GODOT","**PACK** - My MD5: "+hexString+" - APK md5: "+main_pack_md5); if (!md5str.equals(main_pack_md5)) { - Log.d("GODOT", "**PACK MD5 MISMATCH???** - MD5 Found: " + md5str + " " + Integer.toString(md5str.length()) + " - MD5 Expected: " + main_pack_md5 + " " + Integer.toString(main_pack_md5.length())); return true; } return false; } catch (Exception e) { e.printStackTrace(); - Log.d("GODOT", "**PACK FAIL**"); return true; } } @@ -936,7 +908,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC */ @Override public void onDownloadStateChanged(int newState) { - Log.d("GODOT", "onDownloadStateChanged:" + newState); setState(newState); boolean showDashboard = true; boolean showCellMessage = false; @@ -944,7 +915,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC boolean indeterminate; switch (newState) { case IDownloaderClient.STATE_IDLE: - Log.d("GODOT", "DOWNLOAD STATE IDLE"); // STATE_IDLE means the service is listening, so it's // safe to start making calls via mRemoteService. paused = false; @@ -952,13 +922,11 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC break; case IDownloaderClient.STATE_CONNECTING: case IDownloaderClient.STATE_FETCHING_URL: - Log.d("GODOT", "DOWNLOAD STATE CONNECTION / FETCHING URL"); showDashboard = true; paused = false; indeterminate = true; break; case IDownloaderClient.STATE_DOWNLOADING: - Log.d("GODOT", "DOWNLOAD STATE DOWNLOADING"); paused = false; showDashboard = true; indeterminate = false; @@ -968,14 +936,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC case IDownloaderClient.STATE_FAILED: case IDownloaderClient.STATE_FAILED_FETCHING_URL: case IDownloaderClient.STATE_FAILED_UNLICENSED: - Log.d("GODOT", "DOWNLOAD STATE: FAILED, CANCELLED, UNLICENSED OR FAILED TO FETCH URL"); paused = true; showDashboard = false; indeterminate = false; break; case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION: case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION: - Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY MISSING CELLULAR PERMISSION"); showDashboard = false; paused = true; indeterminate = false; @@ -983,26 +949,21 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC break; case IDownloaderClient.STATE_PAUSED_BY_REQUEST: - Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY USER"); paused = true; indeterminate = false; break; case IDownloaderClient.STATE_PAUSED_ROAMING: case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE: - Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY ROAMING OR SDCARD UNAVAILABLE"); paused = true; indeterminate = false; break; case IDownloaderClient.STATE_COMPLETED: - Log.d("GODOT", "DOWNLOAD STATE: COMPLETED"); showDashboard = false; paused = false; indeterminate = false; - // validateXAPKZipFiles(); initializeGodot(); return; default: - Log.d("GODOT", "DOWNLOAD STATE: DEFAULT"); paused = true; indeterminate = true; showDashboard = true; diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index 6b7f7a283e..bde4221644 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -67,7 +67,7 @@ public class GodotPaymentV3 extends Godot.SingletonBase { public GodotPaymentV3(Activity p_activity) { - registerClass("GodotPayments", new String[] { "purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails" }); + registerClass("GodotPayments", new String[] { "purchase", "setPurchaseCallbackId", "setPurchaseValidationUrlPrefix", "setTransactionId", "getSignature", "consumeUnconsumedPurchases", "requestPurchased", "setAutoConsume", "consume", "querySkuDetails", "isConnected" }); activity = (Godot)p_activity; mPaymentManager = activity.getPaymentsManager(); mPaymentManager.setBaseSingleton(this); @@ -101,12 +101,12 @@ public class GodotPaymentV3 extends Godot.SingletonBase { GodotLib.calldeferred(purchaseCallbackId, "consume_not_required", new Object[] {}); } - public void callbackFailConsume() { - GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[] {}); + public void callbackFailConsume(String message) { + GodotLib.calldeferred(purchaseCallbackId, "consume_fail", new Object[] { message }); } - public void callbackFail() { - GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[] {}); + public void callbackFail(String message) { + GodotLib.calldeferred(purchaseCallbackId, "purchase_fail", new Object[] { message }); } public void callbackCancel() { @@ -164,6 +164,19 @@ public class GodotPaymentV3 extends Godot.SingletonBase { GodotLib.calldeferred(purchaseCallbackId, "has_purchased", new Object[] { receipt, signature, sku }); } + public void callbackDisconnected() { + GodotLib.calldeferred(purchaseCallbackId, "iap_disconnected", new Object[] {}); + } + + public void callbackConnected() { + GodotLib.calldeferred(purchaseCallbackId, "iap_connected", new Object[] {}); + } + + // true if connected, false otherwise + public boolean isConnected() { + return mPaymentManager.isConnected(); + } + // consume item automatically after purchase. default is true. public void setAutoConsume(boolean autoConsume) { mPaymentManager.setAutoConsume(autoConsume); diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 0222758c2b..23723c2696 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -261,7 +261,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { }; int source = event.getSource(); - if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + if ((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { final int button = get_godot_button(keyCode); final int device = find_joy_device(event.getDeviceId()); @@ -302,7 +302,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { int source = event.getSource(); //Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD))); - if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { + if ((source & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (source & InputDevice.SOURCE_DPAD) == InputDevice.SOURCE_DPAD || (source & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) { if (event.getRepeatCount() > 0) // ignore key echo return true; diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 1102ab7450..5d13f17ffb 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -103,13 +103,16 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void onTextChanged(final CharSequence pCharSequence, final int start, final int before, final int count) { //Log.d(TAG, "onTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",before: " + before); + final int[] newChars = new int[count]; + for (int i = start; i < start + count; ++i) { + newChars[i - start] = pCharSequence.charAt(i); + } mView.queueEvent(new Runnable() { @Override public void run() { - for (int i = start; i < start + count; ++i) { - final int ch = pCharSequence.charAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + for (int i = 0; i < count; ++i) { + GodotLib.key(0, newChars[i], true); + GodotLib.key(0, newChars[i], false); } } }); 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 da6d66ae88..d4c7380424 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java @@ -93,20 +93,29 @@ public class PaymentsManager { @Override public void onServiceDisconnected(ComponentName name) { mService = null; + + // At this stage, godotPaymentV3 might not have been initialized yet. + if (godotPaymentV3 != null) { + godotPaymentV3.callbackDisconnected(); + } } @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = IInAppBillingService.Stub.asInterface(service); + + // At this stage, godotPaymentV3 might not have been initialized yet. + if (godotPaymentV3 != null) { + godotPaymentV3.callbackConnected(); + } } }; public void requestPurchase(final String sku, String transactionId) { new PurchaseTask(mService, Godot.getInstance()) { - @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } @Override @@ -118,14 +127,16 @@ public class PaymentsManager { protected void alreadyOwned() { godotPaymentV3.callbackAlreadyOwned(sku); } - } .purchase(sku, transactionId); } + public boolean isConnected() { + return mService != null; + } + public void consumeUnconsumedPurchases() { new ReleaseAllConsumablesTask(mService, activity) { - @Override protected void success(String sku, String receipt, String signature, String token) { godotPaymentV3.callbackSuccessProductMassConsumed(receipt, signature, sku); @@ -134,7 +145,7 @@ public class PaymentsManager { @Override protected void error(String message) { Log.d("godot", "consumeUnconsumedPurchases :" + message); - godotPaymentV3.callbackFailConsume(); + godotPaymentV3.callbackFailConsume(message); } @Override @@ -194,21 +205,19 @@ 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) { } @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } } .consume(sku); @@ -217,7 +226,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } @Override @@ -231,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); @@ -244,7 +251,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } } .consume(sku); @@ -252,7 +259,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFail(); + godotPaymentV3.callbackFail(message); } @Override @@ -269,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); @@ -277,7 +283,7 @@ public class PaymentsManager { @Override protected void error(String message) { - godotPaymentV3.callbackFailConsume(); + godotPaymentV3.callbackFailConsume(message); } } .consume(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 80a32452a5..446a5911e5 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -1117,7 +1117,7 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) { } if (!valid) { - print_line("Method Can't be bound (unsupported arguments): " + p_class + "::" + str_method); + print_line("Method can't be bound (unsupported arguments): " + p_class + "::" + str_method); env->DeleteLocalRef(obj); env->DeleteLocalRef(param_types); continue; @@ -1130,7 +1130,7 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) { String strsig; uint32_t sig = 0; if (!_get_type_sig(env, return_type, sig, strsig)) { - print_line("Method Can't be bound (unsupported return type): " + p_class + "::" + str_method); + print_line("Method can't be bound (unsupported return type): " + p_class + "::" + str_method); env->DeleteLocalRef(obj); env->DeleteLocalRef(param_types); env->DeleteLocalRef(return_type); @@ -1140,8 +1140,6 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) { signature += strsig; mi.return_type = sig; - print_line("METHOD: " + str_method + " SIG: " + signature + " static: " + itos(mi._static)); - bool discard = false; for (List<JavaClass::MethodInfo>::Element *E = java_class->methods[str_method].front(); E; E = E->next()) { @@ -1173,11 +1171,9 @@ Ref<JavaClass> JavaClassWrapper::wrap(const String &p_class) { if (new_likeliness > existing_likeliness) { java_class->methods[str_method].erase(E); - print_line("replace old"); break; } else { discard = true; - print_line("old is better"); } } diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 4e9e4f6260..8bb1c38345 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -240,7 +240,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jclass c = env->GetObjectClass(obj); bool array; String name = _get_class_name(env, c, &array); - //print_line("name is " + name + ", array "+Variant(array)); if (name == "java.lang.String") { @@ -251,7 +250,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jobjectArray arr = (jobjectArray)obj; int stringCount = env->GetArrayLength(arr); - //print_line("String array! " + String::num(stringCount)); PoolVector<String> sarr; for (int i = 0; i < stringCount; i++) { @@ -380,7 +378,6 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { Array vals = _jobject_to_variant(env, arr); env->DeleteLocalRef(arr); - //print_line("adding " + String::num(keys.size()) + " to Dictionary!"); for (int i = 0; i < keys.size(); i++) { ret[keys[i]] = vals[i]; @@ -411,7 +408,6 @@ class JNISingleton : public Object { public: virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - //print_line("attempt to call "+String(p_method)); ERR_FAIL_COND_V(!instance, Variant()); r_error.error = Variant::CallError::CALL_OK; @@ -419,7 +415,6 @@ public: Map<StringName, MethodData>::Element *E = method_map.find(p_method); if (!E) { - print_line("no exists"); r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } @@ -427,7 +422,6 @@ public: int ac = E->get().argtypes.size(); if (ac < p_argcount) { - print_line("fewargs"); r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = ac; return Variant(); @@ -435,7 +429,6 @@ public: if (ac > p_argcount) { - print_line("manyargs"); r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = ac; return Variant(); @@ -464,7 +457,6 @@ public: ERR_FAIL_COND_V(res != 0, Variant()); - //print_line("argcount "+String::num(p_argcount)); List<jobject> to_erase; for (int i = 0; i < p_argcount; i++) { @@ -474,26 +466,21 @@ public: to_erase.push_back(vr.obj); } - //print_line("calling method!!"); - Variant ret; switch (E->get().ret_type) { case Variant::NIL: { - //print_line("call void"); env->CallVoidMethodA(instance, E->get().method, v); } break; case Variant::BOOL: { ret = env->CallBooleanMethodA(instance, E->get().method, v) == JNI_TRUE; - //print_line("call bool"); } break; case Variant::INT: { ret = env->CallIntMethodA(instance, E->get().method, v); - //print_line("call int"); } break; case Variant::REAL: { @@ -544,7 +531,6 @@ public: case Variant::DICTIONARY: { - //print_line("call dictionary"); jobject obj = env->CallObjectMethodA(instance, E->get().method, v); ret = _jobject_to_variant(env, obj); env->DeleteLocalRef(obj); @@ -552,7 +538,6 @@ public: } break; default: { - print_line("failure.."); env->PopLocalFrame(NULL); ERR_FAIL_V(Variant()); } break; @@ -564,7 +549,6 @@ public: } env->PopLocalFrame(NULL); - //print_line("success"); return ret; } @@ -630,6 +614,7 @@ static jmethodID _hideKeyboard = 0; static jmethodID _setScreenOrientation = 0; static jmethodID _getUniqueID = 0; static jmethodID _getSystemDir = 0; +static jmethodID _getGLESVersionCode = 0; static jmethodID _playVideo = 0; static jmethodID _isVideoPlaying = 0; static jmethodID _pauseVideo = 0; @@ -701,6 +686,11 @@ static String _get_system_dir(int p_dir) { return String(env->GetStringUTFChars(s, NULL)); } +static int _get_gles_version_code() { + JNIEnv *env = ThreadAndroid::get_env(); + return env->CallIntMethod(_godot_instance, _getGLESVersionCode); +} + static void _hide_vk() { JNIEnv *env = ThreadAndroid::get_env(); @@ -757,8 +747,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion) { - __android_log_print(ANDROID_LOG_INFO, "godot", "**INIT EVENT! - %p\n", env); - initialized = true; JavaVM *jvm; @@ -767,8 +755,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en _godot_instance = env->NewGlobalRef(activity); //_godot_instance=activity; - __android_log_print(ANDROID_LOG_INFO, "godot", "***************** HELLO FROM JNI!!!!!!!!"); - { //setup IO Object @@ -776,22 +762,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en if (cls) { cls = (jclass)env->NewGlobalRef(cls); - __android_log_print(ANDROID_LOG_INFO, "godot", "*******CLASS FOUND!!!"); } - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP2, %p", cls); jfieldID fid = env->GetStaticFieldID(cls, "io", "Lorg/godotengine/godot/GodotIO;"); - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP3 %i", fid); jobject ob = env->GetStaticObjectField(cls, fid); - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP4, %p", ob); jobject gob = env->NewGlobalRef(ob); - __android_log_print(ANDROID_LOG_INFO, "godot", "STEP4.5, %p", gob); godot_io = gob; - _on_video_init = env->GetMethodID(cls, "onVideoInit", "(Z)V"); + _on_video_init = env->GetMethodID(cls, "onVideoInit", "()V"); _setKeepScreenOn = env->GetMethodID(cls, "setKeepScreenOn", "(Z)V"); _alertDialog = env->GetMethodID(cls, "alert", "(Ljava/lang/String;Ljava/lang/String;)V"); + _getGLESVersionCode = env->GetMethodID(cls, "getGLESVersionCode", "()I"); jclass clsio = env->FindClass("org/godotengine/godot/Godot"); if (cls) { @@ -825,25 +807,19 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en AudioDriverAndroid::setup(gob); } - os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); + os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _get_gles_version_code, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); os_android->set_need_reload_hooks(p_need_reload_hook); char wd[500]; getcwd(wd, 500); - __android_log_print(ANDROID_LOG_INFO, "godot", "test construction %i\n", tst.a); - __android_log_print(ANDROID_LOG_INFO, "godot", "running from dir %s\n", wd); - - //video driver is determined here, because once initialized, it can't be changed - // String vd = ProjectSettings::get_singleton()->get("display/driver"); - - env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean) true); + env->CallVoidMethod(_godot_instance, _on_video_init); } static void _initialize_java_modules() { if (!ProjectSettings::get_singleton()->has_setting("android/modules")) { - print_line("ANDROID MODULES: Nothing to load, aborting"); + print_line("Android modules: Nothing to load, aborting"); return; } @@ -853,8 +829,6 @@ static void _initialize_java_modules() { return; } Vector<String> mods = modules.split(",", false); - print_line("ANDROID MODULES : " + modules); - __android_log_print(ANDROID_LOG_INFO, "godot", "mod count: %i", mods.size()); if (mods.size()) { @@ -877,7 +851,7 @@ static void _initialize_java_modules() { String m = mods[i]; //jclass singletonClass = env->FindClass(m.utf8().get_data()); - print_line("LOADING MODULE: " + m); + print_line("Loading module: " + m); jstring strClassName = env->NewStringUTF(m.utf8().get_data()); jclass singletonClass = (jclass)env->CallObjectMethod(cls, findClass, strClassName); @@ -888,7 +862,6 @@ static void _initialize_java_modules() { } //singletonClass=(jclass)env->NewGlobalRef(singletonClass); - __android_log_print(ANDROID_LOG_INFO, "godot", "****^*^*?^*^*class data %x", singletonClass); jmethodID initialize = env->GetStaticMethodID(singletonClass, "initialize", "(Landroid/app/Activity;)Lorg/godotengine/godot/Godot$SingletonBase;"); if (!initialize) { @@ -897,7 +870,6 @@ static void _initialize_java_modules() { ERR_CONTINUE(!initialize); } jobject obj = env->CallStaticObjectMethod(singletonClass, initialize, _godot_instance); - __android_log_print(ANDROID_LOG_INFO, "godot", "****^*^*?^*^*class instance %x", obj); jobject gob = env->NewGlobalRef(obj); } } @@ -906,11 +878,8 @@ static void _initialize_java_modules() { JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline) { ThreadAndroid::setup_thread(); - __android_log_print(ANDROID_LOG_INFO, "godot", "**SETUP"); - const char **cmdline = NULL; int cmdlen = 0; - bool use_apk_expansion = false; if (p_cmdline) { cmdlen = env->GetArrayLength(p_cmdline); if (cmdlen) { @@ -921,20 +890,11 @@ 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) { - __android_log_print(ANDROID_LOG_INFO, "godot", "cmdline arg %i is null\n", i); - } else { - //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString); - - if (strcmp(rawString, "-main_pack") == 0) - use_apk_expansion = true; - } cmdline[i] = rawString; } } } - __android_log_print(ANDROID_LOG_INFO, "godot", "CMDLINE LEN %i - APK EXPANSION %i\n", cmdlen, int(use_apk_expansion)); Error err = Main::setup("apk", cmdlen, (char **)cmdline, false); if (cmdline) { @@ -942,10 +902,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo } if (err != OK) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*****UNABLE TO SETUP"); return; //should exit instead and print the error } - __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK"); java_class_wrapper = memnew(JavaClassWrapper(_godot_instance)); Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", java_class_wrapper)); @@ -954,7 +912,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) { - __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height); if (os_android) os_android->set_display_size(Size2(width, height)); @@ -968,8 +925,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) { - __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id()); - if (os_android) { os_android->set_context_is_16_bits(!p_32_bits); } @@ -981,12 +936,14 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *en } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) { + if (step == 0) + return; + os_android->main_loop_request_go_back(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj) { if (step == 0) { - __android_log_print(ANDROID_LOG_INFO, "godot", "**FIRST_STEP"); // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop @@ -1004,8 +961,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job ++step; } - //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id()); - os_android->process_accelerometer(accelerometer); os_android->process_gravity(gravity); @@ -1019,13 +974,13 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job jclass cls = env->FindClass("org/godotengine/godot/Godot"); jmethodID _finish = env->GetMethodID(cls, "forceQuit", "()V"); env->CallVoidMethod(_godot_instance, _finish); - __android_log_print(ANDROID_LOG_INFO, "godot", "**FINISH REQUEST!!! - %p-%i\n", env, Thread::get_caller_id()); } } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) { - //__android_log_print(ANDROID_LOG_INFO,"godot","**TOUCH EVENT! - %p-%i\n",env,Thread::get_caller_id()); + if (step == 0) + return; Vector<OS_Android::TouchPos> points; for (int i = 0; i < count; i++) { @@ -1292,7 +1247,6 @@ static unsigned int android_get_keysym(unsigned int p_code) { for (int i = 0; _ak_to_keycode[i].keysym != KEY_UNKNOWN; i++) { if (_ak_to_keycode[i].keycode == p_code) { - //print_line("outcode: " + _ak_to_keycode[i].keysym); return _ak_to_keycode[i].keysym; } @@ -1302,6 +1256,8 @@ static unsigned int android_get_keysym(unsigned int p_code) { } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed) { + if (step == 0) + return; OS_Android::JoypadEvent jevent; jevent.device = p_device; @@ -1313,6 +1269,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { + if (step == 0) + return; OS_Android::JoypadEvent jevent; jevent.device = p_device; @@ -1324,6 +1282,9 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) { + if (step == 0) + return; + OS_Android::JoypadEvent jevent; jevent.device = p_device; jevent.type = OS_Android::JOY_EVENT_HAT; @@ -1353,6 +1314,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { + if (step == 0) + return; Ref<InputEventKey> ievent; ievent.instance(); @@ -1362,8 +1325,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobj ievent->set_unicode(val); ievent->set_pressed(p_pressed); - print_line("Scancode: " + String::num(p_scancode) + ":" + String::num(ievent->get_scancode()) + " Unicode: " + String::num(val)); - if (val == '\n') { ievent->set_scancode(KEY_ENTER); } else if (val == 61448) { @@ -1398,14 +1359,18 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jobject obj) { - if (os_android && step > 0) - os_android->main_loop_focusin(); + if (step == 0) + return; + + os_android->main_loop_focusin(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jobject obj) { - if (os_android && step > 0) - os_android->main_loop_focusout(); + if (step == 0) + return; + + os_android->main_loop_focusout(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jobject obj) { @@ -1527,7 +1492,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_method(JNIEnv *env, j jmethodID mid = env->GetMethodID(cls, mname.ascii().get_data(), cs.ascii().get_data()); if (!mid) { - print_line("FAILED GETTING METHOID " + mname); + print_line("Failed getting method ID " + mname); } s->add_method(mname, mid, types, get_jni_type(retval)); @@ -1578,16 +1543,12 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv * int count = env->GetArrayLength(params); Variant args[VARIANT_ARG_MAX]; - //print_line("Java->GD call: "+obj->get_type()+"::"+str_method+" argc "+itos(count)); - for (int i = 0; i < MIN(count, VARIANT_ARG_MAX); i++) { jobject obj = env->GetObjectArrayElement(params, i); if (obj) args[i] = _jobject_to_variant(env, obj); env->DeleteLocalRef(obj); - - //print_line("\targ"+itos(i)+": "+Variant::get_type_name(args[i].get_type())); }; obj->call_deferred(str_method, args[0], args[1], args[2], args[3], args[4]); diff --git a/platform/android/logo.png b/platform/android/logo.png Binary files differindex fcf684c026..ba2a0e366a 100644 --- a/platform/android/logo.png +++ b/platform/android/logo.png diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 23811f963a..f9eda9dff1 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -32,6 +32,7 @@ #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" @@ -48,6 +49,8 @@ #include "file_access_jandroid.h" #endif +#include <dlfcn.h> + class AndroidLogger : public Logger { public: virtual void logv(const char *p_format, va_list p_list, bool p_err) { @@ -121,17 +124,28 @@ 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) { - use_gl2 = p_video_driver != 1; + 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); - AudioDriverManager::add_driver(&audio_driver_android); - - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); + if (use_gl2) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + video_driver_index = VIDEO_DRIVER_GLES2; + } else { + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + video_driver_index = VIDEO_DRIVER_GLES3; + } visual_server = memnew(VisualServerRaster); /* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { @@ -173,6 +187,15 @@ void OS_Android::alert(const String &p_alert, const String &p_title) { alert_func(p_alert, p_title); } +Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { + p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW); + if (!p_library_handle) { + ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + dlerror()); + ERR_FAIL_V(ERR_CANT_OPEN); + } + return OK; +} + void OS_Android::set_mouse_show(bool p_show) { //android has no mouse... @@ -321,17 +344,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (touch.size()) { //end all if exist - { - Ref<InputEventMouseButton> ev; - ev.instance(); - ev->set_button_index(BUTTON_LEFT); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_pressed(false); - ev->set_position(touch[0].pos); - ev->set_global_position(touch[0].pos); - input->parse_input_event(ev); - } - for (int i = 0; i < touch.size(); i++) { Ref<InputEventScreenTouch> ev; @@ -345,23 +357,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; - } - - { - //send mouse - Ref<InputEventMouseButton> ev; - ev.instance(); - // ev.type = Ref<InputEvent>::MOUSE_BUTTON; - ev->set_button_index(BUTTON_LEFT); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_pressed(true); - ev->set_position(touch[0].pos); - ev->set_global_position(touch[0].pos); - input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y)); - last_mouse = touch[0].pos; - input->parse_input_event(ev); + touch.write[i].id = p_points[i].id; + touch.write[i].pos = p_points[i].pos; } //send touch @@ -378,19 +375,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> } break; case 1: { //motion - if (p_points.size()) { - //send mouse, should look for point 0? - Ref<InputEventMouseMotion> ev; - ev.instance(); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_position(p_points[0].pos); - input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y)); - ev->set_speed(input->get_last_mouse_speed()); - ev->set_relative(p_points[0].pos - last_mouse); - last_mouse = p_points[0].pos; - input->parse_input_event(ev); - } - ERR_FAIL_COND(touch.size() != p_points.size()); for (int i = 0; i < touch.size(); i++) { @@ -415,7 +399,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; @@ -423,16 +407,6 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (touch.size()) { //end all if exist - Ref<InputEventMouseButton> ev; - ev.instance(); - ev->set_button_index(BUTTON_LEFT); - ev->set_button_mask(BUTTON_MASK_LEFT); - ev->set_pressed(false); - ev->set_position(touch[0].pos); - ev->set_global_position(touch[0].pos); - input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y)); - input->parse_input_event(ev); - for (int i = 0; i < touch.size(); i++) { Ref<InputEventScreenTouch> ev; @@ -724,7 +698,7 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) { return false; } -OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) { +OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion) { use_apk_expansion = p_use_apk_expansion; default_videomode.width = 800; @@ -746,6 +720,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI get_screen_dpi_func = p_get_screen_dpi_func; get_unique_id_func = p_get_unique_id; get_system_dir_func = p_get_sdir_func; + get_gl_version_code_func = p_get_gl_version_func; video_play_func = p_video_play_func; video_is_playing_func = p_video_is_playing_func; @@ -764,6 +739,8 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI Vector<Logger *> loggers; loggers.push_back(memnew(AndroidLogger)); _set_logger(memnew(CompositeLogger(loggers))); + + AudioDriverManager::add_driver(&audio_driver_android); } OS_Android::~OS_Android() { diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 7ace7b5200..c4220906a3 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -58,6 +58,7 @@ typedef void (*ShowVirtualKeyboardFunc)(const String &); typedef void (*HideVirtualKeyboardFunc)(); typedef void (*SetScreenOrientationFunc)(int); typedef String (*GetSystemDirFunc)(int); +typedef int (*GetGLVersionCodeFunc)(); typedef void (*VideoPlayFunc)(const String &); typedef bool (*VideoIsPlayingFunc)(); @@ -93,7 +94,6 @@ public: private: Vector<TouchPos> touch; - Point2 last_mouse; GFXInitFunc gfx_init_func; void *gfx_init_ud; @@ -127,6 +127,7 @@ private: SetScreenOrientationFunc set_screen_orientation_func; GetUniqueIDFunc get_unique_id_func; GetSystemDirFunc get_system_dir_func; + GetGLVersionCodeFunc get_gl_version_code_func; VideoPlayFunc video_play_func; VideoIsPlayingFunc video_is_playing_func; @@ -136,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 @@ -145,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); @@ -159,6 +163,8 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); + virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); virtual bool is_mouse_grab_enabled() const; @@ -238,7 +244,7 @@ public: void joy_connection_changed(int p_device, bool p_connected, String p_name); virtual bool _check_internal_feature_support(const String &p_feature); - OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion); + OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, bool p_use_apk_expansion); ~OS_Android(); }; diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png Binary files differindex e53f8e9da5..b687c9ac31 100644 --- a/platform/android/run_icon.png +++ b/platform/android/run_icon.png 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; } |