| 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);
|
| }
|
| }
|
|
|
|
|