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

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java

Issue 2496473003: Allow modal permission prompts on Android to request system permissions. (Closed)
Patch Set: -enum Created 4 years, 1 month 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: chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java
index 2ebd1f03349e5cdd82927b33bb54aacc7d3d1dbd..1589d807dbd4e313543cc9f91a562fad7addd9db 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java
@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.permissions;
import android.app.Activity;
import android.content.DialogInterface;
+import android.support.annotation.IntDef;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SwitchCompat;
import android.text.SpannableStringBuilder;
@@ -21,6 +22,8 @@ import org.chromium.base.VisibleForTesting;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.R;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.LinkedList;
import java.util.List;
@@ -33,11 +36,23 @@ import java.util.List;
* visible on the screen at once. Any additional request for a modal permissions dialog is queued,
* and will be displayed once the user responds to the current dialog.
*/
-public class PermissionDialogController {
+public class PermissionDialogController implements AndroidPermissionRequester.RequestDelegate {
+ private static final int NOT_DECIDED = 0;
+ private static final int ACCEPTED = 1;
+ private static final int CANCELED = 2;
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({NOT_DECIDED, ACCEPTED, CANCELED})
+ private @interface Decision {}
+
private AlertDialog mDialog;
private SwitchCompat mSwitchView;
+ private PermissionDialogDelegate mDialogDelegate;
private List<PermissionDialogDelegate> mRequestQueue;
+ /** Whether a decision has been made for the current dialog. */
+ @Decision private int mDecision;
+
// Static holder to ensure safe initialization of the singleton instance.
private static class Holder {
private static final PermissionDialogController sInstance =
@@ -50,6 +65,7 @@ public class PermissionDialogController {
private PermissionDialogController() {
mRequestQueue = new LinkedList<>();
+ mDecision = NOT_DECIDED;
}
/**
@@ -83,14 +99,27 @@ public class PermissionDialogController {
return mDialog;
}
+ @Override
+ public void onAndroidPermissionAccepted() {
+ mDialogDelegate.onAccept(mSwitchView.isChecked());
+ scheduleDisplay();
+ }
+
+ @Override
+ public void onAndroidPermissionCanceled() {
+ mDialogDelegate.onDismiss();
+ scheduleDisplay();
+ }
+
/**
* Shows the dialog asking the user for a web API permission.
*/
public void showDialog() {
if (mRequestQueue.isEmpty()) return;
- final PermissionDialogDelegate delegate = mRequestQueue.remove(0);
- Activity activity = delegate.getActivity();
+ mDecision = NOT_DECIDED;
+ mDialogDelegate = mRequestQueue.remove(0);
+ Activity activity = mDialogDelegate.getActivity();
LayoutInflater inflater = LayoutInflater.from(activity);
View view = inflater.inflate(R.layout.permission_dialog, null);
AlertDialog.Builder builder = new AlertDialog.Builder(activity, R.style.AlertDialogTheme);
@@ -100,17 +129,18 @@ public class PermissionDialogController {
mDialog.setCanceledOnTouchOutside(false);
TextView messageTextView = (TextView) view.findViewById(R.id.text);
- messageTextView.setText(prepareMainMessageString(delegate));
+ messageTextView.setText(prepareMainMessageString(mDialogDelegate));
messageTextView.setVisibility(View.VISIBLE);
- messageTextView.announceForAccessibility(delegate.getMessageText());
- messageTextView.setCompoundDrawablesWithIntrinsicBounds(delegate.getDrawableId(), 0, 0, 0);
+ messageTextView.announceForAccessibility(mDialogDelegate.getMessageText());
+ messageTextView.setCompoundDrawablesWithIntrinsicBounds(
+ mDialogDelegate.getDrawableId(), 0, 0, 0);
messageTextView.setMovementMethod(LinkMovementMethod.getInstance());
mSwitchView = (SwitchCompat) view.findViewById(R.id.permission_dialog_persist_toggle);
mSwitchView.setChecked(true);
TextView toggleTextView =
(TextView) view.findViewById(R.id.permission_dialog_persist_message);
- if (delegate.shouldShowPersistenceToggle()) {
+ if (mDialogDelegate.shouldShowPersistenceToggle()) {
mSwitchView.setVisibility(View.VISIBLE);
String toggleMessage =
mDialog.getContext().getString(R.string.permission_prompt_persist_text);
@@ -128,20 +158,19 @@ public class PermissionDialogController {
// Set the buttons to call the appropriate delegate methods. When the dialog is dismissed,
// the delegate's native pointers are freed, and the next queued dialog (if any) is
// displayed.
- mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
- delegate.getPrimaryButtonText(),
+ mDialog.setButton(DialogInterface.BUTTON_POSITIVE, mDialogDelegate.getPrimaryButtonText(),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
- delegate.onAccept(mSwitchView.isChecked());
+ mDecision = ACCEPTED;
}
});
- mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, delegate.getSecondaryButtonText(),
+ mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, mDialogDelegate.getSecondaryButtonText(),
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
- delegate.onCancel(mSwitchView.isChecked());
+ mDecision = CANCELED;
}
});
@@ -151,8 +180,29 @@ public class PermissionDialogController {
@Override
public void onDismiss(DialogInterface dialog) {
mDialog = null;
- delegate.onDismiss();
- scheduleDisplay();
+ if (mDecision == ACCEPTED) {
+ // Request Android permissions if necessary. This will call back into either
+ // onAndroidPermissionAccepted or onAndroidPermissionCanceled, which will
+ // schedule the next permission dialog.
+ AndroidPermissionRequester requester = new AndroidPermissionRequester(
+ mDialogDelegate.getWindow(), PermissionDialogController.this,
+ mDialogDelegate.getContentSettings());
+ if (requester.shouldSkipPermissionRequest()) {
+ onAndroidPermissionAccepted();
+ } else {
+ requester.requestAndroidPermissions();
+ }
+ } else {
+ // Otherwise, run the necessary delegate callback immediately and schedule the
+ // next dialog.
+ if (mDecision == CANCELED) {
+ mDialogDelegate.onCancel(mSwitchView.isChecked());
+ } else {
+ mDialogDelegate.onDismiss();
+ }
+ mDialogDelegate.destroy();
+ scheduleDisplay();
+ }
}
});
@@ -176,6 +226,7 @@ public class PermissionDialogController {
fullString.setSpan(new ClickableSpan() {
@Override
public void onClick(View view) {
+ mDecision = NOT_DECIDED;
delegate.onLinkClicked();
if (mDialog != null) mDialog.dismiss();
}

Powered by Google App Engine
This is Rietveld 408576698