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.
This commit is contained in:
Sam Lantinga 2017-11-04 09:37:29 -07:00
parent 7334a2a1b5
commit 758156a765
4 changed files with 67 additions and 63 deletions

View file

@ -512,6 +512,8 @@ public class SDLActivity extends Activity {
public static native void onNativeSurfaceChanged(); public static native void onNativeSurfaceChanged();
public static native void onNativeSurfaceDestroyed(); public static native void onNativeSurfaceDestroyed();
public static native String nativeGetHint(String name); 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. * 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. * This method is called by SDL using JNI.
*/ */
public static String getManifestEnvironmentVariable(String variableName) { public static void getManifestEnvironmentVariables() {
try { try {
ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA); ApplicationInfo applicationInfo = getContext().getPackageManager().getApplicationInfo(getContext().getPackageName(), PackageManager.GET_META_DATA);
if (applicationInfo.metaData == null) { Bundle bundle = applicationInfo.metaData;
return null; if (bundle == null) {
return;
} }
String prefix = "SDL_ENV.";
String key = "SDL_ENV." + variableName; final int trimLength = prefix.length();
if (!applicationInfo.metaData.containsKey(key)) { for (String key : bundle.keySet()) {
return null; 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) nativeEnvironmentVariablesSet();
{ } catch (Exception e) {
return null; Log.v("SDL", "exception " + e.toString());
} }
} }

View file

@ -128,6 +128,13 @@ JNIEXPORT jstring JNICALL SDL_JAVA_INTERFACE(nativeGetHint)(
JNIEnv* env, jclass cls, JNIEnv* env, jclass cls,
jstring name); 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 */ /* Java class SDLInputConnection */
JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)(
JNIEnv* env, jclass cls, JNIEnv* env, jclass cls,
@ -213,7 +220,7 @@ static jmethodID midClipboardSetText;
static jmethodID midClipboardGetText; static jmethodID midClipboardGetText;
static jmethodID midClipboardHasText; static jmethodID midClipboardHasText;
static jmethodID midOpenAPKExpansionInputStream; static jmethodID midOpenAPKExpansionInputStream;
static jmethodID midGetManifestEnvironmentVariable; static jmethodID midGetManifestEnvironmentVariables;
static jmethodID midGetDisplayDPI; static jmethodID midGetDisplayDPI;
/* audio manager */ /* audio manager */
@ -244,6 +251,8 @@ static jfieldID fidSeparateMouseAndTouch;
static float fLastAccelerometer[3]; static float fLastAccelerometer[3];
static SDL_bool bHasNewData; static SDL_bool bHasNewData;
static SDL_bool bHasEnvironmentVariables;
/******************************************************************************* /*******************************************************************************
Functions called by JNI Functions called by JNI
*******************************************************************************/ *******************************************************************************/
@ -314,8 +323,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
midOpenAPKExpansionInputStream = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, midOpenAPKExpansionInputStream = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"openAPKExpansionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;"); "openAPKExpansionInputStream", "(Ljava/lang/String;)Ljava/io/InputStream;");
midGetManifestEnvironmentVariable = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, midGetManifestEnvironmentVariables = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass,
"getManifestEnvironmentVariable", "(Ljava/lang/String;)Ljava/lang/String;"); "getManifestEnvironmentVariables", "()V");
midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;");
@ -323,7 +332,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c
!midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds || !midSetActivityTitle || !midSetOrientation || !midGetContext || !midInputGetInputDeviceIds ||
!midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown ||
!midClipboardSetText || !midClipboardGetText || !midClipboardHasText || !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?"); __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; 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 Functions called by SDL into Java
*******************************************************************************/ *******************************************************************************/
@ -2105,40 +2134,17 @@ const char * SDL_AndroidGetExternalStoragePath(void)
return s_AndroidExternalFilesPath; return s_AndroidExternalFilesPath;
} }
// Ugh, but we have to SDL_strdup() our result to pass it safely back void Android_JNI_GetManifestEnvironmentVariables(void)
// 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)) { if (!mActivityClass || !midGetManifestEnvironmentVariables) {
__android_log_print(ANDROID_LOG_WARN, "SDL", "request to get environment variable before JNI is ready: %s", variableName); __android_log_print(ANDROID_LOG_WARN, "SDL", "Request to get environment variables before JNI is ready");
return NULL; return;
} }
if (!bHasEnvironmentVariables) {
JNIEnv *env = Android_JNI_GetEnv(); JNIEnv *env = Android_JNI_GetEnv();
(*env)->CallStaticVoidMethod(env, mActivityClass, midGetManifestEnvironmentVariables);
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 (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__ */ #endif /* __ANDROID__ */

View file

@ -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); int Android_JNI_FileClose(SDL_RWops* ctx);
/* Environment support */ /* Environment support */
char *SDL_AndroidGetManifestEnvironmentVariable(const char *variableName); void Android_JNI_GetManifestEnvironmentVariables(void);
/* Clipboard support */ /* Clipboard support */
int Android_JNI_SetClipboardText(const char* text); int Android_JNI_SetClipboardText(const char* text);

View file

@ -171,23 +171,17 @@ SDL_setenv(const char *name, const char *value, int overwrite)
#endif #endif
/* Retrieve a variable named "name" from the environment */ /* Retrieve a variable named "name" from the environment */
#if defined(HAVE_GETENV)
char *
SDL_getenv(const char *name)
{
#if defined(__ANDROID__) #if defined(__ANDROID__)
char * /* Make sure variables from the application manifest are available */
SDL_getenv(const char *name) Android_JNI_GetManifestEnvironmentVariables();
{ #endif
/* Input validation */
if (!name || SDL_strlen(name)==0) {
return NULL;
}
return SDL_AndroidGetManifestEnvironmentVariable(name);
}
#elif defined(HAVE_GETENV)
char *
SDL_getenv(const char *name)
{
/* Input validation */ /* Input validation */
if (!name || SDL_strlen(name)==0) { if (!name || !*name) {
return NULL; return NULL;
} }