diff --git a/project/java/Settings.java b/project/java/Settings.java index 54e89bf06..38f3bbc4d 100644 --- a/project/java/Settings.java +++ b/project/java/Settings.java @@ -619,6 +619,9 @@ class Settings nativeSetEnv( "SDCARD", Environment.getExternalStorageDirectory().getAbsolutePath() ); nativeSetEnv( "ANDROID_VERSION", String.valueOf(android.os.Build.VERSION.SDK_INT) ); nativeSetEnv( "ANDROID_PACKAGE_NAME", p.getPackageName() ); + try { + nativeSetEnv( "ANDROID_APP_NAME", p.getString(p.getApplicationInfo().labelRes) ); + } catch (Exception eeeeee) {} if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO ) nativeSetEnv( "ANDROID_PACKAGE_PATH", p.getPackageCodePath() ); Log.d("SDL", "libSDL: Is running on OUYA: " + p.isRunningOnOUYA()); diff --git a/project/java/Video.java b/project/java/Video.java index a782d4d2f..527e195b3 100644 --- a/project/java/Video.java +++ b/project/java/Video.java @@ -916,9 +916,19 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer return ret; } - public void openExternalWebBrowser(String url) + public void openExternalApp(String pkgName, String activity, String url) { - context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url))); + Intent i = new Intent(); + if (url != null) + { + i.setAction(Intent.ACTION_VIEW); + i.setData(Uri.parse(url)); + } + if (pkgName != null && activity != null) + { + i.setClassName(pkgName, activity); + } + context.startActivity(i); } private int PowerOf2(int i) diff --git a/project/jni/application/xserver-debian/AndroidData/postinstall2.sh b/project/jni/application/xserver-debian/AndroidData/postinstall2.sh index 8d03a6d81..18743f376 100755 --- a/project/jni/application/xserver-debian/AndroidData/postinstall2.sh +++ b/project/jni/application/xserver-debian/AndroidData/postinstall2.sh @@ -1,10 +1,14 @@ #!/system/bin/sh -echo "Extracting XSDL data files" +echo "Extracting data files" cd $SECURE_STORAGE_DIR ./busybox tar xzf $UNSECURE_STORAGE_DIR/data-1.tar.gz rm -f $UNSECURE_STORAGE_DIR/data-1.tar.gz +ARCH=`getprop ro.product.cpu.abi` +echo "Copying files for architecture $ARCH" +./busybox cp -af img-$ARCH/. img/ +echo "Removing files for other architectures" +./busybox rm -rf img-armeabi-v7a img-x86 cd $SECURE_STORAGE_DIR/img echo "Installation path: $SECURE_STORAGE_DIR/img" -ls -l $SECURE_STORAGE_DIR/img ./postinstall.sh diff --git a/project/jni/application/xserver-gimp/AndroidAppSettings.cfg b/project/jni/application/xserver-gimp/AndroidAppSettings.cfg index 73e2caa90..14c047cc1 100644 --- a/project/jni/application/xserver-gimp/AndroidAppSettings.cfg +++ b/project/jni/application/xserver-gimp/AndroidAppSettings.cfg @@ -18,7 +18,7 @@ AppVersionName="2.8.14.20" # If the URL does not contain 'http://' it is treated as file from 'project/jni/application/src/AndroidData' dir - # these files are put inside .apk package by build system # You can specify Google Play expansion files in the form 'obb:main.12345' or 'obb:patch.12345' where 12345 is the app version, first associated with the file -AppDataDownloadUrl="!!Data files|:data.tar.gz:obb:main.281420|:data.tar.gz:http://sourceforge.net/projects/libsdl-android/files/ubuntu/jessie/dist-gimp-jessie-.tar.gz/download^!!XSDL data files|:data-1.tar.gz:data-1.tgz^!!XSDL fonts|:DroidSansMono.ttf:DroidSansMono.ttf^!!Postinstall script|:postinstall.sh:postinstall2.sh^!!Update|:update1.tar.gz:update1.tgz^!!Update|:update2.tar.gz:update2-.tgz^!!Update|:update3.tar.gz:update3-.tgz^!!Update|:update4.tar.gz:update4.tgz^!!Update|:update6.tar.gz:update6-.tgz" +AppDataDownloadUrl="!!Data files|:data.tar.xz:obb:main.281420|:data.tar.xz:http://sourceforge.net/projects/libsdl-android/files/ubuntu/jessie/dist-gimp-jessie.tar.xz/download^!!XSDL data files|:data-1.tar.gz:data-1.tgz^!!XSDL fonts|:DroidSansMono.ttf:DroidSansMono.ttf^!!Postinstall script|:postinstall.sh:postinstall.sh" # Reset SDL config when updating application to the new version (y) / (n) ResetSdlConfigForThisVersion=y @@ -249,7 +249,7 @@ AppSubdirsBuild='' AppBuildExclude='' # Application command line parameters, including app name as 0-th param -AppCmdline='XSDL -nohelp -screenbuttons -exec $SECURE_STORAGE_DIR/usr/bin/xli -onroot -border black -center $SECURE_STORAGE_DIR/loading.gif ; $SECURE_STORAGE_DIR/img/proot.sh ./startx.sh' +AppCmdline='XSDL -nohelp -screenbuttons -exec $SECURE_STORAGE_DIR/usr/bin/xli -onroot -border black -center $SECURE_STORAGE_DIR/loading.gif ; $SECURE_STORAGE_DIR/img/proot.sh ./startx.sh' # Screen size is used by Google Play to prevent an app to be installed on devices with smaller screens # Minimum screen size that application supports: (s)mall / (m)edium / (l)arge diff --git a/project/jni/application/xserver-gimp/AndroidData/postinstall2.sh b/project/jni/application/xserver-gimp/AndroidData/postinstall.sh similarity index 100% rename from project/jni/application/xserver-gimp/AndroidData/postinstall2.sh rename to project/jni/application/xserver-gimp/AndroidData/postinstall.sh diff --git a/project/jni/application/xserver-gimp/AndroidData/update1.tgz b/project/jni/application/xserver-gimp/AndroidData/update1.tgz deleted file mode 100644 index 2fd22642b..000000000 Binary files a/project/jni/application/xserver-gimp/AndroidData/update1.tgz and /dev/null differ diff --git a/project/jni/application/xserver-gimp/AndroidData/update2-armeabi-v7a.tgz b/project/jni/application/xserver-gimp/AndroidData/update2-armeabi-v7a.tgz deleted file mode 120000 index 30f3f962d..000000000 --- a/project/jni/application/xserver-gimp/AndroidData/update2-armeabi-v7a.tgz +++ /dev/null @@ -1 +0,0 @@ -../../xserver-debian/AndroidData/update2-armeabi-v7a.tgz \ No newline at end of file diff --git a/project/jni/application/xserver-gimp/AndroidData/update2-x86.tgz b/project/jni/application/xserver-gimp/AndroidData/update2-x86.tgz deleted file mode 120000 index ce0925985..000000000 --- a/project/jni/application/xserver-gimp/AndroidData/update2-x86.tgz +++ /dev/null @@ -1 +0,0 @@ -../../xserver-debian/AndroidData/update2-x86.tgz \ No newline at end of file diff --git a/project/jni/application/xserver-gimp/AndroidData/update3-armeabi-v7a.tgz b/project/jni/application/xserver-gimp/AndroidData/update3-armeabi-v7a.tgz deleted file mode 120000 index c719507c9..000000000 --- a/project/jni/application/xserver-gimp/AndroidData/update3-armeabi-v7a.tgz +++ /dev/null @@ -1 +0,0 @@ -../../xserver-debian/AndroidData/update5-armeabi-v7a.tgz \ No newline at end of file diff --git a/project/jni/application/xserver-gimp/AndroidData/update3-x86.tgz b/project/jni/application/xserver-gimp/AndroidData/update3-x86.tgz deleted file mode 120000 index 101d0f2e2..000000000 --- a/project/jni/application/xserver-gimp/AndroidData/update3-x86.tgz +++ /dev/null @@ -1 +0,0 @@ -../../xserver-debian/AndroidData/update5-x86.tgz \ No newline at end of file diff --git a/project/jni/application/xserver-gimp/AndroidData/update4.tgz b/project/jni/application/xserver-gimp/AndroidData/update4.tgz deleted file mode 100644 index 83fc35f69..000000000 Binary files a/project/jni/application/xserver-gimp/AndroidData/update4.tgz and /dev/null differ diff --git a/project/jni/application/xserver-gimp/AndroidData/update6-armeabi-v7a.tgz b/project/jni/application/xserver-gimp/AndroidData/update6-armeabi-v7a.tgz deleted file mode 120000 index 75bea3a43..000000000 --- a/project/jni/application/xserver-gimp/AndroidData/update6-armeabi-v7a.tgz +++ /dev/null @@ -1 +0,0 @@ -../../xserver-debian/AndroidData/update6-armeabi-v7a.tgz \ No newline at end of file diff --git a/project/jni/application/xserver-gimp/AndroidData/update6-x86.tgz b/project/jni/application/xserver-gimp/AndroidData/update6-x86.tgz deleted file mode 120000 index d5fa151e3..000000000 --- a/project/jni/application/xserver-gimp/AndroidData/update6-x86.tgz +++ /dev/null @@ -1 +0,0 @@ -../../xserver-debian/AndroidData/update6-x86.tgz \ No newline at end of file diff --git a/project/jni/application/xserver/gfx.c b/project/jni/application/xserver/gfx.c index cc8a6f125..aab04780d 100644 --- a/project/jni/application/xserver/gfx.c +++ b/project/jni/application/xserver/gfx.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "gfx.h" @@ -20,6 +21,8 @@ static TTF_Font* sFont; static int unpackFinished = 0; +enum { UPGRADE_WARNING_NONE, UPGRADE_WARNING_ASK, UPGRADE_WARNING_PROCEED, UPGRADE_WARNING_CANCEL }; +static int upgradeWarning = UPGRADE_WARNING_NONE; static char unpackLog[4][256]; static void renderString(const char *c, int x, int y); @@ -37,6 +40,8 @@ static int unpackFiles(const char *archive, const char *script, const char *dele char fname2[PATH_MAX*2]; char buf[1024 * 4]; struct stat st; + const char *tarExtractCommand = "tar xz -C"; + char tarxz[PATH_MAX]; if( stat( archive, &st ) == 0 ) { @@ -46,7 +51,25 @@ static int unpackFiles(const char *archive, const char *script, const char *dele __android_log_print(ANDROID_LOG_INFO, "XSDL", "Unpacking data: total size %d Mb", unpackProgressMbTotal); } else - return 1; + { + if (strstr(archive, ".tar.gz") == archive + strlen(archive) - strlen(".tar.gz")) + { + strcpy(tarxz, archive); + strstr(tarxz, ".tar.gz")[5] = 'x'; // .tar.gz -> .tar.xz + if( stat( tarxz, &st ) == 0 ) + { + __android_log_print(ANDROID_LOG_INFO, "XSDL", "Found .tar.xz archive: %s", tarxz); + archive = tarxz; + tarExtractCommand = "tar xJ -C"; + unpackProgressMbTotal = st.st_size / 1024 / 1024; + if( unpackProgressMbTotal <= 0 ) + unpackProgressMbTotal = 1; + __android_log_print(ANDROID_LOG_INFO, "XSDL", "Unpacking data: total size %d Mb", unpackProgressMbTotal); + } + else + return 1; + } + } unpackProgressMb = 0; @@ -60,6 +83,12 @@ static int unpackFiles(const char *archive, const char *script, const char *dele if( strlen(deleteOldDataMarkerFile) > 0 && stat( fname, &st ) == 0 && stat( fname2, &st ) == 0 ) { + __android_log_print(ANDROID_LOG_INFO, "XSDL", "Upgrade detected, showing warning dialog"); + upgradeWarning = UPGRADE_WARNING_ASK; + while( upgradeWarning == UPGRADE_WARNING_ASK ) + SDL_Delay(200); + if( upgradeWarning == UPGRADE_WARNING_CANCEL ) + return 1; __android_log_print(ANDROID_LOG_INFO, "XSDL", "Deleting old installation..."); sprintf(unpackLog[0], "Deleting old installation..."); @@ -95,22 +124,11 @@ static int unpackFiles(const char *archive, const char *script, const char *dele system( fname ); - strcpy( fname, getenv("SECURE_STORAGE_DIR") ); - strcat( fname, "/../cache/busybox" ); - strcat( fname, " setsid " ); - strcat( fname, getenv("SECURE_STORAGE_DIR") ); - strcat( fname, "/../cache/busybox" ); - strcat( fname, " nohup " ); - strcat( fname, getenv("SECURE_STORAGE_DIR") ); - strcat( fname, "/../cache/busybox" ); - strcat( fname, " ash -c 'sleep 2 ; /system/bin/am start --user 0 -n " ); - strcat( fname, getenv("ANDROID_PACKAGE_NAME") ); - strcat( fname, "/.MainActivity'" ); - sprintf(unpackLog[0], "Restarting the app..."); __android_log_print(ANDROID_LOG_INFO, "XSDL", "Restarting the app: %s", fname); - popen( fname, "r" ); + SDL_ANDROID_OpenExternalApp(getenv("ANDROID_PACKAGE_NAME"), ".RestartMainActivity", NULL); + sleep(1); exit(0); } @@ -120,7 +138,9 @@ static int unpackFiles(const char *archive, const char *script, const char *dele strcpy( fname, getenv("SECURE_STORAGE_DIR") ); strcat( fname, "/busybox" ); - strcat( fname, " tar xz -C " ); + strcat( fname, " " ); + strcat( fname, tarExtractCommand ); + strcat( fname, " " ); strcat( fname, getenv("SECURE_STORAGE_DIR") ); FILE * fo = popen(fname, "w"); FILE * ff = fopen(archive, "rb"); @@ -273,6 +293,9 @@ void XSDL_unpackFiles() void * status; memset(unpackLog, 0, sizeof(unpackLog)); pthread_create(&thread_id, NULL, &unpackFilesThread, NULL); + int progress = 0; + enum {PROGRESS_WHEEL_NUM = 8}; + const char *progressWheel[PROGRESS_WHEEL_NUM] = { ";,,,,,,,", ",;,,,,,,", ",,;,,,,,", ",,,;,,,,", ",,,,;,,,", ",,,,,;,,", ",,,,,,;,", ",,,,,,,;" }; while (!unpackFinished) { @@ -282,8 +305,43 @@ void XSDL_unpackFiles() renderString(unpackLog[1], VID_X/2, VID_Y*3/8); renderString(unpackLog[2], VID_X/2, VID_Y*4/8); renderString(unpackLog[3], VID_X/2, VID_Y*5/8); + progress++; + renderString(progressWheel[progress % PROGRESS_WHEEL_NUM], VID_X/2, VID_Y*6/8); renderString("You may put this app to background while it's unpacking", VID_X/2, VID_Y*7/8); SDL_Flip(SDL_GetVideoSurface()); + int x, y; + while( upgradeWarning == UPGRADE_WARNING_ASK ) + { + char s[PATH_MAX]; + sprintf(s, "New update available for %s", getenv("ANDROID_APP_NAME")); + renderString(s, VID_X/2, VID_Y*2/8); + sprintf(s, "Please move all your %s files to SD card", getenv("ANDROID_APP_NAME")); + renderString(s, VID_X/2, VID_Y*3/8); + renderString("or they will be deleted during upgrade", VID_X/2, VID_Y*4/8); + renderString("Install now", VID_X/4, VID_Y*6/8); + renderString("Install later", VID_X*3/4, VID_Y*6/8); + SDL_Flip(SDL_GetVideoSurface()); + SDL_Event event; + while (SDL_PollEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_HELP) + upgradeWarning = UPGRADE_WARNING_CANCEL; + break; + case SDL_MOUSEBUTTONUP: + if( y > VID_Y*5/8 && y < VID_Y*7/8 ) + upgradeWarning = (x > VID_X/2) ? UPGRADE_WARNING_CANCEL : UPGRADE_WARNING_PROCEED; + break; + case SDL_JOYBALLMOTION: + x = event.jball.xrel; + y = event.jball.yrel; + break; + } + } + SDL_Delay(200); + } } pthread_join(thread_id, &status); diff --git a/project/jni/sdl-1.2/include/SDL_android.h b/project/jni/sdl-1.2/include/SDL_android.h index 43627f1f7..279e1920e 100644 --- a/project/jni/sdl-1.2/include/SDL_android.h +++ b/project/jni/sdl-1.2/include/SDL_android.h @@ -118,7 +118,9 @@ Returns 1 if load succeeded, 0 if user aborted sign-in, or there was no network */ extern DECLSPEC int SDLCALL SDL_ANDROID_CloudLoad(const char *filename, const char *saveId, const char *dialogTitle); -/* Open an Android web browser, or Chrome, or Youtube for video links */ +/* Open Android application, any parameter may be NULL */ +extern DECLSPEC void SDLCALL SDL_ANDROID_OpenExternalApp(const char *package, const char *activity, const char *data); +/* Open an Android web browser, or Chrome, or Youtube for video links. Just a wrapper for SDL_ANDROID_OpenExternalApp(NULL, NULL, url) */ extern DECLSPEC void SDLCALL SDL_ANDROID_OpenExternalWebBrowser(const char *url); #ifdef __cplusplus diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c index af72a9375..e393cac08 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c @@ -84,7 +84,7 @@ static jmethodID JavaSetAdvertisementPosition = NULL; static jmethodID JavaRequestNewAdvertisement = NULL; static jmethodID JavaRequestCloudSave = NULL; static jmethodID JavaRequestCloudLoad = NULL; -static jmethodID JavaRequestOpenExternalWebBrowser = NULL; +static jmethodID JavaRequestOpenExternalApp = NULL; static int glContextLost = 0; static int showScreenKeyboardDeferred = 0; static const char * showScreenKeyboardOldText = ""; @@ -356,7 +356,7 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject t "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;J)Z"); JavaRequestCloudLoad = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "cloudLoad", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z"); - JavaRequestOpenExternalWebBrowser = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "openExternalWebBrowser", "(Ljava/lang/String;)V"); + JavaRequestOpenExternalApp = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "openExternalApp", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V"); ANDROID_InitOSKeymap(); } @@ -571,13 +571,25 @@ int SDLCALL SDL_ANDROID_CloudLoad(const char *filename, const char *saveId, cons return result; } +void SDLCALL SDL_ANDROID_OpenExternalApp(const char *package, const char *activity, const char *data) +{ + (*JavaEnv)->PushLocalFrame(JavaEnv, 3); + jstring s1 = package ? (*JavaEnv)->NewStringUTF(JavaEnv, package) : NULL; + jstring s2 = activity ? (*JavaEnv)->NewStringUTF(JavaEnv, activity) : NULL; + jstring s3 = data ? (*JavaEnv)->NewStringUTF(JavaEnv, data) : NULL; + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestOpenExternalApp, s1, s2, s3 ); + if (s3) + (*JavaEnv)->DeleteLocalRef(JavaEnv, s3); + if (s2) + (*JavaEnv)->DeleteLocalRef(JavaEnv, s2); + if (s1) + (*JavaEnv)->DeleteLocalRef(JavaEnv, s1); + (*JavaEnv)->PopLocalFrame(JavaEnv, NULL); +} + void SDLCALL SDL_ANDROID_OpenExternalWebBrowser(const char *url) { - (*JavaEnv)->PushLocalFrame(JavaEnv, 1); - jstring s1 = (*JavaEnv)->NewStringUTF(JavaEnv, url); - (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestOpenExternalWebBrowser, s1 ); - (*JavaEnv)->DeleteLocalRef(JavaEnv, s1); - (*JavaEnv)->PopLocalFrame(JavaEnv, NULL); + SDL_ANDROID_OpenExternalApp(NULL, NULL, url); } // Dummy callback for SDL2 to satisfy linker diff --git a/project/res/raw/ultimatedroid.raw b/project/res/raw/ultimatedroid.raw index 56e9f4238..c86a54055 100644 Binary files a/project/res/raw/ultimatedroid.raw and b/project/res/raw/ultimatedroid.raw differ diff --git a/recordUserInput.sh b/recordUserInput.sh index 6bbd8959f..0817f0c98 100755 --- a/recordUserInput.sh +++ b/recordUserInput.sh @@ -1,16 +1,10 @@ #!/bin/sh -#if [ -z "$1" ]; then echo "Record user touch/key input, and replay it back via script" ; echo "Usage: $0 ScriptName.sh" ; exit ; fi - echo "#!/bin/sh" echo "# Record user touch/key input, and replay it back via script" echo "# Usage: $0 | tee ScriptName.sh ; chmod a+x ScriptName.sh ; ./ScriptName.sh" echo "# Press Ctrl-C when done" -#convert_input() { -#awk '{ if (($1 != "") && (substr($0,1,1)=="/")){ sub(":","",$1); printf("adb shell sendevent %s %d %d %d\n",$1,strtonum("0x"$2),strtonum("0x"$3),strtonum("0x"$4)); } }' -#} - CURTIME=0 export CURTIME