Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Added the ability to set SDL hints from AndroidManifest.xml (thanks R…
…achel!)

This is especially useful for things like the accelerometer hint which could be needed before application main().
  • Loading branch information
slouken committed Oct 24, 2017
1 parent 4553671 commit 8fd0c22
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 2 deletions.
4 changes: 4 additions & 0 deletions android-project/app/src/main/AndroidManifest.xml
Expand Up @@ -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" />

Expand Down
25 changes: 25 additions & 0 deletions android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
Expand Up @@ -24,6 +24,8 @@
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
Expand Down Expand Up @@ -613,6 +615,29 @@ public static Context getContext() {
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
Expand Down
41 changes: 40 additions & 1 deletion src/core/android/SDL_android.c
Expand Up @@ -211,6 +211,7 @@ static jmethodID midClipboardSetText;
static jmethodID midClipboardGetText;
static jmethodID midClipboardHasText;
static jmethodID midOpenAPKExpansionInputStream;
static jmethodID midGetManifestEnvironmentVariable;

/* audio manager */
static jclass mAudioManagerClass;
Expand Down Expand Up @@ -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?");
}

Expand Down Expand Up @@ -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: */
3 changes: 3 additions & 0 deletions src/core/android/SDL_android.h
Expand Up @@ -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);
Expand Down
17 changes: 16 additions & 1 deletion src/stdlib/SDL_getenv.c
Expand Up @@ -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))
Expand Down Expand Up @@ -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)
{
Expand Down

0 comments on commit 8fd0c22

Please sign in to comment.