mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-05-29 07:59:11 +00:00
android: Added SDL_AndroidRequestPermissionAsync.
This commit is contained in:
parent
310f21bf84
commit
af61cfd5e0
7 changed files with 144 additions and 23 deletions
|
@ -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_AtomicSet(&bPermissionRequestPending, SDL_TRUE);
|
||||
|
||||
jpermission = (*env)->NewStringUTF(env, permission);
|
||||
(*env)->CallStaticVoidMethod(env, mActivityClass, midRequestPermission, jpermission, requestCode);
|
||||
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");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue