inital apk extension support apk
authorstopiccot <alexey.petruchik@gmail.com>
Mon, 07 Apr 2014 21:20:39 +0300
branchapk
changeset 8896 d931167c375a
parent 8697 abf45e1abfe3
child 8897 fff9c0b9f1fb
inital apk extension support
android-project/src/org/libsdl/app/SDLActivity.java
include/SDL_hints.h
src/core/android/SDL_android.c
--- a/android-project/src/org/libsdl/app/SDLActivity.java	Sat Apr 05 16:25:30 2014 -0700
+++ b/android-project/src/org/libsdl/app/SDLActivity.java	Mon Apr 07 21:20:39 2014 +0300
@@ -1,5 +1,7 @@
 package org.libsdl.app;
 
+import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -20,6 +22,8 @@
 import android.media.*;
 import android.hardware.*;
 
+import com.android.vending.expansion.zipfile.APKExpansionSupport;
+import com.android.vending.expansion.zipfile.ZipResourceFile;
 
 /**
     SDL Activity
@@ -296,6 +300,7 @@
                                                int is_accelerometer, int nbuttons, 
                                                int naxes, int nhats, int nballs);
     public static native int nativeRemoveJoystick(int device_id);
+    public static native String getHint(String name);
 
     public static void flipBuffers() {
         SDLActivity.nativeFlipBuffers();
@@ -495,7 +500,28 @@
             mJoystickHandler.pollInputDevices();
         }
     }
-    
+
+    // APK extension files support
+    private ZipResourceFile expansionFile = null;
+
+    public InputStream openAPKExtensionInputStream(String fileName) throws IOException {
+        // Get a ZipResourceFile representing a merger of both the main and patch files
+        if (expansionFile == null) {
+            Integer mainVersion = Integer.parseInt(getHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"));
+            Integer patchVersion = Integer.parseInt(getHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"));
+
+            expansionFile = APKExpansionSupport.getAPKExpansionZipFile(this, mainVersion, patchVersion);
+        }
+
+        // Get an input stream for a known file inside the expansion file ZIPs
+        InputStream fileStream = expansionFile.getInputStream(fileName);
+
+        if (fileStream == null) {
+            throw new IOException();
+        }
+
+        return fileStream;
+    }
 }
 
 /**
--- a/include/SDL_hints.h	Sat Apr 05 16:25:30 2014 -0700
+++ b/include/SDL_hints.h	Mon Apr 07 21:20:39 2014 +0300
@@ -435,6 +435,16 @@
  */
 #define SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES    "SDL_VIDEO_MAC_FULLSCREEN_SPACES"
 
+/**
+ * \brief Android APK expansion main file version. Should be a string number like "1", "2" etc.
+ */
+#define SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"
+ 
+/**
+ * \brief Android APK expansion patch file version. Should be a string number like "1", "2" etc.
+ */
+#define SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION "SDL_ANDROID_APK_EXPANSION_MAIN_PATCH_VERSION"
+
 
 /**
  *  \brief  An enumeration of hint priorities
--- a/src/core/android/SDL_android.c	Sat Apr 05 16:25:30 2014 -0700
+++ b/src/core/android/SDL_android.c	Mon Apr 07 21:20:39 2014 +0300
@@ -385,7 +385,15 @@
     (*env)->ReleaseStringUTFChars(env, text, utftext);
 }
 
+jstring Java_org_libsdl_app_SDLActivity_getHint(JNIEnv* env, jclass cls, jstring name) {
+    const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
+    const char *hint = SDL_GetHint(utfname);
 
+    jstring result = (*env)->NewStringUTF(env, hint);
+    (*env)->ReleaseStringUTFChars(env, name, utfname);
+
+    return result;
+}
 
 /*******************************************************************************
              Functions called by SDL into Java
@@ -758,7 +766,14 @@
                 "open", "(Ljava/lang/String;I)Ljava/io/InputStream;");
         inputStream = (*mEnv)->CallObjectMethod(mEnv, assetManager, mid, fileNameJString, 1 /* ACCESS_RANDOM */);
         if (Android_JNI_ExceptionOccurred(false)) {
-            goto failure;
+            // Try fallback to APK Extension files
+            mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context),
+                "openAPKExtensionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;");
+            inputStream = (*mEnv)->CallObjectMethod(mEnv, context, mid, fileNameJString);
+
+            if (Android_JNI_ExceptionOccurred(false)) {
+                goto failure;
+            }
         }
 
         ctx->hidden.androidio.inputStreamRef = (*mEnv)->NewGlobalRef(mEnv, inputStream);