Browse Source

Document the PermissionsManager

master
Anthony Restaino 9 years ago
parent
commit
ce0e02585c
  1. 2
      app/src/main/java/acr/browser/lightning/download/LightningDownloadListener.java
  2. 6
      app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java
  3. 102
      app/src/main/java/acr/browser/lightning/utils/PermissionsManager.java
  4. 2
      app/src/main/java/acr/browser/lightning/utils/Utils.java
  5. 3
      app/src/main/java/acr/browser/lightning/view/LightningChromeClient.java

2
app/src/main/java/acr/browser/lightning/download/LightningDownloadListener.java

@ -26,7 +26,7 @@ public class LightningDownloadListener implements DownloadListener {
@Override @Override
public void onDownloadStart(final String url, final String userAgent, public void onDownloadStart(final String url, final String userAgent,
final String contentDisposition, final String mimetype, long contentLength) { final String contentDisposition, final String mimetype, long contentLength) {
PermissionsManager.getInstance().requestPermissionsIfNecessary(mActivity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsManager.PermissionResult() { Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsManager.PermissionResult() {
@Override @Override
public void onGranted() { public void onGranted() {

6
app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java

@ -88,7 +88,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
PermissionsManager permissionsManager = PermissionsManager.getInstance(); PermissionsManager permissionsManager = PermissionsManager.getInstance();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
permissionsManager.requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS, null); permissionsManager.requestPermissionsIfNecessaryForResult(getActivity(), REQUIRED_PERMISSIONS, null);
} }
} }
@ -127,7 +127,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
// if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) { // if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) {
// mBookmarkManager.exportBookmarks(getActivity()); // mBookmarkManager.exportBookmarks(getActivity());
// } // }
PermissionsManager.getInstance().requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(getActivity(), REQUIRED_PERMISSIONS,
new PermissionsManager.PermissionResult() { new PermissionsManager.PermissionResult() {
@Override @Override
public void onGranted() { public void onGranted() {
@ -145,7 +145,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
// loadFileList(null); // loadFileList(null);
// createDialog(); // createDialog();
// } // }
PermissionsManager.getInstance().requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(getActivity(), REQUIRED_PERMISSIONS,
new PermissionsManager.PermissionResult() { new PermissionsManager.PermissionResult() {
@Override @Override
public void onGranted() { public void onGranted() {

102
app/src/main/java/acr/browser/lightning/utils/PermissionsManager.java

@ -14,30 +14,53 @@ import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* Copyright 8/22/2015 Anthony Restaino * A class to help you manage your permissions
*/ */
public final class PermissionsManager { public final class PermissionsManager {
private static PermissionsManager mInstance; private final static PermissionsManager INSTANCE = new PermissionsManager();
private final Set<String> mPendingRequests = new HashSet<>(); private final Set<String> mPendingRequests = new HashSet<>(1);
private final List<PermissionResult> mPendingActions = new ArrayList<>(); private final List<PermissionResult> mPendingActions = new ArrayList<>(1);
public static PermissionsManager getInstance() { public static PermissionsManager getInstance() {
if (mInstance == null) { return INSTANCE;
mInstance = new PermissionsManager();
}
return mInstance;
} }
private void addPendingAction(@NonNull String[] permissions, @Nullable PermissionResult result) { /**
* This method adds the {@link PermissionResult} to the current list
* of pending actions that will be completed when the permissions are
* received. The list of permissions passed to this method are registered
* in the PermissionResult object so that it will be notified of changes
* made to these permissions.
*
* @param permissions the required permissions for the result to be executed
* @param result the result to add to the current list of pending actions
*/
private synchronized void addPendingAction(@NonNull String[] permissions, @Nullable PermissionResult result) {
if (result == null) { if (result == null) {
return; return;
} }
result.addPermissions(permissions); result.registerPermissions(permissions);
mPendingActions.add(result); mPendingActions.add(result);
} }
public void requestPermissionsIfNecessary(@Nullable Activity activity, @NonNull String[] permissions, @Nullable PermissionResult result) { /**
* This method should be used to execute a {@link PermissionResult} for the array
* of permissions passed to this method. This method will request the permissions if
* they need to be requested (i.e. we don't have permission yet) and will add the
* PermissionResult to the queue to be notified of permissions being granted or
* denied. In the case of pre-Android Marshmallow, permissions will be granted immediately.
* The Activity variable is nullable, but if it is null, the method will fail to execute.
* This is only nullable as a courtesy for Fragments where getActivity() may yeild null
* if the Fragment is not currently added to its parent Activity.
*
* @param activity the activity necessary to request the permissions
* @param permissions the list of permissions to request for the {@link PermissionResult}
* @param result the PermissionResult to notify when the permissions are granted or denied
*/
public synchronized void requestPermissionsIfNecessaryForResult(@Nullable Activity activity,
@NonNull String[] permissions,
@Nullable PermissionResult result) {
if (activity == null) { if (activity == null) {
return; return;
} }
@ -50,7 +73,7 @@ public final class PermissionsManager {
} }
return; return;
} }
List<String> permList = new ArrayList<>(); List<String> permList = new ArrayList<>(1);
for (String perm : permissions) { for (String perm : permissions) {
if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) {
if (!mPendingRequests.contains(perm)) { if (!mPendingRequests.contains(perm)) {
@ -70,20 +93,16 @@ public final class PermissionsManager {
} }
public static boolean checkPermissions(Activity activity, @NonNull String[] permissions) { /**
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { * This method notifies the PermissionsManager that the permissions have change. It should
return true; * be called from the Activity callback onRequestPermissionsResult() with the variables
} else if (activity == null) { * passed to that method. It will notify all the pending PermissionResult objects currently
return false; * in the queue, and will remove the permissions request from the list of pending requests.
} *
boolean permissionsNecessary = true; * @param permissions the permissions that have changed
for (String perm : permissions) { * @param results the values for each permission
permissionsNecessary &= activity.checkSelfPermission(perm) == PackageManager.PERMISSION_GRANTED; */
} public synchronized void notifyPermissionsChange(@NonNull String[] permissions, @NonNull int[] results) {
return permissionsNecessary;
}
public void notifyPermissionsChange(@NonNull String[] permissions, @NonNull int[] results) {
int size = permissions.length; int size = permissions.length;
if (results.length < size) { if (results.length < size) {
size = results.length; size = results.length;
@ -96,15 +115,33 @@ public final class PermissionsManager {
} }
} }
/**
* This abstract class should be used to create an if/else action that the PermissionsManager
* can execute when the permissions you request are granted or denied. Simple use involves
* creating an anonymous instance of it and passing that instance to the
* requestPermissionsIfNecessaryForResult method. The result will be sent back to you as
* either onGranted (all permissions have been granted), or onDenied (a required permission
* has been denied). Ideally you put your functionality in the onGranted method and notify
* the user what won't work in the onDenied method.
*/
public static abstract class PermissionResult { public static abstract class PermissionResult {
private Set<String> mPermissions = new HashSet<>(); private final Set<String> mPermissions = new HashSet<>(1);
public abstract void onGranted(); public abstract void onGranted();
public abstract void onDenied(String permission); public abstract void onDenied(String permission);
public void onResult(String permission, int result) { /**
* This method is called when a particular permission has changed.
* This method will be called for all permissions, so this method determines
* if the permission affects the state or not and whether it can proceed with
* calling onGranted or if onDenied should be called.
*
* @param permission the permission that changed
* @param result the result for that permission
*/
public synchronized final void onResult(String permission, int result) {
if (result == PackageManager.PERMISSION_GRANTED) { if (result == PackageManager.PERMISSION_GRANTED) {
mPermissions.remove(permission); mPermissions.remove(permission);
if (mPermissions.isEmpty()) { if (mPermissions.isEmpty()) {
@ -115,7 +152,14 @@ public final class PermissionsManager {
} }
} }
public void addPermissions(@NonNull String[] perms) { /**
* This method registers the PermissionResult object for the specified permissions
* so that it will know which permissions to look for changes to. The PermissionResult
* will then know to look out for changes to these permissions.
*
* @param perms the permissions to listen for
*/
public synchronized final void registerPermissions(@NonNull String[] perms) {
Collections.addAll(mPermissions, perms); Collections.addAll(mPermissions, perms);
} }
} }

2
app/src/main/java/acr/browser/lightning/utils/Utils.java

@ -45,7 +45,7 @@ public final class Utils {
public static void downloadFile(final Activity activity, final String url, public static void downloadFile(final Activity activity, final String url,
final String userAgent, final String contentDisposition) { final String userAgent, final String contentDisposition) {
PermissionsManager.getInstance().requestPermissionsIfNecessary(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsManager.PermissionResult() { Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsManager.PermissionResult() {
@Override @Override
public void onGranted() { public void onGranted() {

3
app/src/main/java/acr/browser/lightning/view/LightningChromeClient.java

@ -1,7 +1,6 @@
package acr.browser.lightning.view; package acr.browser.lightning.view;
import android.Manifest; import android.Manifest;
import android.app.Activity;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -114,7 +113,7 @@ class LightningChromeClient extends WebChromeClient {
@Override @Override
public void onGeolocationPermissionsShowPrompt(final String origin, public void onGeolocationPermissionsShowPrompt(final String origin,
final GeolocationPermissions.Callback callback) { final GeolocationPermissions.Callback callback) {
PermissionsManager.getInstance().requestPermissionsIfNecessary(mActivity, PERMISSIONS, new PermissionsManager.PermissionResult() { PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity, PERMISSIONS, new PermissionsManager.PermissionResult() {
@Override @Override
public void onGranted() { public void onGranted() {
final boolean remember = true; final boolean remember = true;

Loading…
Cancel
Save