inital apk extension support
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java
index c5714ee..b4c6569 100644
--- a/android-project/src/org/libsdl/app/SDLActivity.java
+++ b/android-project/src/org/libsdl/app/SDLActivity.java
@@ -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.graphics.*;
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 @@ public class SDLActivity extends Activity {
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 @@ public class SDLActivity extends Activity {
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;
+ }
}
/**
diff --git a/include/SDL_hints.h b/include/SDL_hints.h
index ec38e8c..46ebef0 100644
--- a/include/SDL_hints.h
+++ b/include/SDL_hints.h
@@ -435,6 +435,16 @@ extern "C" {
*/
#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
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index d806208..555c4ed 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -385,7 +385,15 @@ void Java_org_libsdl_app_SDLInputConnection_nativeSetComposingText(
(*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 @@ fallback:
"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);