mirror of https://github.com/bjornbytes/lovr.git
Android: Ask for permissions on demand
By looking for failed start and requesting then; and then emitting a new event type when permission has been granted or rejected; and then using that event in the default boot.lua to re-start capture.
This commit is contained in:
parent
aa3dc76176
commit
0265babef4
|
@ -18,6 +18,7 @@ StringEntry lovrEventType[] = {
|
|||
#ifndef LOVR_DISABLE_THREAD
|
||||
[EVENT_THREAD_ERROR] = ENTRY("threaderror"),
|
||||
#endif
|
||||
[EVENT_PERMISSION] = ENTRY("permission"),
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -110,6 +111,12 @@ StringEntry lovrKeyboardKey[] = {
|
|||
{ 0 }
|
||||
};
|
||||
|
||||
StringEntry lovrPermission[] = {
|
||||
[AUDIO_CAPTURE_PERMISSION] = ENTRY("audio_capture"),
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
static LOVR_THREAD_LOCAL int pollRef;
|
||||
|
||||
void luax_checkvariant(lua_State* L, int index, Variant* variant) {
|
||||
|
@ -228,6 +235,11 @@ static int nextEvent(lua_State* L) {
|
|||
return 3;
|
||||
#endif
|
||||
|
||||
case EVENT_PERMISSION:
|
||||
luax_pushenum(L, Permission, event.data.permission.permission);
|
||||
lua_pushboolean(L, event.data.permission.granted);
|
||||
return 3;
|
||||
|
||||
case EVENT_CUSTOM:
|
||||
for (uint32_t i = 0; i < event.data.custom.count; i++) {
|
||||
Variant* variant = &event.data.custom.data[i];
|
||||
|
|
|
@ -129,12 +129,17 @@ typedef enum {
|
|||
BUTTON_RELEASED
|
||||
} ButtonAction;
|
||||
|
||||
typedef enum {
|
||||
AUDIO_CAPTURE_PERMISSION,
|
||||
} Permission;
|
||||
|
||||
typedef void (*quitCallback)(void);
|
||||
typedef void (*windowFocusCallback)(bool focused);
|
||||
typedef void (*windowResizeCallback)(int width, int height);
|
||||
typedef void (*mouseButtonCallback)(MouseButton button, ButtonAction action);
|
||||
typedef void (*keyboardCallback)(ButtonAction action, KeyboardKey key, uint32_t scancode, bool repeat);
|
||||
typedef void (*textCallback)(uint32_t codepoint);
|
||||
typedef void (*permissionsCallback)(Permission permission, bool granted);
|
||||
|
||||
bool lovrPlatformInit(void);
|
||||
void lovrPlatformDestroy(void);
|
||||
|
@ -166,3 +171,5 @@ void lovrPlatformGetMousePosition(double* x, double* y);
|
|||
void lovrPlatformSetMouseMode(MouseMode mode);
|
||||
bool lovrPlatformIsMouseDown(MouseButton button);
|
||||
bool lovrPlatformIsKeyDown(KeyboardKey key);
|
||||
void lovrPlatformRequestAudioCapture();
|
||||
void lovrPlatformOnPermissionEvent(permissionsCallback callback);
|
|
@ -22,6 +22,7 @@ static struct {
|
|||
quitCallback onQuit;
|
||||
keyboardCallback onKeyboardEvent;
|
||||
textCallback onTextEvent;
|
||||
permissionsCallback onPermissionEvent;
|
||||
} state;
|
||||
|
||||
static void onAppCmd(struct android_app* app, int32_t cmd) {
|
||||
|
@ -470,6 +471,32 @@ bool lovrPlatformIsKeyDown(KeyboardKey key) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// permissions
|
||||
|
||||
void lovrPlatformRequestAudioCapture() {
|
||||
jobject activity = state.app->activity->clazz;
|
||||
jclass class = (*state.jni)->GetObjectClass(state.jni, activity);
|
||||
jmethodID requestAudioCapturePermission = (*state.jni)->GetMethodID(state.jni, class, "requestAudioCapturePermission", "()V");
|
||||
if (!requestAudioCapturePermission) {
|
||||
(*state.jni)->DeleteLocalRef(state.jni, class);
|
||||
if(state.onPermissionEvent) state.onPermissionEvent(AUDIO_CAPTURE_PERMISSION, false);
|
||||
return;
|
||||
}
|
||||
|
||||
(*state.jni)->CallVoidMethod(state.jni, activity, requestAudioCapturePermission);
|
||||
}
|
||||
|
||||
void lovrPlatformOnPermissionEvent(permissionsCallback callback) {
|
||||
state.onPermissionEvent = callback;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_org_lovr_app_Activity_lovrPermissionEvent(JNIEnv* jni, jobject activity, jint permission, jboolean granted) {
|
||||
if (state.onPermissionEvent) {
|
||||
state.onPermissionEvent(permission, granted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Private, must be declared manually to use
|
||||
|
||||
struct ANativeActivity* lovrPlatformGetActivity() {
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "data/blob.h"
|
||||
#include "core/arr.h"
|
||||
#include "core/ref.h"
|
||||
#include "core/ref.h"
|
||||
#include "core/os.h"
|
||||
#include "core/util.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -247,11 +247,16 @@ bool lovrAudioReset() {
|
|||
bool lovrAudioStart(AudioType type) {
|
||||
if(state.config[type].enable == false) {
|
||||
if(lovrAudioInitDevice(type) == false) {
|
||||
if (type == AUDIO_CAPTURE) {
|
||||
lovrPlatformRequestAudioCapture();
|
||||
// lovrAudioStart will be retried from boot.lua upon permission granted event
|
||||
}
|
||||
return false;
|
||||
}
|
||||
state.config[type].enable = state.config[type].start = true;
|
||||
}
|
||||
return ma_device_start(&state.devices[type]) == MA_SUCCESS;
|
||||
int status = ma_device_start(&state.devices[type]);
|
||||
return status == MA_SUCCESS;
|
||||
}
|
||||
|
||||
bool lovrAudioStop(AudioType type) {
|
||||
|
|
|
@ -32,6 +32,14 @@ static void onTextEvent(uint32_t codepoint) {
|
|||
lovrEventPush(event);
|
||||
}
|
||||
|
||||
static void onPermissionEvent(Permission permission, bool granted) {
|
||||
Event event;
|
||||
event.type = EVENT_PERMISSION;
|
||||
event.data.permission.permission = permission;
|
||||
event.data.permission.granted = granted;
|
||||
lovrEventPush(event);
|
||||
}
|
||||
|
||||
void lovrVariantDestroy(Variant* variant) {
|
||||
switch (variant->type) {
|
||||
case TYPE_STRING: free(variant->value.string); return;
|
||||
|
@ -45,6 +53,7 @@ bool lovrEventInit() {
|
|||
arr_init(&state.events);
|
||||
lovrPlatformOnKeyboardEvent(onKeyboardEvent);
|
||||
lovrPlatformOnTextEvent(onTextEvent);
|
||||
lovrPlatformOnPermissionEvent(onPermissionEvent);
|
||||
return state.initialized = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "core/os.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
|
@ -19,6 +20,7 @@ typedef enum {
|
|||
#ifndef LOVR_DISABLE_THREAD
|
||||
EVENT_THREAD_ERROR,
|
||||
#endif
|
||||
EVENT_PERMISSION,
|
||||
} EventType;
|
||||
|
||||
typedef enum {
|
||||
|
@ -80,6 +82,11 @@ typedef struct {
|
|||
uint32_t count;
|
||||
} CustomEvent;
|
||||
|
||||
typedef struct {
|
||||
Permission permission;
|
||||
bool granted;
|
||||
} PermissionEvent;
|
||||
|
||||
typedef union {
|
||||
QuitEvent quit;
|
||||
BoolEvent boolean;
|
||||
|
@ -88,6 +95,7 @@ typedef union {
|
|||
TextEvent text;
|
||||
ThreadEvent thread;
|
||||
CustomEvent custom;
|
||||
PermissionEvent permission;
|
||||
} EventData;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -17,23 +17,24 @@ public class Activity extends NativeActivity implements ActivityCompat.OnRequest
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Log.i("LOVR", "MainActivity.onCreate()");
|
||||
RequestPermissionsIfNeeded();
|
||||
}
|
||||
|
||||
protected native void lovrPermissionEvent(int permission, boolean granted);
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
|
||||
{
|
||||
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
Log.i("LOVR", "RECORD_AUDIO permissions have now been granted.");
|
||||
lovrPermissionEvent(0, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log.i("LOVR", "RECORD_AUDIO permissions were denied.");
|
||||
lovrPermissionEvent(0, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void RequestPermissionsIfNeeded()
|
||||
private void requestAudioCapturePermission()
|
||||
{
|
||||
int existingPermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO);
|
||||
if(existingPermission != PackageManager.PERMISSION_GRANTED)
|
||||
|
@ -43,7 +44,7 @@ public class Activity extends NativeActivity implements ActivityCompat.OnRequest
|
|||
}
|
||||
else
|
||||
{
|
||||
Log.i("LOVR", "RECORD_AUDIO permissions already granted.");
|
||||
lovrPermissionEvent(0, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,6 +172,12 @@ function lovr.boot()
|
|||
return lovr.run()
|
||||
end
|
||||
|
||||
function lovr.permission(permission, granted)
|
||||
if permission == "audio_capture" and granted then
|
||||
lovr.audio.start("capture")
|
||||
end
|
||||
end
|
||||
|
||||
function lovr.run()
|
||||
lovr.timer.step()
|
||||
if lovr.load then lovr.load(arg) end
|
||||
|
|
Loading…
Reference in New Issue