Added some platform specific API functions for Android:
authorSam Lantinga <slouken@libsdl.org>
Fri, 02 Nov 2012 02:22:32 -0700
changeset 6630 55910871076b
parent 6629 8e2c731103e6
child 6631 47ab7ba21530
Added some platform specific API functions for Android: SDL_AndroidGetJNIEnv() SDL_AndroidGetActivity() SDL_AndroidGetInternalStoragePath() SDL_AndroidGetExternalStorageState() SDL_AndroidGetExternalStoragePath()
include/SDL_system.h
src/core/android/SDL_android.cpp
--- a/include/SDL_system.h	Fri Nov 02 00:35:48 2012 -0700
+++ b/include/SDL_system.h	Fri Nov 02 02:22:32 2012 -0700
@@ -43,6 +43,11 @@
 /* *INDENT-ON* */
 #endif
 
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/*
+/* Platform specific functions for iOS 
+/*
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
 #if __IPHONEOS__
 
 extern DECLSPEC int SDLCALL SDL_iPhoneSetAnimationCallback(SDL_Window * window, int interval, void (*callback)(void*), void *callbackParam);
@@ -53,7 +58,47 @@
 #define SDL_iPhoneKeyboardToggle    SDL_ToggleScreenKeyboard
 #define SDL_iPhoneKeyboardIsShown   SDL_IsScreenKeyboardShown
 
-#endif
+#endif /* __IPHONEOS__ */
+
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+/*
+/* Platform specific functions for Android 
+/*
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#if __ANDROID__
+
+/* Get the JNI environment for the current thread
+   This returns JNIEnv*, but the prototype is void* so we don't need jni.h
+ */
+extern DECLSPEC void * SDLCALL SDL_AndroidGetJNIEnv();
+
+/* Get the SDL Activity object for the application
+   This returns jobject, but the prototype is void* so we don't need jni.h
+ */
+extern DECLSPEC void * SDLCALL SDL_AndroidGetActivity();
+
+/* See the official Android developer guide for more information:
+   http://developer.android.com/guide/topics/data/data-storage.html
+*/
+#define SDL_ANDROID_EXTERNAL_STORAGE_READ   0x01
+#define SDL_ANDROID_EXTERNAL_STORAGE_WRITE  0x02
+
+/* Get the path used for internal storage for this application */
+extern DECLSPEC const char * SDLCALL SDL_AndroidGetInternalStoragePath();
+
+/* Get the current state of external storage, a bitmask of these values:
+    SDL_ANDROID_EXTERNAL_STORAGE_READ
+    SDL_ANDROID_EXTERNAL_STORAGE_WRITE
+   If external storage is currently unavailable, this will return 0.
+*/
+extern DECLSPEC int SDLCALL SDL_AndroidGetExternalStorageState();
+
+/* Get the path used for external storage for this application */
+extern DECLSPEC const char * SDLCALL SDL_AndroidGetExternalStoragePath();
+
+#endif /* __ANDROID__ */
+
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
--- a/src/core/android/SDL_android.cpp	Fri Nov 02 00:35:48 2012 -0700
+++ b/src/core/android/SDL_android.cpp	Fri Nov 02 02:22:32 2012 -0700
@@ -24,6 +24,7 @@
 
 #ifdef __ANDROID__
 
