Merge pull request #32600 from cagdasc/3.2-auto-permission-manager
Add request defined permissions in AndroidManifest.xml
This commit is contained in:
commit
4e29faaeea
13 changed files with 258 additions and 29 deletions
|
@ -1136,6 +1136,16 @@ bool _OS::request_permission(const String &p_name) {
|
||||||
return OS::get_singleton()->request_permission(p_name);
|
return OS::get_singleton()->request_permission(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _OS::request_permissions() {
|
||||||
|
|
||||||
|
return OS::get_singleton()->request_permissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> _OS::get_granted_permissions() const {
|
||||||
|
|
||||||
|
return OS::get_singleton()->get_granted_permissions();
|
||||||
|
}
|
||||||
|
|
||||||
_OS *_OS::singleton = NULL;
|
_OS *_OS::singleton = NULL;
|
||||||
|
|
||||||
void _OS::_bind_methods() {
|
void _OS::_bind_methods() {
|
||||||
|
@ -1319,6 +1329,8 @@ void _OS::_bind_methods() {
|
||||||
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);
|
ClassDB::bind_method(D_METHOD("request_permission", "name"), &_OS::request_permission);
|
||||||
|
ClassDB::bind_method(D_METHOD("request_permissions"), &_OS::request_permissions);
|
||||||
|
ClassDB::bind_method(D_METHOD("get_granted_permissions"), &_OS::get_granted_permissions);
|
||||||
|
|
||||||
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");
|
||||||
|
|
|
@ -349,6 +349,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);
|
bool request_permission(const String &p_name);
|
||||||
|
bool request_permissions();
|
||||||
|
Vector<String> get_granted_permissions() const;
|
||||||
|
|
||||||
static _OS *get_singleton() { return singleton; }
|
static _OS *get_singleton() { return singleton; }
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,8 @@ void MainLoop::_bind_methods() {
|
||||||
BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
|
BIND_CONSTANT(NOTIFICATION_OS_IME_UPDATE);
|
||||||
BIND_CONSTANT(NOTIFICATION_APP_RESUMED);
|
BIND_CONSTANT(NOTIFICATION_APP_RESUMED);
|
||||||
BIND_CONSTANT(NOTIFICATION_APP_PAUSED);
|
BIND_CONSTANT(NOTIFICATION_APP_PAUSED);
|
||||||
|
|
||||||
|
ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted")));
|
||||||
};
|
};
|
||||||
|
|
||||||
void MainLoop::set_init_script(const Ref<Script> &p_init_script) {
|
void MainLoop::set_init_script(const Ref<Script> &p_init_script) {
|
||||||
|
|
|
@ -530,6 +530,8 @@ public:
|
||||||
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 bool request_permission(const String &p_name) { return true; }
|
||||||
|
virtual bool request_permissions() { return true; }
|
||||||
|
virtual Vector<String> get_granted_permissions() const { return Vector<String>(); }
|
||||||
|
|
||||||
virtual void process_and_drop_events() {}
|
virtual void process_and_drop_events() {}
|
||||||
OS();
|
OS();
|
||||||
|
|
|
@ -167,6 +167,17 @@
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
</methods>
|
</methods>
|
||||||
|
<signals>
|
||||||
|
<signal name="on_request_permissions_result">
|
||||||
|
<argument index="0" name="permission" type="String">
|
||||||
|
</argument>
|
||||||
|
<argument index="1" name="granted" type="bool">
|
||||||
|
</argument>
|
||||||
|
<description>
|
||||||
|
Emitted when an user responds to permission request.
|
||||||
|
</description>
|
||||||
|
</signal>
|
||||||
|
</signals>
|
||||||
<constants>
|
<constants>
|
||||||
<constant name="NOTIFICATION_WM_MOUSE_ENTER" value="1002">
|
<constant name="NOTIFICATION_WM_MOUSE_ENTER" value="1002">
|
||||||
Notification received from the OS when the mouse enters the game window.
|
Notification received from the OS when the mouse enters the game window.
|
||||||
|
|
|
@ -217,6 +217,13 @@
|
||||||
Returns the path to the current engine executable.
|
Returns the path to the current engine executable.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="get_granted_permissions">
|
||||||
|
<return type="PoolStringArray">
|
||||||
|
</return>
|
||||||
|
<description>
|
||||||
|
With this function you can get the list of dangerous permissions that have been granted to the Android application.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="get_ime_selection" qualifiers="const">
|
<method name="get_ime_selection" qualifiers="const">
|
||||||
<return type="Vector2">
|
<return type="Vector2">
|
||||||
</return>
|
</return>
|
||||||
|
@ -744,6 +751,13 @@
|
||||||
At the moment this function is only used by [code]AudioDriverOpenSL[/code] to request permission for [code]RECORD_AUDIO[/code] on Android.
|
At the moment this function is only used by [code]AudioDriverOpenSL[/code] to request permission for [code]RECORD_AUDIO[/code] on Android.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="request_permissions">
|
||||||
|
<return type="bool">
|
||||||
|
</return>
|
||||||
|
<description>
|
||||||
|
With this function you can request dangerous permissions since normal permissions are automatically granted at install time in Android application.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="set_icon">
|
<method name="set_icon">
|
||||||
<return type="void">
|
<return type="void">
|
||||||
</return>
|
</return>
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
package org.godotengine.godot;
|
package org.godotengine.godot;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
|
@ -64,7 +63,6 @@ import android.os.Vibrator;
|
||||||
import android.provider.Settings.Secure;
|
import android.provider.Settings.Secure;
|
||||||
import android.support.annotation.Keep;
|
import android.support.annotation.Keep;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v4.content.ContextCompat;
|
|
||||||
import android.view.Display;
|
import android.view.Display;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
|
@ -98,14 +96,12 @@ import java.util.Locale;
|
||||||
import javax.microedition.khronos.opengles.GL10;
|
import javax.microedition.khronos.opengles.GL10;
|
||||||
import org.godotengine.godot.input.GodotEditText;
|
import org.godotengine.godot.input.GodotEditText;
|
||||||
import org.godotengine.godot.payments.PaymentsManager;
|
import org.godotengine.godot.payments.PaymentsManager;
|
||||||
|
import org.godotengine.godot.utils.PermissionsUtil;
|
||||||
import org.godotengine.godot.xr.XRMode;
|
import org.godotengine.godot.xr.XRMode;
|
||||||
|
|
||||||
public abstract class Godot extends Activity implements SensorEventListener, IDownloaderClient {
|
public abstract 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;
|
|
||||||
static final int REQUEST_CAMERA_PERMISSION = 2;
|
|
||||||
static final int REQUEST_VIBRATE_PERMISSION = 3;
|
|
||||||
private IStub mDownloaderClientStub;
|
private IStub mDownloaderClientStub;
|
||||||
private TextView mStatusText;
|
private TextView mStatusText;
|
||||||
private TextView mProgressFraction;
|
private TextView mProgressFraction;
|
||||||
|
@ -1007,32 +1003,15 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requestPermission(String p_name) {
|
public boolean requestPermission(String p_name) {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
return PermissionsUtil.requestPermission(p_name, this);
|
||||||
// Not necessary, asked on install already
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_name.equals("RECORD_AUDIO")) {
|
public boolean requestPermissions() {
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
|
return PermissionsUtil.requestManifestPermissions(this);
|
||||||
requestPermissions(new String[] { Manifest.permission.RECORD_AUDIO }, REQUEST_RECORD_AUDIO_PERMISSION);
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_name.equals("CAMERA")) {
|
public String[] getGrantedPermissions() {
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
return PermissionsUtil.getGrantedPermissions(this);
|
||||||
requestPermissions(new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA_PERMISSION);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p_name.equals("VIBRATE")) {
|
|
||||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
requestPermissions(new String[] { Manifest.permission.VIBRATE }, REQUEST_VIBRATE_PERMISSION);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,157 @@
|
||||||
|
package org.godotengine.godot.utils;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.PermissionInfo;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import org.godotengine.godot.Godot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class includes utility functions for Android permissions related operations.
|
||||||
|
* @author Cagdas Caglak <cagdascaglak@gmail.com>
|
||||||
|
*/
|
||||||
|
public final class PermissionsUtil {
|
||||||
|
|
||||||
|
static final int REQUEST_RECORD_AUDIO_PERMISSION = 1;
|
||||||
|
static final int REQUEST_CAMERA_PERMISSION = 2;
|
||||||
|
static final int REQUEST_VIBRATE_PERMISSION = 3;
|
||||||
|
static final int REQUEST_ALL_PERMISSION_REQ_CODE = 1001;
|
||||||
|
|
||||||
|
private PermissionsUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request a dangerous permission. name must be specified in <a href="https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/res/AndroidManifest.xml">this</a>
|
||||||
|
* @param name the name of the requested permission.
|
||||||
|
* @param activity the caller activity for this method.
|
||||||
|
* @return true/false. "true" if permission was granted otherwise returns "false".
|
||||||
|
*/
|
||||||
|
public static boolean requestPermission(String name, Godot activity) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
|
// Not necessary, asked on install already
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("RECORD_AUDIO") && ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
activity.requestPermissions(new String[] { Manifest.permission.RECORD_AUDIO }, REQUEST_RECORD_AUDIO_PERMISSION);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("CAMERA") && ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
activity.requestPermissions(new String[] { Manifest.permission.CAMERA }, REQUEST_CAMERA_PERMISSION);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name.equals("VIBRATE") && ContextCompat.checkSelfPermission(activity, Manifest.permission.VIBRATE) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
activity.requestPermissions(new String[] { Manifest.permission.VIBRATE }, REQUEST_VIBRATE_PERMISSION);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request dangerous permissions which are defined in the Android manifest file from the user.
|
||||||
|
* @param activity the caller activity for this method.
|
||||||
|
* @return true/false. "true" if all permissions were granted otherwise returns "false".
|
||||||
|
*/
|
||||||
|
public static boolean requestManifestPermissions(Godot activity) {
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] manifestPermissions;
|
||||||
|
try {
|
||||||
|
manifestPermissions = getManifestPermissions(activity);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (manifestPermissions == null || manifestPermissions.length == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
List<String> dangerousPermissions = new ArrayList<>();
|
||||||
|
for (String manifestPermission : manifestPermissions) {
|
||||||
|
try {
|
||||||
|
PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
|
||||||
|
int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
|
||||||
|
if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) != PackageManager.PERMISSION_GRANTED) {
|
||||||
|
dangerousPermissions.add(manifestPermission);
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dangerousPermissions.isEmpty()) {
|
||||||
|
// If list is empty, all of dangerous permissions were granted.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] requestedPermissions = dangerousPermissions.toArray(new String[0]);
|
||||||
|
activity.requestPermissions(requestedPermissions, REQUEST_ALL_PERMISSION_REQ_CODE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With this function you can get the list of dangerous permissions that have been granted to the Android application.
|
||||||
|
* @param activity the caller activity for this method.
|
||||||
|
* @return granted permissions list
|
||||||
|
*/
|
||||||
|
public static String[] getGrantedPermissions(Godot activity) {
|
||||||
|
String[] manifestPermissions;
|
||||||
|
try {
|
||||||
|
manifestPermissions = getManifestPermissions(activity);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
if (manifestPermissions == null || manifestPermissions.length == 0)
|
||||||
|
return new String[0];
|
||||||
|
|
||||||
|
List<String> dangerousPermissions = new ArrayList<>();
|
||||||
|
for (String manifestPermission : manifestPermissions) {
|
||||||
|
try {
|
||||||
|
PermissionInfo permissionInfo = getPermissionInfo(activity, manifestPermission);
|
||||||
|
int protectionLevel = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? permissionInfo.getProtection() : permissionInfo.protectionLevel;
|
||||||
|
if (protectionLevel == PermissionInfo.PROTECTION_DANGEROUS && ContextCompat.checkSelfPermission(activity, manifestPermission) == PackageManager.PERMISSION_GRANTED) {
|
||||||
|
dangerousPermissions.add(manifestPermission);
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dangerousPermissions.toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the permissions defined in the AndroidManifest.xml file.
|
||||||
|
* @param activity the caller activity for this method.
|
||||||
|
* @return manifest permissions list
|
||||||
|
* @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found.
|
||||||
|
*/
|
||||||
|
private static String[] getManifestPermissions(Godot activity) throws PackageManager.NameNotFoundException {
|
||||||
|
PackageManager packageManager = activity.getPackageManager();
|
||||||
|
PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS);
|
||||||
|
return packageInfo.requestedPermissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the information of the desired permission.
|
||||||
|
* @param activity the caller activity for this method.
|
||||||
|
* @param permission the name of the permission.
|
||||||
|
* @return permission info object
|
||||||
|
* @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found.
|
||||||
|
*/
|
||||||
|
private static PermissionInfo getPermissionInfo(Godot activity, String permission) throws PackageManager.NameNotFoundException {
|
||||||
|
PackageManager packageManager = activity.getPackageManager();
|
||||||
|
return packageManager.getPermissionInfo(permission, 0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1393,6 +1393,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_requestPermissionResu
|
||||||
if (permission == "android.permission.RECORD_AUDIO" && p_result) {
|
if (permission == "android.permission.RECORD_AUDIO" && p_result) {
|
||||||
AudioDriver::get_singleton()->capture_start();
|
AudioDriver::get_singleton()->capture_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (os_android->get_main_loop()) {
|
||||||
|
os_android->get_main_loop()->emit_signal("on_request_permissions_result", permission, p_result == JNI_TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz) {
|
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_onRendererResumed(JNIEnv *env, jclass clazz) {
|
||||||
|
|
|
@ -59,6 +59,8 @@ GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
|
||||||
_get_clipboard = p_env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
|
_get_clipboard = p_env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
|
||||||
_set_clipboard = p_env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
|
_set_clipboard = p_env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
|
||||||
_request_permission = p_env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z");
|
_request_permission = p_env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z");
|
||||||
|
_request_permissions = p_env->GetMethodID(cls, "requestPermissions", "()Z");
|
||||||
|
_get_granted_permissions = p_env->GetMethodID(cls, "getGrantedPermissions", "()[Ljava/lang/String;");
|
||||||
_init_input_devices = p_env->GetMethodID(cls, "initInputDevices", "()V");
|
_init_input_devices = p_env->GetMethodID(cls, "initInputDevices", "()V");
|
||||||
_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;");
|
_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;");
|
||||||
_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z");
|
_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z");
|
||||||
|
@ -199,6 +201,34 @@ bool GodotJavaWrapper::request_permission(const String &p_name) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GodotJavaWrapper::request_permissions() {
|
||||||
|
if (_request_permissions) {
|
||||||
|
JNIEnv *env = ThreadAndroid::get_env();
|
||||||
|
return env->CallBooleanMethod(godot_instance, _request_permissions);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> GodotJavaWrapper::get_granted_permissions() const {
|
||||||
|
Vector<String> permissions_list;
|
||||||
|
if (_get_granted_permissions) {
|
||||||
|
JNIEnv *env = ThreadAndroid::get_env();
|
||||||
|
jobject permissions_object = env->CallObjectMethod(godot_instance, _get_granted_permissions);
|
||||||
|
jobjectArray *arr = reinterpret_cast<jobjectArray *>(&permissions_object);
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
jsize len = env->GetArrayLength(*arr);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
jstring jstr = (jstring)env->GetObjectArrayElement(*arr, i);
|
||||||
|
String str = jstring_to_string(jstr, env);
|
||||||
|
permissions_list.push_back(str);
|
||||||
|
env->DeleteLocalRef(jstr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return permissions_list;
|
||||||
|
}
|
||||||
|
|
||||||
void GodotJavaWrapper::init_input_devices() {
|
void GodotJavaWrapper::init_input_devices() {
|
||||||
if (_init_input_devices) {
|
if (_init_input_devices) {
|
||||||
JNIEnv *env = ThreadAndroid::get_env();
|
JNIEnv *env = ThreadAndroid::get_env();
|
||||||
|
|
|
@ -54,6 +54,8 @@ private:
|
||||||
jmethodID _get_clipboard = 0;
|
jmethodID _get_clipboard = 0;
|
||||||
jmethodID _set_clipboard = 0;
|
jmethodID _set_clipboard = 0;
|
||||||
jmethodID _request_permission = 0;
|
jmethodID _request_permission = 0;
|
||||||
|
jmethodID _request_permissions = 0;
|
||||||
|
jmethodID _get_granted_permissions = 0;
|
||||||
jmethodID _init_input_devices = 0;
|
jmethodID _init_input_devices = 0;
|
||||||
jmethodID _get_surface = 0;
|
jmethodID _get_surface = 0;
|
||||||
jmethodID _is_activity_resumed = 0;
|
jmethodID _is_activity_resumed = 0;
|
||||||
|
@ -81,6 +83,8 @@ public:
|
||||||
bool has_set_clipboard();
|
bool has_set_clipboard();
|
||||||
void set_clipboard(const String &p_text);
|
void set_clipboard(const String &p_text);
|
||||||
bool request_permission(const String &p_name);
|
bool request_permission(const String &p_name);
|
||||||
|
bool request_permissions();
|
||||||
|
Vector<String> get_granted_permissions() const;
|
||||||
void init_input_devices();
|
void init_input_devices();
|
||||||
jobject get_surface();
|
jobject get_surface();
|
||||||
bool is_activity_resumed();
|
bool is_activity_resumed();
|
||||||
|
|
|
@ -220,6 +220,16 @@ bool OS_Android::request_permission(const String &p_name) {
|
||||||
return godot_java->request_permission(p_name);
|
return godot_java->request_permission(p_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool OS_Android::request_permissions() {
|
||||||
|
|
||||||
|
return godot_java->request_permissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> OS_Android::get_granted_permissions() const {
|
||||||
|
|
||||||
|
return godot_java->get_granted_permissions();
|
||||||
|
}
|
||||||
|
|
||||||
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);
|
||||||
ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + ".");
|
ERR_FAIL_COND_V_MSG(!p_library_handle, ERR_CANT_OPEN, "Can't open dynamic library: " + p_path + ", error: " + dlerror() + ".");
|
||||||
|
|
|
@ -125,6 +125,8 @@ public:
|
||||||
|
|
||||||
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 bool request_permission(const String &p_name);
|
||||||
|
virtual bool request_permissions();
|
||||||
|
virtual Vector<String> get_granted_permissions() const;
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue