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