+#include "SDL_system.h"
 #include "SDL_android.h"
 
 extern "C" {
@@ -963,8 +964,6 @@
 
 /*extern "C" int Android_JNI_HideTextInput()
 {
-
-
     JNIEnv *env = Android_JNI_GetEnv();
     if (!env) {
         return -1;
@@ -978,6 +977,155 @@
     return 0;
 }*/
 
+//////////////////////////////////////////////////////////////////////////////
+//
+// Functions exposed to SDL applications in SDL_system.h
+//
+
+extern "C" void *SDL_AndroidGetJNIEnv()
+{
+    return Android_JNI_GetEnv();
+}
+
+extern "C" void *SDL_AndroidGetActivity()
+{
+    LocalReferenceHolder refs;
+    jmethodID mid;
+
+    JNIEnv *env = Android_JNI_GetEnv();
+    if (!refs.init(env)) {
+        return NULL;
+    }
+
+    // return SDLActivity.getContext();
+    mid = env->GetStaticMethodID(mActivityClass,
+            "getContext","()Landroid/content/Context;");
+    return env->CallStaticObjectMethod(mActivityClass, mid);
+}
+
+extern "C" const char * SDL_AndroidGetInternalStoragePath()
+{
+    static char *s_AndroidInternalFilesPath = NULL;
+
+    if (!s_AndroidInternalFilesPath) {
+        LocalReferenceHolder refs;
+        jmethodID mid;
+        jobject context;
+        jobject fileObject;
+        jstring pathString;
+        const char *path;
+
+        JNIEnv *env = Android_JNI_GetEnv();
+        if (!refs.init(env)) {
+            return NULL;
+        }
+
+        // context = SDLActivity.getContext();
+        mid = env->GetStaticMethodID(mActivityClass,
+                "getContext","()Landroid/content/Context;");
+        context = env->CallStaticObjectMethod(mActivityClass, mid);
+
+        // fileObj = context.getFilesDir();
+        mid = env->GetMethodID(env->GetObjectClass(context),
+                "getFilesDir", "()Ljava/io/File;");
+        fileObject = env->CallObjectMethod(context, mid);
+        if (!fileObject) {
+            SDL_SetError("Couldn't get internal directory");
+            return NULL;
+        }
+
+        // path = fileObject.getAbsolutePath();
+        mid = env->GetMethodID(env->GetObjectClass(fileObject),
+                "getAbsolutePath", "()Ljava/lang/String;");
+        pathString = (jstring)env->CallObjectMethod(fileObject, mid);
+
+        path = env->GetStringUTFChars(pathString, NULL);
+        s_AndroidInternalFilesPath = SDL_strdup(path);
+        env->ReleaseStringUTFChars(pathString, path);
+    }
+    return s_AndroidInternalFilesPath;
+}
+
+extern "C" int SDL_AndroidGetExternalStorageState()
+{
+    LocalReferenceHolder refs;
+    jmethodID mid;
+    jclass cls;
+    jstring stateString;
+    const char *state;
+    int stateFlags;
+
+    JNIEnv *env = Android_JNI_GetEnv();
+    if (!refs.init(env)) {
+        return 0;
+    }
+
+    cls = env->FindClass("android/os/Environment");
+    mid = env->GetStaticMethodID(cls,
+            "getExternalStorageState", "()Ljava/lang/String;");
+    stateString = (jstring)env->CallStaticObjectMethod(cls, mid);
+
+    state = env->GetStringUTFChars(stateString, NULL);
+
+    // Print an info message so people debugging know the storage state
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "external storage state: %s", state);
+
+    if (SDL_strcmp(state, "mounted") == 0) {
+        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ |
+                     SDL_ANDROID_EXTERNAL_STORAGE_WRITE;
+    } else if (SDL_strcmp(state, "mounted_ro") == 0) {
+        stateFlags = SDL_ANDROID_EXTERNAL_STORAGE_READ;
+    } else {
+        stateFlags = 0;
+    }
+    env->ReleaseStringUTFChars(stateString, state);
+
+    return stateFlags;
+}
+
+extern "C" const char * SDL_AndroidGetExternalStoragePath()
+{
+    static char *s_AndroidExternalFilesPath = NULL;
+
+    if (!s_AndroidExternalFilesPath) {
+        LocalReferenceHolder refs;
+        jmethodID mid;
+        jobject context;
+        jobject fileObject;
+        jstring pathString;
+        const char *path;
+
+        JNIEnv *env = Android_JNI_GetEnv();
+        if (!refs.init(env)) {
+            return NULL;
+        }
+
+        // context = SDLActivity.getContext();
+        mid = env->GetStaticMethodID(mActivityClass,
+                "getContext","()Landroid/content/Context;");
+        context = env->CallStaticObjectMethod(mActivityClass, mid);
+
+        // fileObj = context.getExternalFilesDir();
+        mid = env->GetMethodID(env->GetObjectClass(context),
+                "getExternalFilesDir", "(Ljava/lang/String;)Ljava/io/File;");
+        fileObject = env->CallObjectMethod(context, mid, NULL);
+        if (!fileObject) {
+            SDL_SetError("Couldn't get external directory");
+            return NULL;
+        }
+
+        // path = fileObject.getAbsolutePath();
+        mid = env->GetMethodID(env->GetObjectClass(fileObject),
+                "getAbsolutePath", "()Ljava/lang/String;");
+        pathString = (jstring)env->CallObjectMethod(fileObject, mid);
+
+        path = env->GetStringUTFChars(pathString, NULL);
+        s_AndroidExternalFilesPath = SDL_strdup(path);
+        env->ReleaseStringUTFChars(pathString, path);
+    }
+    return s_AndroidExternalFilesPath;
+}
+
 #endif /* __ANDROID__ */
 
 /* vi: set ts=4 sw=4 expandtab: */