Navigation Menu

Skip to content

Commit

Permalink
Merged changes from Alexey Petruchik to support Android obb files
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Jun 22, 2014
2 parents f448815 + 25313c3 commit e8d84fb
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
52 changes: 50 additions & 2 deletions android-project/src/org/libsdl/app/SDLActivity.java
@@ -1,10 +1,13 @@
package org.libsdl.app;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.lang.reflect.Method;

import android.app.*;
import android.content.*;
Expand All @@ -20,7 +23,6 @@
import android.media.*;
import android.hardware.*;


/**
SDL Activity
*/
Expand Down Expand Up @@ -296,6 +298,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 nativeGetHint(String name);

/**
* This method is called by SDL using JNI.
Expand Down Expand Up @@ -531,7 +534,52 @@ public static void pollInputDevices() {
mJoystickHandler.pollInputDevices();
}
}


// APK extension files support

/** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */
private Object expansionFile;

/** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */
private Method expansionFileMethod;

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(nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"));
Integer patchVersion = Integer.parseInt(nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION"));

try {
// To avoid direct dependency on Google APK extension library that is
// not a part of Android SDK we access it using reflection
expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport")
.getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class)
.invoke(null, this, mainVersion, patchVersion);

expansionFileMethod = expansionFile.getClass()
.getMethod("getInputStream", String.class);
} catch (Exception ex) {
ex.printStackTrace();
expansionFile = null;
expansionFileMethod = null;
}
}

// Get an input stream for a known file inside the expansion file ZIPs
InputStream fileStream;
try {
fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName);
} catch (Exception ex) {
ex.printStackTrace();
fileStream = null;
}

if (fileStream == null) {
throw new IOException();
}

return fileStream;
}
}

/**
Expand Down
10 changes: 10 additions & 0 deletions include/SDL_hints.h
Expand Up @@ -457,6 +457,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_PATCH_FILE_VERSION"


/**
* \brief An enumeration of hint priorities
Expand Down
17 changes: 16 additions & 1 deletion src/core/android/SDL_android.c
Expand Up @@ -385,7 +385,15 @@ JNIEXPORT void JNICALL Java_org_libsdl_app_SDLInputConnection_nativeSetComposing
(*env)->ReleaseStringUTFChars(env, text, utftext);
}

jstring Java_org_libsdl_app_SDLActivity_nativeGetHint(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
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit e8d84fb

Please sign in to comment.