Fixed bug 3917 - Android, issues with getManifestEnvironmentVariable We're going to push the manifest environment variables from the Java side instead of continually querying for them from the native side.
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 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
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 c5520f8..be8aecc 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
@@ -512,6 +512,8 @@ public class SDLActivity extends Activity {
public static native void onNativeSurfaceChanged();
public static native void onNativeSurfaceDestroyed();
public static native String nativeGetHint(String name);
+ public static native void nativeSetenv(String name, String value);
+ public static native void nativeEnvironmentVariablesSet();
/**
* This method is called by SDL using JNI.
@@ -616,23 +618,25 @@ public class SDLActivity extends Activity {
/**
* This method is called by SDL using JNI.
*/
- public static String getManifestEnvironmentVariable(String variableName) {
+ public static void getManifestEnvironmentVariables() {
try {
ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
- if (applicationInfo.metaData == null) {
- return null;
+ Bundle bundle = applicationInfo.metaData;
+ if (bundle == null) {
+ return;
}
-
- String key = "SDL_ENV." + variableName;
- if (!applicationInfo.metaData.containsKey(key)) {
- return null;
+ String prefix = "SDL_ENV.";
+ final int trimLength = prefix.length();
+ for (String key : bundle.keySet()) {
+ if (key.startsWith(prefix)) {
+ String name = key.substring(trimLength);
+ String value = bundle.get(key).toString();
+ nativeSetenv(name, value);
+ }
}
-
- return applicationInfo.metaData.get(key).toString();
- }
- catch (PackageManager.NameNotFoundException e)
- {
- return null;
+ nativeEnvironmentVariablesSet();
+ } catch (Exception e) {
+ Log.v("SDL", "exception " + e.toString());
}
}
diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c
index 04a5f24..28f9a19 100644
--- a/src/core/android/SDL_android.c
+++ b/src/core/android/SDL_android.c
@@ -128,6 +128,13 @@ JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
JNIEnv* env, jclass cls,
jstring name);
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
+ JNIEnv* env, jclass cls,
+ jstring name, jstring value);
+
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)(
+ JNIEnv* env, jclass cls);
+
/* Java class SDLInputConnection */
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
JNIEnv* env, jclass cls,
@@ -213,7 +220,7 @@ static jmethodID midClipboardSetText;
static jmethodID midClipboardGetText;
static jmethodID midClipboardHasText;
static jmethodID midOpenAPKExpansionInputStream;
-static jmethodID midGetManifestEnvironmentVariable;
+static jmethodID midGetManifestEnvironmentVariables;
static jmethodID midGetDisplayDPI;
/* audio manager */
@@ -244,6 +251,8 @@ static jfieldID fidSeparateMouseAndTouch;
static float fLastAccelerometer[3];
static SDL_bool bHasNewData;
+static SDL_bool bHasEnvironmentVariables;
+
/*******************************************************************************
Functions called by JNI
*******************************************************************************/
@@ -314,16 +323,16 @@ 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;");
+ midGetManifestEnvironmentVariables = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
+ "getManifestEnvironmentVariables", "()V");
midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;");
if (!midGetNativeSurface ||
!midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds ||
- !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
+ !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
!midClipboardSetText || !midClipboardGetText || !midClipboardHasText ||
- !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariable || !midGetDisplayDPI) {
+ !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables|| !midGetDisplayDPI) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?");
}
@@ -808,6 +817,26 @@ JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
return result;
}
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)(
+ JNIEnv* env, jclass cls,
+ jstring name, jstring value)
+{
+ const char *utfname = (*env)->GetStringUTFChars(env, name, NULL);
+ const char *utfvalue = (*env)->GetStringUTFChars(env, value, NULL);
+
+ SDL_setenv(utfname, utfvalue, 1);
+
+ (*env)->ReleaseStringUTFChars(env, name, utfname);
+ (*env)->ReleaseStringUTFChars(env, value, utfvalue);
+
+}
+
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)(
+ JNIEnv* env, jclass cls)
+{
+ bHasEnvironmentVariables = SDL_TRUE;
+}
+
/*******************************************************************************
Functions called by SDL into Java
*******************************************************************************/
@@ -2105,40 +2134,17 @@ 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)
+void Android_JNI_GetManifestEnvironmentVariables(void)
{
- 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));
- (*env)->DeleteLocalRef(env, jVariableName);
-
- if (jResult == NULL) {
- return NULL;
+ if (!mActivityClass || !midGetManifestEnvironmentVariables) {
+ __android_log_print(ANDROID_LOG_WARN, "SDL", "Request to get environment variables before JNI is ready");
+ return;
}
- if (SDL_AndroidEnvMem) {
- SDL_free(SDL_AndroidEnvMem);
- SDL_AndroidEnvMem = NULL;
+ if (!bHasEnvironmentVariables) {
+ JNIEnv *env = Android_JNI_GetEnv();
+ (*env)->CallStaticVoidMethod(env, mActivityClass, midGetManifestEnvironmentVariables);
}
-
- 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__ */
diff --git a/src/core/android/SDL_android.h b/src/core/android/SDL_android.h
index 06d40e2..4e7acbe 100644
--- a/src/core/android/SDL_android.h
+++ b/src/core/android/SDL_android.h
@@ -62,7 +62,7 @@ size_t Android_JNI_FileWrite(SDL_RWops* ctx, const void* buffer, size_t size, si
int Android_JNI_FileClose(SDL_RWops* ctx);
/* Environment support */
-char *SDL_AndroidGetManifestEnvironmentVariable(const char *variableName);
+void Android_JNI_GetManifestEnvironmentVariables(void);
/* Clipboard support */
int Android_JNI_SetClipboardText(const char* text);
diff --git a/src/stdlib/SDL_getenv.c b/src/stdlib/SDL_getenv.c
index f24e4c0..ddb2e1e 100644
--- a/src/stdlib/SDL_getenv.c
+++ b/src/stdlib/SDL_getenv.c
@@ -171,23 +171,17 @@ SDL_setenv(const char *name, const char *value, int overwrite)
#endif
/* Retrieve a variable named "name" from the environment */
-#if defined(__ANDROID__)
+#if defined(HAVE_GETENV)
char *
SDL_getenv(const char *name)
{
- /* Input validation */
- if (!name || SDL_strlen(name)==0) {
- return NULL;
- }
+#if defined(__ANDROID__)
+ /* Make sure variables from the application manifest are available */
+ Android_JNI_GetManifestEnvironmentVariables();
+#endif
- return SDL_AndroidGetManifestEnvironmentVariable(name);
-}
-#elif defined(HAVE_GETENV)
-char *
-SDL_getenv(const char *name)
-{
/* Input validation */
- if (!name || SDL_strlen(name)==0) {
+ if (!name || !*name) {
return NULL;
}