godot/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java
Rémi Verschelde e637fe9dd3 clang-format: Add JavaImportGroups for Java code
(cherry picked from commit 6038325470)
2020-05-07 13:36:27 +02:00

213 lines
9.3 KiB
Java

/*************************************************************************/
/* PermissionsUtil.java */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
package org.godotengine.godot.utils;
import org.godotengine.godot.Godot;
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 android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* This class includes utility functions for Android permissions related operations.
* @author Cagdas Caglak <cagdascaglak@gmail.com>
*/
public final class PermissionsUtil {
private static final String TAG = PermissionsUtil.class.getSimpleName();
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.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) {
// Skip this permission and continue.
Log.w(TAG, "Unable to identify permission " + manifestPermission, e);
}
}
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.length == 0)
return manifestPermissions;
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) {
// Skip this permission and continue.
Log.w(TAG, "Unable to identify permission " + manifestPermission, e);
}
}
return dangerousPermissions.toArray(new String[0]);
}
/**
* Check if the given permission is in the AndroidManifest.xml file.
* @param activity the caller activity for this method.
* @param permission the permession to look for in the manifest file.
* @return "true" if the permission is in the manifest file of the activity, "false" otherwise.
*/
public static boolean hasManifestPermission(Godot activity, String permission) {
try {
for (String p : getManifestPermissions(activity)) {
if (permission.equals(p))
return true;
}
} catch (PackageManager.NameNotFoundException e) {
}
return false;
}
/**
* 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);
if (packageInfo.requestedPermissions == null)
return new String[0];
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);
}
}