Browse Source

Update to latest support libraries, move permissions stuff to separate package

master
Anthony Restaino 9 years ago
parent
commit
94b69fd328
  1. 10
      app/build.gradle
  2. 3
      app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java
  3. 2
      app/src/main/java/acr/browser/lightning/activity/SettingsActivity.java
  4. 5
      app/src/main/java/acr/browser/lightning/download/LightningDownloadListener.java
  5. 7
      app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java
  6. 176
      app/src/main/java/acr/browser/lightning/permissions/PermissionsManager.java
  7. 57
      app/src/main/java/acr/browser/lightning/permissions/PermissionsResultAction.java
  8. 167
      app/src/main/java/acr/browser/lightning/utils/PermissionsManager.java
  9. 4
      app/src/main/java/acr/browser/lightning/utils/Utils.java
  10. 5
      app/src/main/java/acr/browser/lightning/view/LightningChromeClient.java

10
app/build.gradle

@ -43,7 +43,7 @@ android {
abortOnError true abortOnError true
} }
packagingOptions { packagingOptions {
exclude '.README' exclude '.readme'
} }
} }
@ -56,10 +56,10 @@ dexcount {
} }
dependencies { dependencies {
compile 'com.android.support:palette-v7:23.0.1' compile 'com.android.support:palette-v7:23.1.0'
compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:appcompat-v7:23.1.0'
compile 'com.android.support:design:23.0.1' compile 'com.android.support:design:23.1.0'
compile 'com.android.support:recyclerview-v7:23.0.1' compile 'com.android.support:recyclerview-v7:23.1.0'
compile 'org.jsoup:jsoup:1.8.3' compile 'org.jsoup:jsoup:1.8.3'
compile 'com.squareup:otto:1.3.8' compile 'com.squareup:otto:1.3.8'
compile 'com.google.dagger:dagger:2.0.1' compile 'com.google.dagger:dagger:2.0.1'

3
app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java

@ -4,7 +4,6 @@
package acr.browser.lightning.activity; package acr.browser.lightning.activity;
import android.animation.Animator;
import android.animation.ArgbEvaluator; import android.animation.ArgbEvaluator;
import android.animation.LayoutTransition; import android.animation.LayoutTransition;
import android.animation.ValueAnimator; import android.animation.ValueAnimator;
@ -106,7 +105,7 @@ import acr.browser.lightning.fragment.BookmarksFragment;
import acr.browser.lightning.fragment.TabsFragment; import acr.browser.lightning.fragment.TabsFragment;
import acr.browser.lightning.object.SearchAdapter; import acr.browser.lightning.object.SearchAdapter;
import acr.browser.lightning.receiver.NetworkReceiver; import acr.browser.lightning.receiver.NetworkReceiver;
import acr.browser.lightning.utils.PermissionsManager; import acr.browser.lightning.permissions.PermissionsManager;
import acr.browser.lightning.utils.ProxyUtils; import acr.browser.lightning.utils.ProxyUtils;
import acr.browser.lightning.utils.ThemeUtils; import acr.browser.lightning.utils.ThemeUtils;
import acr.browser.lightning.utils.UrlUtils; import acr.browser.lightning.utils.UrlUtils;

2
app/src/main/java/acr/browser/lightning/activity/SettingsActivity.java

@ -15,7 +15,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import acr.browser.lightning.R; import acr.browser.lightning.R;
import acr.browser.lightning.utils.PermissionsManager; import acr.browser.lightning.permissions.PermissionsManager;
public class SettingsActivity extends ThemableSettingsActivity { public class SettingsActivity extends ThemableSettingsActivity {

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

@ -13,7 +13,8 @@ import android.webkit.URLUtil;
import acr.browser.lightning.R; import acr.browser.lightning.R;
import acr.browser.lightning.constant.Constants; import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.utils.PermissionsManager; import acr.browser.lightning.permissions.PermissionsManager;
import acr.browser.lightning.permissions.PermissionsResultAction;
public class LightningDownloadListener implements DownloadListener { public class LightningDownloadListener implements DownloadListener {
@ -28,7 +29,7 @@ public class LightningDownloadListener implements DownloadListener {
final String contentDisposition, final String mimetype, long contentLength) { final String contentDisposition, final String mimetype, long contentLength) {
PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
new PermissionsManager.PermissionResult() { new PermissionsResultAction() {
@Override @Override
public void onGranted() { public void onGranted() {
String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype);

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

@ -27,7 +27,8 @@ import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.database.BookmarkLocalSync; import acr.browser.lightning.database.BookmarkLocalSync;
import acr.browser.lightning.database.BookmarkManager; import acr.browser.lightning.database.BookmarkManager;
import acr.browser.lightning.database.HistoryItem; import acr.browser.lightning.database.HistoryItem;
import acr.browser.lightning.utils.PermissionsManager; import acr.browser.lightning.permissions.PermissionsManager;
import acr.browser.lightning.permissions.PermissionsResultAction;
import acr.browser.lightning.utils.Utils; import acr.browser.lightning.utils.Utils;
public class BookmarkSettingsFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener { public class BookmarkSettingsFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener {
@ -138,7 +139,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
switch (preference.getKey()) { switch (preference.getKey()) {
case SETTINGS_EXPORT: case SETTINGS_EXPORT:
PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(getActivity(), REQUIRED_PERMISSIONS, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(getActivity(), REQUIRED_PERMISSIONS,
new PermissionsManager.PermissionResult() { new PermissionsResultAction() {
@Override @Override
public void onGranted() { public void onGranted() {
mBookmarkManager.exportBookmarks(getActivity()); mBookmarkManager.exportBookmarks(getActivity());
@ -152,7 +153,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
return true; return true;
case SETTINGS_IMPORT: case SETTINGS_IMPORT:
PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(getActivity(), REQUIRED_PERMISSIONS, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(getActivity(), REQUIRED_PERMISSIONS,
new PermissionsManager.PermissionResult() { new PermissionsResultAction() {
@Override @Override
public void onGranted() { public void onGranted() {
loadFileList(null); loadFileList(null);

176
app/src/main/java/acr/browser/lightning/permissions/PermissionsManager.java

@ -0,0 +1,176 @@
package acr.browser.lightning.permissions;
import android.app.Activity;
import android.app.Fragment;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* A class to help you manage your permissions simply.
*/
public final class PermissionsManager {
private static final String TAG = PermissionsManager.class.getSimpleName();
private static final String[] EMPTY_PERMISSIONS = new String[0];
private static final PermissionsManager INSTANCE = new PermissionsManager();
private final Set<String> mPendingRequests = new HashSet<>(1);
private final List<PermissionsResultAction> mPendingActions = new ArrayList<>(1);
public static PermissionsManager getInstance() {
return INSTANCE;
}
private PermissionsManager() {}
/**
* This method adds the {@link PermissionsResultAction} 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 PermissionsResultAction object so that it will be notified of changes
* made to these permissions.
*
* @param permissions the required permissions for the action to be executed
* @param action the action to add to the current list of pending actions
*/
private synchronized void addPendingAction(@NonNull String[] permissions, @Nullable PermissionsResultAction action) {
if (action == null) {
return;
}
action.registerPermissions(permissions);
mPendingActions.add(action);
}
/**
* This method will request all the permissions declared in your application manifest
* for the specified {@link PermissionsResultAction}. The purpose of this method is to enable
* all permissions to be requested at one shot. The PermissionsResultAction is used to notify
* you of the user allowing or denying each permission. The Activity and PermissionsResultAction
* parameters are both annotated Nullable, but this method will not work if the Activity
* is null. It is only annotated Nullable as a courtesy to prevent crashes in the case
* that you call this from a Fragment where {@link Fragment#getActivity()} could yield
* null. Additionally, you will not receive any notification of permissions being granted
* if you provide a null PermissionsResultAction.
*
* @param activity the Activity necessary to request and check permissions.
* @param action the PermissionsResultAction used to notify you of permissions being accepted.
*/
public synchronized void requestAllManifestPermissionsIfNecessary(final @Nullable Activity activity,
final @Nullable PermissionsResultAction action) {
if (activity == null) {
return;
}
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
PackageInfo packageInfo = null;
try {
Log.d(TAG, activity.getPackageName());
packageInfo = activity.getPackageManager().getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "A problem occurred when retrieving permissions", e);
}
if (packageInfo != null) {
String[] permissions = packageInfo.requestedPermissions;
if (permissions != null) {
for (String perm : permissions) {
Log.d(TAG, "Requesting permission if necessary: " + perm);
}
} else {
permissions = EMPTY_PERMISSIONS;
}
requestPermissionsIfNecessaryForResult(activity, permissions, action);
}
}
});
}
/**
* This method should be used to execute a {@link PermissionsResultAction} 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
* PermissionsResultAction 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 PermissionsResultAction}
* @param action the PermissionsResultAction to notify when the permissions are granted or denied
*/
public synchronized void requestPermissionsIfNecessaryForResult(@Nullable Activity activity,
@NonNull String[] permissions,
@Nullable PermissionsResultAction action) {
if (activity == null) {
return;
}
addPendingAction(permissions, action);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
for (String perm : permissions) {
if (action != null) {
if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) {
action.onResult(perm, PackageManager.PERMISSION_DENIED);
} else {
action.onResult(perm, PackageManager.PERMISSION_GRANTED);
}
}
}
} else {
List<String> permList = new ArrayList<>(1);
for (String perm : permissions) {
if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) {
if (!mPendingRequests.contains(perm)) {
permList.add(perm);
}
} else {
if (action != null) {
action.onResult(perm, PackageManager.PERMISSION_GRANTED);
}
}
}
if (!permList.isEmpty()) {
String[] permsToRequest = permList.toArray(new String[permList.size()]);
mPendingRequests.addAll(permList);
ActivityCompat.requestPermissions(activity, permsToRequest, 1);
}
}
}
/**
* This method notifies the PermissionsManager that the permissions have change. It should
* be called from the Activity callback onRequestPermissionsResult() with the variables
* passed to that method. It will notify all the pending PermissionsResultAction objects currently
* in the queue, and will remove the permissions request from the list of pending requests.
*
* @param permissions the permissions that have changed
* @param results the values for each permission
*/
public synchronized void notifyPermissionsChange(@NonNull String[] permissions, @NonNull int[] results) {
int size = permissions.length;
if (results.length < size) {
size = results.length;
}
for (int n = 0; n < size; n++) {
for (PermissionsResultAction result : mPendingActions) {
result.onResult(permissions[n], results[n]);
mPendingRequests.remove(permissions[n]);
}
}
}
}

57
app/src/main/java/acr/browser/lightning/permissions/PermissionsResultAction.java

@ -0,0 +1,57 @@
package acr.browser.lightning.permissions;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* 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 abstract class PermissionsResultAction {
private final Set<String> mPermissions = new HashSet<>(1);
public abstract void onGranted();
public abstract void onDenied(String permission);
/**
* 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) {
mPermissions.remove(permission);
if (mPermissions.isEmpty()) {
onGranted();
}
} else {
onDenied(permission);
}
}
/**
* This method registers the PermissionsResultAction object for the specified permissions
* so that it will know which permissions to look for changes to. The PermissionsResultAction
* 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);
}
}

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

@ -1,167 +0,0 @@
package acr.browser.lightning.utils;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* A class to help you manage your permissions
*/
public final class PermissionsManager {
private final static PermissionsManager INSTANCE = new PermissionsManager();
private final Set<String> mPendingRequests = new HashSet<>(1);
private final List<PermissionResult> mPendingActions = new ArrayList<>(1);
public static PermissionsManager getInstance() {
return INSTANCE;
}
/**
* 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) {
return;
}
result.registerPermissions(permissions);
mPendingActions.add(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) {
return;
}
addPendingAction(permissions, result);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
for (String perm : permissions) {
if (result != null) {
result.onResult(perm, PackageManager.PERMISSION_GRANTED);
}
}
return;
}
List<String> permList = new ArrayList<>(1);
for (String perm : permissions) {
if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) {
if (!mPendingRequests.contains(perm)) {
permList.add(perm);
}
} else {
if (result != null) {
result.onResult(perm, PackageManager.PERMISSION_GRANTED);
}
}
}
if (!permList.isEmpty()) {
String[] permsToRequest = permList.toArray(new String[permList.size()]);
mPendingRequests.addAll(permList);
ActivityCompat.requestPermissions(activity, permsToRequest, 1);
}
}
/**
* This method notifies the PermissionsManager that the permissions have change. It should
* be called from the Activity callback onRequestPermissionsResult() with the variables
* passed to that method. It will notify all the pending PermissionResult objects currently
* in the queue, and will remove the permissions request from the list of pending requests.
*
* @param permissions the permissions that have changed
* @param results the values for each permission
*/
public synchronized void notifyPermissionsChange(@NonNull String[] permissions, @NonNull int[] results) {
int size = permissions.length;
if (results.length < size) {
size = results.length;
}
for (int n = 0; n < size; n++) {
for (PermissionResult result : mPendingActions) {
result.onResult(permissions[n], results[n]);
mPendingRequests.remove(permissions[n]);
}
}
}
/**
* 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 {
private final Set<String> mPermissions = new HashSet<>(1);
public abstract void onGranted();
public abstract void onDenied(String permission);
/**
* 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) {
mPermissions.remove(permission);
if (mPermissions.isEmpty()) {
onGranted();
}
} else {
onDenied(permission);
}
}
/**
* 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);
}
}
}

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

@ -40,13 +40,15 @@ import java.util.Date;
import acr.browser.lightning.R; import acr.browser.lightning.R;
import acr.browser.lightning.constant.Constants; import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.download.DownloadHandler; import acr.browser.lightning.download.DownloadHandler;
import acr.browser.lightning.permissions.PermissionsManager;
import acr.browser.lightning.permissions.PermissionsResultAction;
public final class Utils { 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().requestPermissionsIfNecessaryForResult(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 PermissionsResultAction() {
@Override @Override
public void onGranted() { public void onGranted() {
String fileName = URLUtil.guessFileName(url, null, null); String fileName = URLUtil.guessFileName(url, null, null);

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

@ -28,7 +28,8 @@ import acr.browser.lightning.app.BrowserApp;
import acr.browser.lightning.bus.BrowserEvents; import acr.browser.lightning.bus.BrowserEvents;
import acr.browser.lightning.constant.Constants; import acr.browser.lightning.constant.Constants;
import acr.browser.lightning.controller.UIController; import acr.browser.lightning.controller.UIController;
import acr.browser.lightning.utils.PermissionsManager; import acr.browser.lightning.permissions.PermissionsManager;
import acr.browser.lightning.permissions.PermissionsResultAction;
import acr.browser.lightning.utils.Utils; import acr.browser.lightning.utils.Utils;
/** /**
@ -113,7 +114,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().requestPermissionsIfNecessaryForResult(mActivity, PERMISSIONS, new PermissionsManager.PermissionResult() { PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity, PERMISSIONS, new PermissionsResultAction() {
@Override @Override
public void onGranted() { public void onGranted() {
final boolean remember = true; final boolean remember = true;

Loading…
Cancel
Save