Request Android record permission when needed

This commit is contained in:
DESKTOP-3H3MR3A\eloisa 2019-03-04 23:06:37 -03:00 committed by Marcelo Fernandez
parent a38bf5287a
commit b22cf46fdb
12 changed files with 83 additions and 5 deletions

View File

@ -1093,6 +1093,11 @@ void _OS::alert(const String &p_alert, const String &p_title) {
OS::get_singleton()->alert(p_alert, p_title); OS::get_singleton()->alert(p_alert, p_title);
} }
bool _OS::request_permission(const String &p_name) {
return OS::get_singleton()->request_permission(p_name);
}
_OS *_OS::singleton = NULL; _OS *_OS::singleton = NULL;
void _OS::_bind_methods() { void _OS::_bind_methods() {
@ -1265,6 +1270,8 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_power_seconds_left"), &_OS::get_power_seconds_left); ClassDB::bind_method(D_METHOD("get_power_seconds_left"), &_OS::get_power_seconds_left);
ClassDB::bind_method(D_METHOD("get_power_percent_left"), &_OS::get_power_percent_left); ClassDB::bind_method(D_METHOD("get_power_percent_left"), &_OS::get_power_percent_left);
ClassDB::bind_method(D_METHOD("request_permission", "name"), &_OS::request_permission);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "clipboard"), "set_clipboard", "get_clipboard"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "clipboard"), "set_clipboard", "get_clipboard");
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen"); ADD_PROPERTY(PropertyInfo(Variant::INT, "current_screen"), "set_current_screen", "get_current_screen");
ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code"); ADD_PROPERTY(PropertyInfo(Variant::INT, "exit_code"), "set_exit_code", "get_exit_code");

View File

@ -356,6 +356,8 @@ public:
bool has_feature(const String &p_feature) const; bool has_feature(const String &p_feature) const;
bool request_permission(const String &p_name);
static _OS *get_singleton() { return singleton; } static _OS *get_singleton() { return singleton; }
_OS(); _OS();

View File

@ -518,6 +518,8 @@ public:
bool is_restart_on_exit_set() const; bool is_restart_on_exit_set() const;
List<String> get_restart_on_exit_arguments() const; List<String> get_restart_on_exit_arguments() const;
virtual bool request_permission(const String &p_name) { return true; }
virtual void process_and_drop_events() {} virtual void process_and_drop_events() {}
OS(); OS();
virtual ~OS(); virtual ~OS();

View File

@ -684,6 +684,13 @@
Request the user attention to the window. It'll flash the taskbar button on Windows or bounce the dock icon on OSX. Request the user attention to the window. It'll flash the taskbar button on Windows or bounce the dock icon on OSX.
</description> </description>
</method> </method>
<method name="request_permission">
<return type="bool">
</return>
<description>
At the moment this function is only used by the AudioDriverOpenSL to request permission for RECORD_AUDIO on Android.
</description>
</method>
<method name="set_icon"> <method name="set_icon">
<return type="void"> <return type="void">
</return> </return>

View File

