Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(714)

Unified Diff: ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java

Issue 1164973003: Add initial support for runtime permissions in android M. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Appease findbugs Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
diff --git a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
index c83a0cac60cc7f05dac183db393efd6c1663fb36..6e6e308b24a757aced7c88cdc6779df1a682cd39 100644
--- a/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
+++ b/ui/android/java/src/org/chromium/ui/base/ActivityWindowAndroid.java
@@ -9,6 +9,8 @@ import android.app.PendingIntent;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
+import android.os.Handler;
+import android.util.SparseArray;
import android.view.View;
import org.chromium.base.ActivityState;
@@ -16,6 +18,8 @@ import org.chromium.base.ApplicationStatus;
import org.chromium.ui.UiUtils;
import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
/**
* The class provides the WindowAndroid's implementation which requires
@@ -31,6 +35,12 @@ public class ActivityWindowAndroid
private static final String TAG = "ActivityWindowAndroid";
private final WeakReference<Activity> mActivityRef;
+ private final Handler mHandler;
+ private final SparseArray<PermissionCallback> mOutstandingPermissionRequests;
+ private final Runnable mClearPermissionRequestsTask;
+
+ private Method mRequestPermissionsMethod;
+
private int mNextRequestCode = 0;
/**
@@ -51,6 +61,17 @@ public class ActivityWindowAndroid
public ActivityWindowAndroid(Activity activity, boolean listenToActivityState) {
super(activity.getApplicationContext());
mActivityRef = new WeakReference<Activity>(activity);
+ mHandler = new Handler();
+ mOutstandingPermissionRequests = new SparseArray<PermissionCallback>();
+ mClearPermissionRequestsTask = new Runnable() {
+ @Override
+ public void run() {
+ for (int i = 0; i < mOutstandingPermissionRequests.size(); i++) {
+ mOutstandingPermissionRequests.valueAt(i).onRequestPermissionAborted();
+ }
+ mOutstandingPermissionRequests.clear();
+ }
+ };
if (listenToActivityState) {
ApplicationStatus.registerStateListenerForActivity(this, activity);
}
@@ -113,7 +134,13 @@ public class ActivityWindowAndroid
activity.finishActivity(requestCode);
}
- @Override
+ /**
+ * Responds to the intent result if the intent was created by the native window.
+ * @param requestCode Request code of the requested intent.
+ * @param resultCode Result code of the requested intent.
+ * @param data The data returned by the intent.
+ * @return Boolean value of whether the intent was started by the native window.
+ */
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
IntentCallback callback = mOutstandingIntents.get(requestCode);
mOutstandingIntents.delete(requestCode);
@@ -133,6 +160,53 @@ public class ActivityWindowAndroid
}
@Override
+ public void requestPermissions(String[] permissions, PermissionCallback callback) {
+ mHandler.removeCallbacks(mClearPermissionRequestsTask);
+
+ // TODO(tedchoc): Remove the reflection aspect of this once a public M SDK is available.
+ Activity activity = mActivityRef.get();
+ if (activity == null) return;
+
+ if (mRequestPermissionsMethod == null) {
+ try {
+ mRequestPermissionsMethod = Activity.class.getMethod(
+ "requestPermissions", String[].class, int.class);
+ } catch (NoSuchMethodException e) {
+ return;
+ }
+ }
+
+ int requestCode = generateNextRequestCode();
+ mOutstandingPermissionRequests.put(requestCode, callback);
+
+ try {
+ mRequestPermissionsMethod.invoke(activity, permissions, requestCode);
+ } catch (IllegalAccessException e) {
+ mOutstandingPermissionRequests.delete(requestCode);
+ } catch (IllegalArgumentException e) {
+ mOutstandingPermissionRequests.delete(requestCode);
+ } catch (InvocationTargetException e) {
+ mOutstandingPermissionRequests.delete(requestCode);
+ }
+ }
+
+ /**
+ * Responds to a pending permission result.
+ * @param requestCode The unique code for the permission request.
+ * @param permissions The list of permissions in the result.
+ * @param grantResults Whether the permissions were granted.
+ * @return Whether the permission request corresponding to a pending permission request.
+ */
+ public boolean onRequestPermissionsResult(int requestCode, String[] permissions,
+ int[] grantResults) {
+ PermissionCallback callback = mOutstandingPermissionRequests.get(requestCode);
+ mOutstandingPermissionRequests.delete(requestCode);
+ if (callback == null) return false;
+ callback.onRequestPermissionsResult(permissions, grantResults);
+ return true;
+ }
+
+ @Override
public WeakReference<Activity> getActivity() {
// Return a new WeakReference to prevent clients from releasing our internal WeakReference.
return new WeakReference<Activity>(mActivityRef.get());
@@ -144,6 +218,11 @@ public class ActivityWindowAndroid
onActivityPaused();
} else if (newState == ActivityState.RESUMED) {
onActivityResumed();
+
+ // Work around an issue where we do not always get an onRequestPermissionsResult
+ // callback if the user hits the back button in the permission dialog instead
+ // of taking an action.
+ mHandler.post(mClearPermissionRequestsTask);
}
}

Powered by Google App Engine
This is Rietveld 408576698