зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1624675 - Remove unused org.mozilla.gecko.permissions. r=snorp
Differential Revision: https://phabricator.services.mozilla.com/D68442 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
cf8805ecf1
Коммит
94059c6d87
|
@ -20,7 +20,6 @@ import android.util.Log;
|
|||
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.annotation.WebRTCJNITarget;
|
||||
import org.mozilla.gecko.permissions.Permissions;
|
||||
|
||||
import org.webrtc.CameraEnumerator;
|
||||
import org.webrtc.CameraEnumerationAndroid.CaptureFormat;
|
||||
|
|
|
@ -1,150 +0,0 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.permissions;
|
||||
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
/**
|
||||
* Helper class to run code blocks depending on whether a user has granted or denied certain runtime permissions.
|
||||
*/
|
||||
public class PermissionBlock {
|
||||
private final PermissionsHelper mHelper;
|
||||
|
||||
private Context mContext;
|
||||
private String[] mPermissions;
|
||||
private boolean mOnUiThread;
|
||||
private boolean mOnBackgroundThread;
|
||||
private Runnable mOnPermissionsGranted;
|
||||
private Runnable mOnPermissionsDenied;
|
||||
private boolean mDoNotPrompt;
|
||||
|
||||
/* package-private */ PermissionBlock(final Context context, final PermissionsHelper helper) {
|
||||
mContext = context;
|
||||
mHelper = helper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the app has been granted the specified permissions.
|
||||
*/
|
||||
public PermissionBlock withPermissions(final @NonNull String... permissions) {
|
||||
mPermissions = permissions;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all callbacks on the UI thread.
|
||||
*/
|
||||
public PermissionBlock onUIThread() {
|
||||
mOnUiThread = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute all callbacks on the background thread.
|
||||
*/
|
||||
public PermissionBlock onBackgroundThread() {
|
||||
mOnBackgroundThread = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not prompt the user to accept the permission if it has not been granted yet.
|
||||
* This also guarantees that the callback will run on the current thread if no callback
|
||||
* thread has been explicitly specified.
|
||||
*/
|
||||
public PermissionBlock doNotPrompt() {
|
||||
mDoNotPrompt = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the condition is true then do not prompt the user to accept the permission if it has not
|
||||
* been granted yet.
|
||||
*/
|
||||
public PermissionBlock doNotPromptIf(final boolean condition) {
|
||||
if (condition) {
|
||||
doNotPrompt();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute this permission block. Calling this method will prompt the user if needed.
|
||||
*/
|
||||
public void run() {
|
||||
run(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the specified runnable if the app has been granted all permissions. Calling this method will prompt the
|
||||
* user if needed.
|
||||
*/
|
||||
public void run(final Runnable onPermissionsGranted) {
|
||||
if (!mDoNotPrompt && !(mContext instanceof Activity)) {
|
||||
throw new IllegalStateException("You need to either specify doNotPrompt() or pass in an Activity context");
|
||||
}
|
||||
|
||||
mOnPermissionsGranted = onPermissionsGranted;
|
||||
|
||||
if (hasPermissions(mContext)) {
|
||||
onPermissionsGranted();
|
||||
} else if (mDoNotPrompt) {
|
||||
onPermissionsDenied();
|
||||
} else {
|
||||
Permissions.prompt((Activity) mContext, this);
|
||||
}
|
||||
|
||||
// This reference is no longer needed. Let's clear it now to avoid memory leaks.
|
||||
mContext = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute this fallback if at least one permission has not been granted.
|
||||
*/
|
||||
public PermissionBlock andFallback(final @NonNull Runnable onPermissionsDenied) {
|
||||
mOnPermissionsDenied = onPermissionsDenied;
|
||||
return this;
|
||||
}
|
||||
|
||||
/* package-private */ void onPermissionsGranted() {
|
||||
executeRunnable(mOnPermissionsGranted);
|
||||
}
|
||||
|
||||
/* package-private */ void onPermissionsDenied() {
|
||||
executeRunnable(mOnPermissionsDenied);
|
||||
}
|
||||
|
||||
private void executeRunnable(final Runnable runnable) {
|
||||
if (runnable == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mOnUiThread && mOnBackgroundThread) {
|
||||
throw new IllegalStateException("Cannot run callback on more than one thread");
|
||||
}
|
||||
|
||||
if (mOnUiThread && !ThreadUtils.isOnUiThread()) {
|
||||
ThreadUtils.runOnUiThread(runnable);
|
||||
} else if (mOnBackgroundThread && !ThreadUtils.isOnBackgroundThread()) {
|
||||
ThreadUtils.postToBackgroundThread(runnable);
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
||||
/* package-private */ String[] getPermissions() {
|
||||
return mPermissions;
|
||||
}
|
||||
|
||||
/* package-private */ boolean hasPermissions(final Context context) {
|
||||
return mHelper.hasPermissions(context, mPermissions);
|
||||
}
|
||||
}
|
|
@ -1,223 +0,0 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.permissions;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
/**
|
||||
* Convenience class for checking and prompting for runtime permissions.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* Permissions.from(activity)
|
||||
* .withPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
* .onUiThread()
|
||||
* .andFallback(onPermissionDenied())
|
||||
* .run(onPermissionGranted())
|
||||
*
|
||||
* This example will run the runnable returned by onPermissionGranted() if the WRITE_EXTERNAL_STORAGE permission is
|
||||
* already granted. Otherwise it will prompt the user and run the runnable returned by onPermissionGranted() or
|
||||
* onPermissionDenied() depending on whether the user accepted or not.
|
||||
* <p>
|
||||
* If onUiThread()/onBackgroundThread() is specified, all callbacks will be run on the respective
|
||||
* thread. Otherwise, the callback may run on the current thread, but will switch to the UI thread
|
||||
* if a permissions prompt is required.
|
||||
*/
|
||||
public class Permissions {
|
||||
private static final Queue<PermissionBlock> waiting = new LinkedList<>();
|
||||
private static final Queue<PermissionBlock> prompt = new LinkedList<>();
|
||||
|
||||
private static PermissionsHelper permissionHelper = new PermissionsHelper();
|
||||
|
||||
/**
|
||||
* Entry point for checking (and optionally prompting for) runtime permissions.
|
||||
*
|
||||
* Note: The provided context needs to be an Activity context in order to prompt. Use doNotPrompt()
|
||||
* for all other contexts.
|
||||
*/
|
||||
public static PermissionBlock from(final @NonNull Context context) {
|
||||
return new PermissionBlock(context, permissionHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will block until the specified permissions have been granted or denied by the user.
|
||||
* If needed the user will be prompted.
|
||||
*
|
||||
* @return true if all of the permissions have been granted. False if any of the permissions have been denied.
|
||||
*/
|
||||
public static boolean waitFor(final @NonNull Activity activity, final String... permissions) {
|
||||
ThreadUtils.assertNotOnUiThread(); // We do not want to block the UI thread.
|
||||
|
||||
// This task will block until all of the permissions have been granted
|
||||
final FutureTask<Boolean> blockingTask = new FutureTask<>(new Callable<Boolean>() {
|
||||
@Override
|
||||
public Boolean call() throws Exception {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// This runnable will cancel the task if any of the permissions have been denied
|
||||
Runnable cancelBlockingTask = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
blockingTask.cancel(true);
|
||||
}
|
||||
};
|
||||
|
||||
Permissions.from(activity)
|
||||
.withPermissions(permissions)
|
||||
.andFallback(cancelBlockingTask)
|
||||
.run(blockingTask);
|
||||
|
||||
try {
|
||||
return blockingTask.get();
|
||||
} catch (InterruptedException | ExecutionException | CancellationException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether you have been granted particular permissions.
|
||||
*/
|
||||
public static boolean has(final Context context, final String... permissions) {
|
||||
return permissionHelper.hasPermissions(context, permissions);
|
||||
}
|
||||
|
||||
/* package-private */ static void setPermissionHelper(final PermissionsHelper permissionHelper) {
|
||||
Permissions.permissionHelper = permissionHelper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for Activity.onRequestPermissionsResult(). All activities that prompt for permissions using this class
|
||||
* should implement onRequestPermissionsResult() and call this method.
|
||||
*/
|
||||
public static synchronized void onRequestPermissionsResult(final @NonNull Activity activity,
|
||||
final @NonNull String[] permissions,
|
||||
final @NonNull int[] grantResults) {
|
||||
processGrantResults(permissions, grantResults);
|
||||
|
||||
processQueue(activity, permissions, grantResults);
|
||||
}
|
||||
|
||||
/* package-private */ static synchronized void prompt(final Activity activity,
|
||||
final PermissionBlock block) {
|
||||
if (prompt.isEmpty()) {
|
||||
prompt.add(block);
|
||||
showPrompt(activity);
|
||||
} else {
|
||||
waiting.add(block);
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized void processGrantResults(final @NonNull String[] permissions,
|
||||
final @NonNull int[] grantResults) {
|
||||
final HashSet<String> grantedPermissions = collectGrantedPermissions(permissions, grantResults);
|
||||
|
||||
while (!prompt.isEmpty()) {
|
||||
final PermissionBlock block = prompt.poll();
|
||||
|
||||
if (allPermissionsGranted(block, grantedPermissions)) {
|
||||
block.onPermissionsGranted();
|
||||
} else {
|
||||
block.onPermissionsDenied();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized void processQueue(final Activity activity,
|
||||
final String[] permissions,
|
||||
final int[] grantResults) {
|
||||
final HashSet<String> deniedPermissions = collectDeniedPermissions(permissions, grantResults);
|
||||
|
||||
while (!waiting.isEmpty()) {
|
||||
final PermissionBlock block = waiting.poll();
|
||||
|
||||
if (block.hasPermissions(activity)) {
|
||||
block.onPermissionsGranted();
|
||||
} else {
|
||||
if (atLeastOnePermissionDenied(block, deniedPermissions)) {
|
||||
// We just prompted the user and one of the permissions of this block has been denied:
|
||||
// There's no reason to instantly prompt again; Just reject without prompting.
|
||||
block.onPermissionsDenied();
|
||||
} else {
|
||||
prompt.add(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!prompt.isEmpty()) {
|
||||
showPrompt(activity);
|
||||
}
|
||||
}
|
||||
|
||||
private static synchronized void showPrompt(final Activity activity) {
|
||||
HashSet<String> permissions = new HashSet<>();
|
||||
|
||||
for (PermissionBlock block : prompt) {
|
||||
Collections.addAll(permissions, block.getPermissions());
|
||||
}
|
||||
|
||||
permissionHelper.prompt(activity, permissions.toArray(new String[permissions.size()]));
|
||||
}
|
||||
|
||||
private static HashSet<String> collectGrantedPermissions(final @NonNull String[] permissions,
|
||||
final @NonNull int[] grantResults) {
|
||||
return filterPermissionsByResult(permissions, grantResults, PackageManager.PERMISSION_GRANTED);
|
||||
}
|
||||
|
||||
private static HashSet<String> collectDeniedPermissions(final @NonNull String[] permissions,
|
||||
final @NonNull int[] grantResults) {
|
||||
return filterPermissionsByResult(permissions, grantResults, PackageManager.PERMISSION_DENIED);
|
||||
}
|
||||
|
||||
private static HashSet<String> filterPermissionsByResult(final @NonNull String[] permissions,
|
||||
final @NonNull int[] grantResults,
|
||||
final int result) {
|
||||
HashSet<String> grantedPermissions = new HashSet<>(permissions.length);
|
||||
for (int i = 0; i < permissions.length; i++) {
|
||||
if (grantResults[i] == result) {
|
||||
grantedPermissions.add(permissions[i]);
|
||||
}
|
||||
}
|
||||
return grantedPermissions;
|
||||
}
|
||||
|
||||
private static boolean allPermissionsGranted(final PermissionBlock block,
|
||||
final HashSet<String> grantedPermissions) {
|
||||
for (String permission : block.getPermissions()) {
|
||||
if (!grantedPermissions.contains(permission)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean atLeastOnePermissionDenied(final PermissionBlock block,
|
||||
final HashSet<String> deniedPermissions) {
|
||||
for (String permission : block.getPermissions()) {
|
||||
if (deniedPermissions.contains(permission)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.permissions;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
/* package-private */ class PermissionsHelper {
|
||||
private static final int PERMISSIONS_REQUEST_CODE = 212;
|
||||
|
||||
public boolean hasPermissions(final Context context, final String... permissions) {
|
||||
for (String permission : permissions) {
|
||||
final int permissionCheck = ContextCompat.checkSelfPermission(context, permission);
|
||||
|
||||
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void prompt(final Activity activity, final String[] permissions) {
|
||||
ActivityCompat.requestPermissions(activity, permissions, PERMISSIONS_REQUEST_CODE);
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче