Android: factorize asset manager code (bug 2131 and 4297)

This commit is contained in:
Sylvain Becker 2020-05-08 11:00:51 +02:00
parent fa23e3d00b
commit 0059ace0b4
1 changed files with 69 additions and 35 deletions

View File

@ -356,6 +356,12 @@ static SDL_bool bHasEnvironmentVariables;
static SDL_atomic_t bPermissionRequestPending; static SDL_atomic_t bPermissionRequestPending;
static SDL_bool bPermissionRequestResult; static SDL_bool bPermissionRequestResult;
/* Android AssetManager */
static void Internal_Android_Create_AssetManager(void);
static void Internal_Android_Destroy_AssetManager(void);
static AAssetManager *asset_manager = NULL;
static jobject javaAssetManagerRef = 0;
/******************************************************************************* /*******************************************************************************
Functions called by JNI Functions called by JNI
*******************************************************************************/ *******************************************************************************/
@ -1177,6 +1183,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeQuit)(
Android_ResumeSem = NULL; Android_ResumeSem = NULL;
} }
Internal_Android_Destroy_AssetManager();
str = SDL_GetError(); str = SDL_GetError();
if (str && str[0]) { if (str && str[0]) {
__android_log_print(ANDROID_LOG_ERROR, "SDL", "SDLActivity thread ends (error=%s)", str); __android_log_print(ANDROID_LOG_ERROR, "SDL", "SDLActivity thread ends (error=%s)", str);
@ -1799,6 +1807,53 @@ static SDL_bool Android_JNI_ExceptionOccurred(SDL_bool silent)
return SDL_FALSE; return SDL_FALSE;
} }
static void Internal_Android_Create_AssetManager() {
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
JNIEnv *env = Android_JNI_GetEnv();
jmethodID mid;
jobject context;
jobject javaAssetManager;
if (!LocalReferenceHolder_Init(&refs, env)) {
LocalReferenceHolder_Cleanup(&refs);
return;
}
/* context = SDLActivity.getContext(); */
context = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext);
/* javaAssetManager = context.getAssets(); */
mid = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, context),
"getAssets", "()Landroid/content/res/AssetManager;");
javaAssetManager = (*env)->CallObjectMethod(env, context, mid);
/**
* Given a Dalvik AssetManager object, obtain the corresponding native AAssetManager
* object. Note that the caller is responsible for obtaining and holding a VM reference
* to the jobject to prevent its being garbage collected while the native object is
* in use.
*/
javaAssetManagerRef = (*env)->NewGlobalRef(env, javaAssetManager);
asset_manager = AAssetManager_fromJava(env, javaAssetManagerRef);
if (asset_manager == NULL) {
(*env)->DeleteGlobalRef(env, javaAssetManagerRef);
Android_JNI_ExceptionOccurred(SDL_TRUE);
}
LocalReferenceHolder_Cleanup(&refs);
}
static void Internal_Android_Destroy_AssetManager() {
JNIEnv *env = Android_JNI_GetEnv();
if (asset_manager) {
(*env)->DeleteGlobalRef(env, javaAssetManagerRef);
asset_manager = NULL;
}
}
static int Internal_Android_JNI_FileOpen(SDL_RWops *ctx) static int Internal_Android_JNI_FileOpen(SDL_RWops *ctx)
{ {
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__);
@ -2800,50 +2855,32 @@ SDL_bool Android_JNI_RequestPermission(const char *permission)
int Android_JNI_GetLocale(char *buf, size_t buflen) int Android_JNI_GetLocale(char *buf, size_t buflen)
{ {
struct LocalReferenceHolder refs = LocalReferenceHolder_Setup(__FUNCTION__); AConfiguration *cfg;
JNIEnv* env = Android_JNI_GetEnv();
int retval = -1;
JNIEnv *mEnv = Android_JNI_GetEnv();
if (!LocalReferenceHolder_Init(&refs, env)) {
LocalReferenceHolder_Cleanup(&refs);
return -1;
}
SDL_assert(buflen > 6); SDL_assert(buflen > 6);
jmethodID mid; if (asset_manager == NULL) {
jobject context; Internal_Android_Create_AssetManager();
jobject assetManager; }
/* context = SDLActivity.getContext(); */ if (asset_manager == NULL) {
mid = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, return -1;
"getContext","()Landroid/content/Context;"); }
context = (*mEnv)->CallStaticObjectMethod(mEnv, mActivityClass, mid);
/* assetManager = context.getAssets(); */ cfg = AConfiguration_new();
mid = (*mEnv)->GetMethodID(mEnv, (*mEnv)->GetObjectClass(mEnv, context), if (cfg == NULL) {
"getAssets", "()Landroid/content/res/AssetManager;"); return -1;
assetManager = (*mEnv)->CallObjectMethod(mEnv, context, mid); }
/* API from NDK: android/configuration.h */
/* API from NDK: android/asset_manager_jni.h */
AAssetManager* asset_mgr = AAssetManager_fromJava(env, assetManager);
AConfiguration *cfg = AConfiguration_new();
if (asset_mgr && cfg)
{ {
char language[2] = {}; char language[2] = {};
char country[2] = {}; char country[2] = {};
size_t id = 0; size_t id = 0;
AConfiguration_fromAssetManager(cfg, asset_mgr); AConfiguration_fromAssetManager(cfg, asset_manager);
AConfiguration_getLanguage(cfg, language); AConfiguration_getLanguage(cfg, language);
AConfiguration_getCountry(cfg, country); AConfiguration_getCountry(cfg, country);
retval = 0;
/* copy language (not null terminated) */ /* copy language (not null terminated) */
if (language[0]) { if (language[0]) {
buf[id++] = language[0]; buf[id++] = language[0];
@ -2866,12 +2903,9 @@ int Android_JNI_GetLocale(char *buf, size_t buflen)
SDL_assert(id <= buflen); SDL_assert(id <= buflen);
} }
if (cfg) { AConfiguration_delete(cfg);
AConfiguration_delete(cfg);
}
LocalReferenceHolder_Cleanup(&refs); return 0;
return retval;
} }
#endif /* __ANDROID__ */ #endif /* __ANDROID__ */