From 612f4a69dbf0cc5ecb4bc45d74033fac4d11f3c8 Mon Sep 17 00:00:00 2001 From: stopiccot Date: Mon, 7 Apr 2014 21:20:39 +0300 Subject: [PATCH] inital apk extension support --- .../src/org/libsdl/app/SDLActivity.java | 28 ++++++++++++++++++- include/SDL_hints.h | 10 +++++++ src/core/android/SDL_android.c | 17 ++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java index c5714eeea617c..b4c6569e25a5f 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.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 static native int nativeAddJoystick(int device_id, String name, 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 static void pollInputDevices() { 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 ec38e8c740315..46ebef048533a 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 d806208e75763..555c4edbc3f78 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 @@ static int Internal_Android_JNI_FileOpen(SDL_RWops* ctx) "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);