|
@@ -381,9 +381,6 @@ static SDL_bool bHasNewData;
|
|
|
|
|
|
static SDL_bool bHasEnvironmentVariables;
|
|
|
|
|
|
-static SDL_AtomicInt bPermissionRequestPending;
|
|
|
-static SDL_bool bPermissionRequestResult;
|
|
|
-
|
|
|
/* Android AssetManager */
|
|
|
static void Internal_Android_Create_AssetManager(void);
|
|
|
static void Internal_Android_Destroy_AssetManager(void);
|
|
@@ -997,14 +994,6 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeAddTouch)(
|
|
|
(*env)->ReleaseStringUTFChars(env, name, utfname);
|
|
|
}
|
|
|
|
|
|
-JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
|
|
|
- JNIEnv *env, jclass cls,
|
|
|
- jint requestCode, jboolean result)
|
|
|
-{
|
|
|
- bPermissionRequestResult = result;
|
|
|
- SDL_AtomicSet(&bPermissionRequestPending, SDL_FALSE);
|
|
|
-}
|
|
|
-
|
|
|
JNIEXPORT void JNICALL
|
|
|
SDL_JAVA_AUDIO_INTERFACE(addAudioDevice)(JNIEnv *env, jclass jcls, jboolean is_capture,
|
|
|
jstring name, jint device_id)
|
|
@@ -2640,29 +2629,100 @@ SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled)
|
|
|
return (*env)->CallStaticBooleanMethod(env, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1));
|
|
|
}
|
|
|
|
|
|
-SDL_bool Android_JNI_RequestPermission(const char *permission)
|
|
|
+typedef struct NativePermissionRequestInfo
|
|
|
{
|
|
|
- JNIEnv *env = Android_JNI_GetEnv();
|
|
|
- jstring jpermission;
|
|
|
- const int requestCode = 1;
|
|
|
+ int request_code;
|
|
|
+ char *permission;
|
|
|
+ SDL_AndroidRequestPermissionCallback callback;
|
|
|
+ void *userdata;
|
|
|
+ struct NativePermissionRequestInfo *next;
|
|
|
+} NativePermissionRequestInfo;
|
|
|
|
|
|
- /* Wait for any pending request on another thread */
|
|
|
- while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
|
|
- SDL_Delay(10);
|
|
|
+static NativePermissionRequestInfo pending_permissions;
|
|
|
+
|
|
|
+JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativePermissionResult)(
|
|
|
+ JNIEnv *env, jclass cls,
|
|
|
+ jint requestCode, jboolean result)
|
|
|
+{
|
|
|
+ SDL_LockMutex(Android_ActivityMutex);
|
|
|
+ NativePermissionRequestInfo *prev = &pending_permissions;
|
|
|
+ for (NativePermissionRequestInfo *info = prev->next; info != NULL; info = info->next) {
|
|
|
+ if (info->request_code == (int) requestCode) {
|
|
|
+ prev->next = info->next;
|
|
|
+ SDL_UnlockMutex(Android_ActivityMutex);
|
|
|
+ info->callback(info->userdata, info->permission, result ? SDL_TRUE : SDL_FALSE);
|
|
|
+ SDL_free(info->permission);
|
|
|
+ SDL_free(info);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ prev = info;
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_UnlockMutex(Android_ActivityMutex);
|
|
|
+ SDL_assert(!"Shouldn't have hit this code"); // we had a permission response for a request we never made...?
|
|
|
+}
|
|
|
+
|
|
|
+int SDL_AndroidRequestPermissionAsync(const char *permission, SDL_AndroidRequestPermissionCallback cb, void *userdata)
|
|
|
+{
|
|
|
+ if (!permission) {
|
|
|
+ return SDL_InvalidParamError("permission");
|
|
|
+ } else if (!cb) {
|
|
|
+ return SDL_InvalidParamError("cb");
|
|
|
}
|
|
|
- SDL_AtomicSet(&bPermissionRequestPending, SDL_TRUE);
|
|
|
|
|
|
- jpermission = (*env)->NewStringUTF(env, permission);
|
|
|
- (*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);
|
|
|
+ NativePermissionRequestInfo *info = (NativePermissionRequestInfo *) SDL_calloc(1, sizeof (NativePermissionRequestInfo));
|
|
|
+ if (!info) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ info->permission = SDL_strdup(permission);
|
|
|
+ if (!info->permission) {
|
|
|
+ SDL_free(info);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ static SDL_AtomicInt next_request_code;
|
|
|
+ info->request_code = SDL_AtomicAdd(&next_request_code, 1);
|
|
|
+
|
|
|
+ info->callback = cb;
|
|
|
+ info->userdata = userdata;
|
|
|
+
|
|
|
+ SDL_LockMutex(Android_ActivityMutex);
|
|
|
+ info->next = pending_permissions.next;
|
|
|
+ pending_permissions.next = info;
|
|
|
+ SDL_UnlockMutex(Android_ActivityMutex);
|
|
|
+
|
|
|
+ JNIEnv *env = Android_JNI_GetEnv();
|
|
|
+ jstring jpermission = (*env)->NewStringUTF(env, permission);
|
|
|
+ (*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, info->request_code);
|
|
|
(*env)->DeleteLocalRef(env, jpermission);
|
|
|
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void SDLCALL AndroidRequestPermissionBlockingCallback(void *userdata, const char *permission, SDL_bool granted)
|
|
|
+{
|
|
|
+ SDL_AtomicSet((SDL_AtomicInt *) userdata, granted ? 1 : -1);
|
|
|
+}
|
|
|
+
|
|
|
+SDL_bool Android_JNI_RequestPermission(const char *permission)
|
|
|
+{
|
|
|
+ SDL_AtomicInt response;
|
|
|
+ SDL_AtomicSet(&response, 0);
|
|
|
+
|
|
|
+ if (SDL_AndroidRequestPermissionAsync(permission, AndroidRequestPermissionBlockingCallback, &response) == -1) {
|
|
|
+ return SDL_FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
/* Wait for the request to complete */
|
|
|
- while (SDL_AtomicGet(&bPermissionRequestPending) == SDL_TRUE) {
|
|
|
+ while (SDL_AtomicGet(&response) == 0) {
|
|
|
SDL_Delay(10);
|
|
|
}
|
|
|
- return bPermissionRequestResult;
|
|
|
+
|
|
|
+ return (SDL_AtomicGet(&response) < 0) ? SDL_FALSE : SDL_TRUE;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/* Show toast notification */
|
|
|
int Android_JNI_ShowToast(const char *message, int duration, int gravity, int xOffset, int yOffset)
|
|
|
{
|