@ -230,7 +230,7 @@ void AudioDriverOpenSL::_record_buffer_callbacks(SLAndroidSimpleBufferQueueItf q
ad->_record_buffer_callback(queueItf); ad->_record_buffer_callback(queueItf);
} }
Error AudioDriverOpenSL::capture_start() { Error AudioDriverOpenSL::capture_init_device() {
SLDataLocator_IODevice loc_dev = { SLDataLocator_IODevice loc_dev = {
SL_DATALOCATOR_IODEVICE, SL_DATALOCATOR_IODEVICE,
@ -298,6 +298,15 @@ Error AudioDriverOpenSL::capture_start() {
return OK; return OK;
} }
Error AudioDriverOpenSL::capture_start() {
if (OS::get_singleton()->request_permission("RECORD_AUDIO")) {
return capture_init_device();
}
return OK;
}
Error AudioDriverOpenSL::capture_stop() { Error AudioDriverOpenSL::capture_stop() {
SLuint32 state; SLuint32 state;

View File

@ -88,6 +88,8 @@ class AudioDriverOpenSL : public AudioDriver {
SLAndroidSimpleBufferQueueItf queueItf, SLAndroidSimpleBufferQueueItf queueItf,
void *pContext); void *pContext);
virtual Error capture_init_device();
public: public:
void set_singleton(); void set_singleton();

View File

@ -45,6 +45,7 @@ import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor; import android.content.SharedPreferences.Editor;
import android.content.pm.ConfigurationInfo; import android.content.pm.ConfigurationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
@ -52,11 +53,13 @@ import android.hardware.Sensor;
import android.hardware.SensorEvent; import android.hardware.SensorEvent;
import android.hardware.SensorEventListener; import android.hardware.SensorEventListener;
import android.hardware.SensorManager; import android.hardware.SensorManager;
import android.Manifest;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Messenger; import android.os.Messenger;
import android.provider.Settings.Secure; import android.provider.Settings.Secure;
import android.support.v4.content.ContextCompat;
import android.util.Log; import android.util.Log;
import android.view.Display; import android.view.Display;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -99,6 +102,7 @@ import javax.microedition.khronos.opengles.GL10;
public class Godot extends Activity implements SensorEventListener, IDownloaderClient { public class Godot extends Activity implements SensorEventListener, IDownloaderClient {
static final int MAX_SINGLETONS = 64; static final int MAX_SINGLETONS = 64;
static final int REQUEST_RECORD_AUDIO_PERMISSION = 1;
private IStub mDownloaderClientStub; private IStub mDownloaderClientStub;
private IDownloaderService mRemoteService; private IDownloaderService mRemoteService;
private TextView mStatusText; private TextView mStatusText;
@ -259,6 +263,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
for (int i = 0; i < singleton_count; i++) { for (int i = 0; i < singleton_count; i++) {
singletons[i].onMainRequestPermissionsResult(requestCode, permissions, grantResults); singletons[i].onMainRequestPermissionsResult(requestCode, permissions, grantResults);
} }
for (int i = 0; i < permissions.length; i++) {
GodotLib.requestPermissionResult(permissions[i], grantResults[i] == PackageManager.PERMISSION_GRANTED);
}
}; };
public void onVideoInit() { public void onVideoInit() {
@ -936,7 +944,21 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
} }
*/ */
// Audio public boolean requestPermission(String p_name) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Not necessary, asked on install already
return true;
}
if (p_name.equals("RECORD_AUDIO")) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] { Manifest.permission.RECORD_AUDIO }, REQUEST_RECORD_AUDIO_PERMISSION);
return false;
}
}
return true;
}
/** /**
* The download state should trigger changes in the UI --- it may be useful * The download state should trigger changes in the UI --- it may be useful

View File

@ -69,6 +69,7 @@ public class GodotLib {
public static native String getGlobal(String p_key); public static native String getGlobal(String p_key);
public static native void callobject(int p_ID, String p_method, Object[] p_params); public static native void callobject(int p_ID, String p_method, Object[] p_params);
public static native void calldeferred(int p_ID, String p_method, Object[] p_params); public static native void calldeferred(int p_ID, String p_method, Object[] p_params);
public static native void requestPermissionResult(String p_permission, boolean p_result);
public static native void setVirtualKeyboardHeight(int p_height); public static native void setVirtualKeyboardHeight(int p_height);
} }

View File

@ -621,6 +621,7 @@ static jmethodID _pauseVideo = 0;
static jmethodID _stopVideo = 0; static jmethodID _stopVideo = 0;
static jmethodID _setKeepScreenOn = 0; static jmethodID _setKeepScreenOn = 0;
static jmethodID _alertDialog = 0; static jmethodID _alertDialog = 0;
static jmethodID _requestPermission = 0;
static void _gfx_init_func(void *ud, bool gl2) { static void _gfx_init_func(void *ud, bool gl2) {
} }
@ -746,6 +747,12 @@ static void _alert(const String &p_message, const String &p_title) {
env->CallVoidMethod(_godot_instance, _alertDialog, jStrMessage, jStrTitle); env->CallVoidMethod(_godot_instance, _alertDialog, jStrMessage, jStrTitle);
} }
static bool _request_permission(const String &p_name) {
JNIEnv *env = ThreadAndroid::get_env();
jstring jStrName = env->NewStringUTF(p_name.utf8().get_data());
return env->CallBooleanMethod(_godot_instance, _requestPermission, jStrName);
}
// volatile because it can be changed from non-main thread and we need to // volatile because it can be changed from non-main thread and we need to
// ensure the change is immediately visible to other threads. // ensure the change is immediately visible to other threads.
static volatile int virtual_keyboard_height; static volatile int virtual_keyboard_height;
@ -790,6 +797,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
_getGLESVersionCode = env->GetMethodID(cls, "getGLESVersionCode", "()I"); _getGLESVersionCode = env->GetMethodID(cls, "getGLESVersionCode", "()I");
_getClipboard = env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;"); _getClipboard = env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
_setClipboard = env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V"); _setClipboard = env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
_requestPermission = env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z");
if (cls) { if (cls) {
jclass c = env->GetObjectClass(gob); jclass c = env->GetObjectClass(gob);
@ -822,7 +830,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
AudioDriverAndroid::setup(gob); AudioDriverAndroid::setup(gob);
} }
os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _get_gles_version_code, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, _set_clipboard, _get_clipboard, p_use_apk_expansion); os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_user_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _get_vk_height, _set_screen_orient, _get_unique_id, _get_system_dir, _get_gles_version_code, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, _set_clipboard, _get_clipboard, _request_permission, p_use_apk_expansion);
char wd[500]; char wd[500];
getcwd(wd, 500); getcwd(wd, 500);
@ -1572,3 +1580,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *
// something // something
env->PopLocalFrame(NULL); env->PopLocalFrame(NULL);
} }
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jobject p_obj, jstring p_permission, jboolean p_result) {
String permission = jstring_to_string(p_permission, env);
if (permission == "android.permission.RECORD_AUDIO" && p_result) {
AudioDriver::get_singleton()->capture_start();
}
}

View File

@ -60,6 +60,7 @@ JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jobject obj, jint p_height); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHeight(JNIEnv *env, jobject obj, jint p_height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResult(JNIEnv *env, jobject p_obj, jstring p_permission, jboolean p_result);
} }
#endif // JAVA_GLUE_H #endif // JAVA_GLUE_H

View File

@ -202,6 +202,12 @@ void OS_Android::alert(const String &p_alert, const String &p_title) {
alert_func(p_alert, p_title); alert_func(p_alert, p_title);
} }
bool OS_Android::request_permission(const String &p_name) {
if (request_permission_func)
return request_permission_func(p_name);
return false;
}
Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) { Error OS_Android::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW); p_library_handle = dlopen(p_path.utf8().get_data(), RTLD_NOW);
if (!p_library_handle) { if (!p_library_handle) {
@ -713,7 +719,7 @@ bool OS_Android::_check_internal_feature_support(const String &p_feature) {
return false; return false;
} }
OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, SetClipboardFunc p_set_clipboard_func, GetClipboardFunc p_get_clipboard_func, bool p_use_apk_expansion) { OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, SetClipboardFunc p_set_clipboard_func, GetClipboardFunc p_get_clipboard_func, RequestPermissionFunc p_request_permission, bool p_use_apk_expansion) {
use_apk_expansion = p_use_apk_expansion; use_apk_expansion = p_use_apk_expansion;
default_videomode.width = 800; default_videomode.width = 800;
@ -752,6 +758,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
set_screen_orientation_func = p_screen_orient; set_screen_orientation_func = p_screen_orient;
set_keep_screen_on_func = p_set_keep_screen_on_func; set_keep_screen_on_func = p_set_keep_screen_on_func;
alert_func = p_alert_func; alert_func = p_alert_func;
request_permission_func = p_request_permission;
Vector<Logger *> loggers; Vector<Logger *> loggers;
loggers.push_back(memnew(AndroidLogger)); loggers.push_back(memnew(AndroidLogger));

View File

@ -63,6 +63,7 @@ typedef void (*VideoStopFunc)();
typedef void (*SetKeepScreenOnFunc)(bool p_enabled); typedef void (*SetKeepScreenOnFunc)(bool p_enabled);
typedef void (*AlertFunc)(const String &, const String &); typedef void (*AlertFunc)(const String &, const String &);
typedef int (*VirtualKeyboardHeightFunc)(); typedef int (*VirtualKeyboardHeightFunc)();
typedef bool (*RequestPermissionFunc)(const String &);
class OS_Android : public OS_Unix { class OS_Android : public OS_Unix {
public: public:
@ -132,6 +133,7 @@ private:
VideoStopFunc video_stop_func; VideoStopFunc video_stop_func;
SetKeepScreenOnFunc set_keep_screen_on_func; SetKeepScreenOnFunc set_keep_screen_on_func;
AlertFunc alert_func; AlertFunc alert_func;
RequestPermissionFunc request_permission_func;
//PowerAndroid *power_manager; //PowerAndroid *power_manager;
int video_driver_index; int video_driver_index;
@ -159,6 +161,7 @@ public:
static OS *get_singleton(); static OS *get_singleton();
virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual bool request_permission(const String &p_name);
virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
@ -238,7 +241,7 @@ public:
void joy_connection_changed(int p_device, bool p_connected, String p_name); void joy_connection_changed(int p_device, bool p_connected, String p_name);
virtual bool _check_internal_feature_support(const String &p_feature); virtual bool _check_internal_feature_support(const String &p_feature);
OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, SetClipboardFunc p_set_clipboard, GetClipboardFunc p_get_clipboard, bool p_use_apk_expansion); OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetUserDataDirFunc p_get_user_data_dir_func, GetLocaleFunc p_get_locale_func, GetModelFunc p_get_model_func, GetScreenDPIFunc p_get_screen_dpi_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk, VirtualKeyboardHeightFunc p_vk_height_func, SetScreenOrientationFunc p_screen_orient, GetUniqueIDFunc p_get_unique_id, GetSystemDirFunc p_get_sdir_func, GetGLVersionCodeFunc p_get_gl_version_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func, SetKeepScreenOnFunc p_set_keep_screen_on_func, AlertFunc p_alert_func, SetClipboardFunc p_set_clipboard, GetClipboardFunc p_get_clipboard, RequestPermissionFunc p_request_permission, bool p_use_apk_expansion);
~OS_Android(); ~OS_Android();
}; };