Added the ability to set SDL hints from AndroidManifest.xml (thanks Rachel!) This is especially useful for things like the accelerometer hint which could be needed before application main().
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml
index ca5cdf3..0116491 100644
--- a/android-project/app/src/main/AndroidManifest.xml
+++ b/android-project/app/src/main/AndroidManifest.xml
@@ -8,6 +8,10 @@
android:versionName="1.0"
android:installLocation="auto">
+ <!-- Example of setting SDL hints from AndroidManifest.xml:
+ <meta-data android:value="0" android:name="SDL_ENV.SDL_ACCELEROMETER_AS_JOYSTICK"/>
+ -->
+
<!-- Android 4.0.1 -->
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="16" />
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index 7807fc7..5d2ef4a 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -24,6 +24,8 @@ import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.hardware.*;
import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ApplicationInfo;
/**
SDL Activity
@@ -613,6 +615,29 @@ public class SDLActivity extends Activity {
return SDL.getContext();
}
+ /**
+ * This method is called by SDL using JNI.
+ */
+ public static String getManifestEnvironmentVariable(String variableName) {
+ try {
+ ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
+ if (applicationInfo.metaData == null) {
+ return null;
+ }
+
+ String key = "SDL_ENV." + variableName;
+ if (!applicationInfo.metaData.containsKey(key)) {
+ return null;
+ }
+
+ return applicationInfo.metaData.get(key).toString();
+ }
+ catch (PackageManager.NameNotFoundException e)
+ {
+ return null;
+ }
+ }
+
static class ShowTextInputTask implements Runnable {
/*
* This is used to regulate the pan&scan method to have some offset from
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index 48cf7b7..c3a9ba5 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -211,6 +211,7 @@ static jmethodID midClipboardSetText;
static jmethodID midClipboardGetText;
static jmethodID midClipboardHasText;
static jmethodID midOpenAPKExpansionInputStream;
+static jmethodID midGetManifestEnvironmentVariable;
/* audio manager */
static jclass mAudioManagerClass;
@@ -310,11 +311,14 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
midOpenAPKExpansionInputStream = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"openAPKExpansionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;");
+ midGetManifestEnvironmentVariable = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+ "getManifestEnvironmentVariable", "(Ljava/lang/String;)Ljava/lang/String;");
+
if (!midGetNativeSurface ||
!midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds ||
!midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
!midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
- !midOpenAPKExpansionInputStream) {
+ !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariable) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
}
@@ -2034,6 +2038,41 @@ const char * SDL_AndroidGetExternalStoragePath(void)
return s_AndroidExternalFilesPath;
}
+// Ugh, but we have to SDL_strdup() our result to pass it safely back
+// out into normal SDL_getenv flow. So we'll just do the same sort
+// of trick as on Win32 over in SDL_getenv.c.
+char *SDL_AndroidEnvMem;
+
+char *SDL_AndroidGetManifestEnvironmentVariable(const char *variableName)
+{
+ if ((mActivityClass == NULL) || (midGetManifestEnvironmentVariable == 0)) {
+ __android_log_print(ANDROID_LOG_WARN, "SDL", "request to get environment variable before JNI is ready: %s", variableName);
+ return NULL;
+ }
+
+ JNIEnv *env = Android_JNI_GetEnv();
+
+ jstring jVariableName = (*env)->NewStringUTF(env, variableName);
+ jstring jResult = (jstring)((*env)->CallStaticObjectMethod(env, mActivityClass, midGetManifestEnvironmentVariable, jVariableName));
+
+ if (jResult == NULL) {
+ return NULL;
+ }
+
+ if (SDL_AndroidEnvMem) {
+ SDL_free(SDL_AndroidEnvMem);
+ SDL_AndroidEnvMem = NULL;
+ }
+
+ const char *result = (*env)->GetStringUTFChars(env, jResult, NULL);
+ SDL_AndroidEnvMem = SDL_strdup(result);
+ (*env)->ReleaseStringUTFChars(env, jResult, result);
+ (*env)->DeleteLocalRef(env, jResult);
+
+ __android_log_print(ANDROID_LOG_INFO, "SDL", "environment variable in metadata: %s = %s", variableName, SDL_AndroidEnvMem);
+ return SDL_AndroidEnvMem;
+}
+
#endif /* __ANDROID__ */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index e0ae7b5..1d7e81a 100644
--- a/src/core/android/SDL_android.h
+++ b/src/core/android/SDL_android.h
@@ -59,6 +59,9 @@ size_t Android_JNI_FileRead(SDL_RWops* ctx, void* buffer, size_t size, size_t ma
size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, size_t size, size_t num);
int Android_JNI_FileClose(SDL_RWops* ctx);
+/* Environment support */
+char *SDL_AndroidGetManifestEnvironmentVariable(const char *variableName);
+
/* Clipboard support */
int Android_JNI_SetClipboardText(const char* text);
char* Android_JNI_GetClipboardText(void);
diff --git a/src/stdlib/SDL_getenv.c b/src/stdlib/SDL_getenv.c
index 305307f..f24e4c0 100644
--- a/src/stdlib/SDL_getenv.c
+++ b/src/stdlib/SDL_getenv.c
@@ -29,6 +29,10 @@
#include "../core/windows/SDL_windows.h"
#endif
+#if defined(__ANDROID__)
+#include "../core/android/SDL_android.h"
+#endif
+
#include "SDL_stdinc.h"
#if defined(__WIN32__) && (!defined(HAVE_SETENV) || !defined(HAVE_GETENV))
@@ -167,7 +171,18 @@ SDL_setenv(const char *name, const char *value, int overwrite)
#endif
/* Retrieve a variable named "name" from the environment */
-#if defined(HAVE_GETENV)
+#if defined(__ANDROID__)
+char *
+SDL_getenv(const char *name)
+{
+ /* Input validation */
+ if (!name || SDL_strlen(name)==0) {
+ return NULL;
+ }
+
+ return SDL_AndroidGetManifestEnvironmentVariable(name);
+}
+#elif defined(HAVE_GETENV)
char *
SDL_getenv(const char *name)
{