[Touchless] Support permission dialogs in touchless
This CL ports existing permission dialogs to use TouchlessDialogPresenter
when in touchless mode.
Since permission dialogs in touchless mode have titles that describe the
type of permission, this CL also adds the new GetTypeText() to the
PermissionRequest class.
Link to UX deck: https://docs.google.com/presentation/d/1c-aVSZ_zsBuzCwQ4CrBJppmRQjiupa6PXmlC2OS-F-Q/edit#slide=id.g4fb0666bdb_2_5
Bug: 959204
Change-Id: I749dcfe28b7d5264947325e0d72f62f5ca300c96
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1606564
Commit-Queue: Mehran Mahmoudi <[email protected]>
Reviewed-by: Ted Choc <[email protected]>
Reviewed-by: Matthew Jones <[email protected]>
Reviewed-by: Dominick Ng <[email protected]>
Cr-Commit-Position: refs/heads/master@{#659677}
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 3e705be8..6816e8f6 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -1166,7 +1166,7 @@
"java/src/org/chromium/chrome/browser/payments/ui/SectionUiUtils.java",
"java/src/org/chromium/chrome/browser/payments/ui/ShoppingCart.java",
"java/src/org/chromium/chrome/browser/permissions/AndroidPermissionRequester.java",
- "java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java",
+ "java/src/org/chromium/chrome/browser/permissions/PermissionDialogModel.java",
"java/src/org/chromium/chrome/browser/permissions/PermissionDialogController.java",
"java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java",
"java/src/org/chromium/chrome/browser/permissions/PermissionUmaUtil.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java
deleted file mode 100644
index 80e104d..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionAppModalDialogView.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.permissions;
-
-import android.content.Context;
-import android.support.v4.widget.TextViewCompat;
-import android.text.TextUtils;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.TextView;
-
-import org.chromium.chrome.R;
-import org.chromium.ui.modaldialog.ModalDialogProperties;
-import org.chromium.ui.modelutil.PropertyModel;
-
-/**
- * The Permission dialog that is app modal.
- */
-class PermissionAppModalDialogView {
- private final PropertyModel mDialogModel;
-
- PermissionAppModalDialogView(
- ModalDialogProperties.Controller controller, PermissionDialogDelegate delegate) {
- Context context = delegate.getTab().getActivity();
- LayoutInflater inflater = LayoutInflater.from(context);
- View customView = inflater.inflate(R.layout.permission_dialog, null);
-
- String messageText = delegate.getMessageText();
- assert !TextUtils.isEmpty(messageText);
-
- TextView messageTextView = customView.findViewById(R.id.text);
- messageTextView.setText(messageText);
- TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
- messageTextView, delegate.getDrawableId(), 0, 0, 0);
-
- mDialogModel =
- new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
- .with(ModalDialogProperties.CONTROLLER, controller)
- .with(ModalDialogProperties.CUSTOM_VIEW, customView)
- .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT,
- delegate.getPrimaryButtonText())
- .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT,
- delegate.getSecondaryButtonText())
- .with(ModalDialogProperties.CONTENT_DESCRIPTION, delegate.getMessageText())
- .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true)
- .build();
- }
-
- /**
- * @return The dialog model for the permission dialog.
- */
- PropertyModel getDialogModel() {
- return mDialogModel;
- }
-}
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 2174044..bd5715a 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
@@ -45,7 +45,7 @@
int REQUEST_ANDROID_PERMISSIONS = 5;
}
- private PermissionAppModalDialogView mAppModalDialogView;
+ private PropertyModel mDialogModel;
private PermissionDialogDelegate mDialogDelegate;
private ModalDialogManager mModalDialogManager;
@@ -189,9 +189,8 @@
}
mModalDialogManager = mDialogDelegate.getTab().getActivity().getModalDialogManager();
- mAppModalDialogView = new PermissionAppModalDialogView(this, mDialogDelegate);
- mModalDialogManager.showDialog(
- mAppModalDialogView.getDialogModel(), ModalDialogManager.ModalDialogType.TAB);
+ mDialogModel = PermissionDialogModel.getModel(this, mDialogDelegate);
+ mModalDialogManager.showDialog(mDialogModel, ModalDialogManager.ModalDialogType.TAB);
mState = State.PROMPT_OPEN;
}
@@ -202,8 +201,8 @@
// may be called after onClick and before onDismiss, or before both of those listeners.
mDialogDelegate = null;
if (mState == State.PROMPT_OPEN) {
- mModalDialogManager.dismissDialog(mAppModalDialogView.getDialogModel(),
- DialogDismissalCause.DISMISSED_BY_NATIVE);
+ mModalDialogManager.dismissDialog(
+ mDialogModel, DialogDismissalCause.DISMISSED_BY_NATIVE);
} else {
assert mState == State.PROMPT_PENDING || mState == State.REQUEST_ANDROID_PERMISSIONS
|| mState == State.PROMPT_DENIED || mState == State.PROMPT_ACCEPTED;
@@ -221,7 +220,7 @@
// call this handler after the primary/secondary handler.
// When the dialog is dismissed, the delegate's native pointers are
// freed, and the next queued dialog (if any) is displayed.
- mAppModalDialogView = null;
+ mDialogModel = null;
if (mDialogDelegate == null) {
// We get into here if a tab navigates or is closed underneath the
// prompt.
@@ -286,6 +285,6 @@
@VisibleForTesting
public void clickButtonForTest(@ModalDialogProperties.ButtonType int buttonType) {
- onClick(mAppModalDialogView.getDialogModel(), buttonType);
+ onClick(mDialogModel, buttonType);
}
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java
index 5b37eb2..e3016ca8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogDelegate.java
@@ -29,6 +29,9 @@
/** The icon to display in the dialog. */
private int mDrawableId;
+ /** Title text that can be shown in the dialog. */
+ private String mTitleText;
+
/** Text shown in the dialog. */
private String mMessageText;
@@ -53,6 +56,10 @@
return mDrawableId;
}
+ public String getTitleText() {
+ return mTitleText;
+ }
+
public String getMessageText() {
return mMessageText;
}
@@ -105,28 +112,30 @@
* @param tab The tab to create the dialog for.
* @param contentSettingsTypes The content settings types requested by this dialog.
* @param iconResourceId The id of the icon to display in the dialog.
+ * @param title The title to display in the dialog. This is the permission type.
* @param message The message to display in the dialog.
* @param primaryTextButton The text to display on the primary button.
* @param secondaryTextButton The text to display on the primary button.
*/
@CalledByNative
private static PermissionDialogDelegate create(long nativeDelegatePtr, Tab tab,
- int[] contentSettingsTypes, int enumeratedIconId, String message,
+ int[] contentSettingsTypes, int enumeratedIconId, String title, String message,
String primaryButtonText, String secondaryButtonText) {
return new PermissionDialogDelegate(nativeDelegatePtr, tab, contentSettingsTypes,
- enumeratedIconId, message, primaryButtonText, secondaryButtonText);
+ enumeratedIconId, title, message, primaryButtonText, secondaryButtonText);
}
/**
* Upon construction, this class takes ownership of the passed in native delegate.
*/
private PermissionDialogDelegate(long nativeDelegatePtr, Tab tab, int[] contentSettingsTypes,
- int enumeratedIconId, String message, String primaryButtonText,
+ int enumeratedIconId, String title, String message, String primaryButtonText,
String secondaryButtonText) {
mNativeDelegatePtr = nativeDelegatePtr;
mTab = tab;
mContentSettingsTypes = contentSettingsTypes;
mDrawableId = ResourceId.mapToDrawableId(enumeratedIconId);
+ mTitleText = title;
mMessageText = message;
mPrimaryButtonText = primaryButtonText;
mSecondaryButtonText = secondaryButtonText;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogModel.java b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogModel.java
new file mode 100644
index 0000000..d82f58d
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/permissions/PermissionDialogModel.java
@@ -0,0 +1,53 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.permissions;
+
+import android.content.Context;
+import android.support.v4.widget.TextViewCompat;
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.touchless.TouchlessDelegate;
+import org.chromium.chrome.browser.util.FeatureUtilities;
+import org.chromium.ui.modaldialog.ModalDialogProperties;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/**
+ * This class creates the model for permission dialog.
+ */
+class PermissionDialogModel {
+ public static PropertyModel getModel(
+ ModalDialogProperties.Controller controller, PermissionDialogDelegate delegate) {
+ if (FeatureUtilities.isNoTouchModeEnabled()) {
+ return TouchlessDelegate.getTouchlessPermissionDialogModel(controller, delegate);
+ }
+
+ Context context = delegate.getTab().getActivity();
+ LayoutInflater inflater = LayoutInflater.from(context);
+ View customView = inflater.inflate(R.layout.permission_dialog, null);
+
+ String messageText = delegate.getMessageText();
+ assert !TextUtils.isEmpty(messageText);
+
+ TextView messageTextView = customView.findViewById(R.id.text);
+ messageTextView.setText(messageText);
+ TextViewCompat.setCompoundDrawablesRelativeWithIntrinsicBounds(
+ messageTextView, delegate.getDrawableId(), 0, 0, 0);
+
+ return new PropertyModel.Builder(ModalDialogProperties.ALL_KEYS)
+ .with(ModalDialogProperties.CONTROLLER, controller)
+ .with(ModalDialogProperties.CUSTOM_VIEW, customView)
+ .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT,
+ delegate.getPrimaryButtonText())
+ .with(ModalDialogProperties.NEGATIVE_BUTTON_TEXT,
+ delegate.getSecondaryButtonText())
+ .with(ModalDialogProperties.CONTENT_DESCRIPTION, delegate.getMessageText())
+ .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true)
+ .build();
+ }
+}
diff --git a/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java b/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
index 318ccf84..5a551ff 100644
--- a/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
+++ b/chrome/android/touchless/fallback/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
@@ -7,6 +7,9 @@
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.native_page.NativePage;
import org.chromium.chrome.browser.native_page.NativePageHost;
+import org.chromium.chrome.browser.permissions.PermissionDialogDelegate;
+import org.chromium.ui.modaldialog.ModalDialogProperties;
+import org.chromium.ui.modelutil.PropertyModel;
/**
* The fallback version of TouchlessDelegate, when touchless mode isn't enabled.
@@ -35,4 +38,9 @@
public static Class<?> getTouchlessPreferencesClass() {
return null;
}
+
+ public static PropertyModel getTouchlessPermissionDialogModel(
+ ModalDialogProperties.Controller controller, PermissionDialogDelegate delegate) {
+ return null;
+ }
}
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
index 7603a8e..15031a4 100644
--- a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessDelegate.java
@@ -7,9 +7,13 @@
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.native_page.NativePage;
import org.chromium.chrome.browser.native_page.NativePageHost;
+import org.chromium.chrome.browser.permissions.PermissionDialogDelegate;
+import org.chromium.chrome.browser.touchless.permissions.TouchlessPermissionDialogModel;
+import org.chromium.ui.modaldialog.ModalDialogProperties;
+import org.chromium.ui.modelutil.PropertyModel;
/**
- * Provides an entry point into touchless code from the rest of Chrome.
+ * Provides an entry point into touchless code from the rest of Chrome.
*/
public class TouchlessDelegate {
public static final boolean TOUCHLESS_MODE_ENABLED = true;
@@ -35,4 +39,9 @@
public static Class<?> getTouchlessPreferencesClass() {
return TouchlessPreferences.class;
}
+
+ public static PropertyModel getTouchlessPermissionDialogModel(
+ ModalDialogProperties.Controller controller, PermissionDialogDelegate delegate) {
+ return TouchlessPermissionDialogModel.getModel(controller, delegate);
+ }
}
diff --git a/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/permissions/TouchlessPermissionDialogModel.java b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/permissions/TouchlessPermissionDialogModel.java
new file mode 100644
index 0000000..466e7d1
--- /dev/null
+++ b/chrome/android/touchless/java/src/org/chromium/chrome/browser/touchless/permissions/TouchlessPermissionDialogModel.java
@@ -0,0 +1,84 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.touchless.permissions;
+
+import android.content.res.Resources;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffColorFilter;
+import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
+
+import org.chromium.base.ApiCompatibilityUtils;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.permissions.PermissionDialogDelegate;
+import org.chromium.chrome.browser.touchless.dialog.TouchlessDialogProperties;
+import org.chromium.ui.modaldialog.DialogDismissalCause;
+import org.chromium.ui.modaldialog.ModalDialogProperties;
+import org.chromium.ui.modelutil.PropertyModel;
+
+/**
+ * This class creates the model for permission dialog in touchless mode.
+ */
+public class TouchlessPermissionDialogModel {
+ public static PropertyModel getModel(
+ ModalDialogProperties.Controller controller, PermissionDialogDelegate delegate) {
+ Resources resources = delegate.getTab().getActivity().getResources();
+ TouchlessDialogProperties.ActionNames names = new TouchlessDialogProperties.ActionNames();
+ names.cancel = R.string.cancel;
+ names.select = R.string.select;
+ names.alt = 0;
+ Drawable icon =
+ ApiCompatibilityUtils.getDrawable(resources, delegate.getDrawableId()).mutate();
+ icon.setColorFilter(new PorterDuffColorFilter(
+ resources.getColor(R.color.modern_grey_700), PorterDuff.Mode.SRC_ATOP));
+ String messageText = delegate.getMessageText();
+ assert !TextUtils.isEmpty(messageText);
+
+ PropertyModel model =
+ new PropertyModel.Builder(TouchlessDialogProperties.ALL_DIALOG_KEYS)
+ .with(TouchlessDialogProperties.IS_FULLSCREEN, false)
+ .with(TouchlessDialogProperties.PRIORITY,
+ TouchlessDialogProperties.Priority.HIGH)
+ .with(TouchlessDialogProperties.ACTION_NAMES, names)
+ .with(TouchlessDialogProperties.ALT_ACTION, null)
+ .with(ModalDialogProperties.MESSAGE, messageText)
+ .with(ModalDialogProperties.TITLE, delegate.getTitleText())
+ .with(ModalDialogProperties.TITLE_ICON, icon)
+ .with(ModalDialogProperties.CONTROLLER, controller)
+ .with(ModalDialogProperties.FILTER_TOUCH_FOR_SECURITY, true)
+ .with(ModalDialogProperties.CONTENT_DESCRIPTION, delegate.getMessageText())
+ .build();
+
+ PropertyModel[] items = new PropertyModel[]{
+ new PropertyModel
+ .Builder(TouchlessDialogProperties.DialogListItemProperties.ALL_KEYS)
+ .with(TouchlessDialogProperties.DialogListItemProperties.TEXT,
+ delegate.getPrimaryButtonText())
+ .with(TouchlessDialogProperties.DialogListItemProperties.CLICK_LISTENER,
+ (v) -> controller.onClick(model,
+ ModalDialogProperties.ButtonType.POSITIVE))
+ .with(TouchlessDialogProperties.DialogListItemProperties.ICON,
+ ApiCompatibilityUtils.getDrawable(
+ resources, R.drawable.ic_check_circle))
+ .build(),
+ new PropertyModel
+ .Builder(TouchlessDialogProperties.DialogListItemProperties.ALL_KEYS)
+ .with(TouchlessDialogProperties.DialogListItemProperties.TEXT,
+ delegate.getSecondaryButtonText())
+ .with(TouchlessDialogProperties.DialogListItemProperties.CLICK_LISTENER,
+ (v) -> controller.onClick(model,
+ ModalDialogProperties.ButtonType.NEGATIVE))
+ .with(TouchlessDialogProperties.DialogListItemProperties.ICON,
+ ApiCompatibilityUtils.getDrawable(
+ resources, R.drawable.ic_cancel_circle))
+ .build()};
+
+ model.set(TouchlessDialogProperties.LIST_MODELS, items);
+ model.set(TouchlessDialogProperties.CANCEL_ACTION,
+ (v) -> delegate.getTab().getActivity().getModalDialogManager().dismissDialog(model,
+ DialogDismissalCause.NAVIGATE_BACK_OR_TOUCH_OUTSIDE));
+ return model;
+ }
+}
diff --git a/chrome/android/touchless/touchless_java_sources.gni b/chrome/android/touchless/touchless_java_sources.gni
index b377af860..efa2219 100644
--- a/chrome/android/touchless/touchless_java_sources.gni
+++ b/chrome/android/touchless/touchless_java_sources.gni
@@ -49,6 +49,7 @@
"touchless/java/src/org/chromium/chrome/browser/touchless/TouchlessZoomHelper.java",
"touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogPresenter.java",
"touchless/java/src/org/chromium/chrome/browser/touchless/dialog/TouchlessDialogProperties.java",
+ "touchless/java/src/org/chromium/chrome/browser/touchless/permissions/TouchlessPermissionDialogModel.java",
"touchless/java/src/org/chromium/chrome/browser/touchless/snackbar/BlackHoleSnackbarManager.java",
"touchless/java/src/org/chromium/chrome/browser/touchless/ui/iph/KeyFunctionsIPHCoordinator.java",
"touchless/java/src/org/chromium/chrome/browser/touchless/ui/iph/KeyFunctionsIPHMediator.java",
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 6f6a593..ad397367 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -5236,6 +5236,9 @@
<message name="IDS_ACCESSIBILITY_EVENTS_INFOBAR_TEXT" desc="Text requesting permission for a site to listen to accessibility events, for example if the user has a screen reader or braille device enabled">
<ph name="URL">$1<ex>maps.google.com</ex></ph> wants to respond to accessibility events
</message>
+ <message name="IDS_ACCESSIBILITY_EVENTS_PERMISSION_TITLE" desc="Title text for dialog requesting permission for a site to listen to accessibility events, for example if the user has a screen reader or braille device enabled">
+ Accessibility Events
+ </message>
</if>
<!-- Clipboard permission -->
@@ -5246,6 +5249,9 @@
<message name="IDS_CLIPBOARD_INFOBAR_TEXT" desc="Text requesting permission for a site to read data from the system clipboard">
<ph name="URL">$1<ex>maps.google.com</ex></ph> wants to see text and images copied to the clipboard
</message>
+ <message name="IDS_CLIPBOARD_PERMISSION_TITLE" desc="Title text for dialog requesting permission for a site to read data from the system clipboard">
+ Clipboard
+ </message>
</if>
<message name="IDS_ALLOWED_CLIPBOARD_TITLE" desc="Title of the info bubble shown when a site has been allowed access to read the contents of the system clipboard.">
Clipboard read access allowed
@@ -7113,6 +7119,11 @@
<message name="IDS_MULTI_DOWNLOAD_WARNING" desc="Warning invoked if multiple downloads are attempted without user interaction.">
<ph name="ORIGIN">$1<ex>https://backgroundfetch.com</ex></ph> wants to download multiple files
</message>
+ <if expr="is_android">
+ <message name="IDS_MULTI_DOWNLOAD_WARNING_TITLE" desc="Title text for warning dialog invoked if multiple downloads are attempted without user interaction.">
+ Download
+ </message>
+ </if>
<message name="IDS_MULTI_DOWNLOAD_PERMISSION_FRAGMENT" desc="Permission request shown if multiple downloads are attempted without user interaction and there are multiple permissions requested. Follows a prompt: 'This site would like to:'">
Download multiple files
</message>
@@ -7557,6 +7568,11 @@
<message name="IDS_NOTIFICATIONS_INFOBAR_TEXT" desc="Text requesting permission for Web Notifications.">
<ph name="site">$1<ex>mail.google.com</ex></ph> wants to send you notifications
</message>
+ <if expr="is_android">
+ <message name="IDS_NOTIFICATIONS_PERMISSION_TITLE" desc="Title text for dialog requesting permission for Web Notifications.">
+ Notifications
+ </message>
+ </if>
<message name="IDS_NOTIFICATION_PERMISSIONS_FRAGMENT" desc="Permission sentence fragment to show following the prompt 'This site wants to:' in a permissions request">
Show notifications
</message>
@@ -7986,6 +8002,9 @@
<message name="IDS_GEOLOCATION_INFOBAR_TEXT" desc="Mobile: Text requesting permission for a site to access the user's physical location">
<ph name="URL">$1<ex>maps.google.com</ex></ph> wants to use your device's location
</message>
+ <message name="IDS_GEOLOCATION_PERMISSION_TITLE" desc="Mobile: Title text for dialog requesting permission for a site to access the user's physical location">
+ Location
+ </message>
</if>
<message name="IDS_GEOLOCATION_INFOBAR_PERMISSION_FRAGMENT" desc="Permission fragment used in the permission bubble, after 'This site wants to:' asking for permission to access the user's physical location.">
Know your location
@@ -8016,6 +8035,11 @@
<message name="IDS_MIDI_SYSEX_INFOBAR_TEXT" desc="Text requesting permission for a site to access MIDI devices with system exclusive messages.">
<ph name="URL">$1<ex>www.google.com</ex></ph> wants to get full control of your MIDI devices
</message>
+ <if expr="is_android">
+ <message name="IDS_MIDI_SYSEX_PERMISSION_TITLE" desc="Title text for dialog requesting permission for a site to access MIDI devices with system exclusive messages.">
+ MIDI Devices
+ </message>
+ </if>
<message name="IDS_MIDI_SYSEX_PERMISSION_FRAGMENT" desc="Permission asked in the permission bubble when a URL wants to access MIDI devices with system exclusive messages, along with other permissions requests. Preceded by the prompt 'This site would like to:'">
Use your MIDI devices
</message>
@@ -8133,6 +8157,9 @@
<message name="IDS_PROTECTED_MEDIA_IDENTIFIER_PER_DEVICE_PROVISIONING_INFOBAR_TEXT" desc="Text requesting permission for a site to access protected media identifier. It shows the origin of the URL.">
<ph name="URL">$1<ex>https://www.youtube.com</ex></ph> wants to play protected content. Your device's identity will be verified by Google and may be accessed by this site.
</message>
+ <message name="IDS_PROTECTED_MEDIA_IDENTIFIER_PERMISSION_TITLE" desc="Title text for dialog requesting permission for a site to access protected media identifier.">
+ Protected Media Identifier
+ </message>
</if>
<message name="IDS_MANAGE_PASSWORDS_CONFIRM_GENERATED_TEXT" desc="A message that the browser shows after saving a password it has autogenerated for the user. This message appears in a bubble and contains a link to all the user's saved autogenerated passwords. The link text is a separate string in the translation console and appears here as placeholder text.">
View and manage saved passwords in your <ph name="SAVED_PASSWORDS_STORE">$1<ex>Google Account</ex></ph>
@@ -8363,6 +8390,17 @@
<message name="IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_FRAGMENT" desc="Permission fragment shown in the permissions bubble when a web page requests access to the computer's camera.">
Use your camera
</message>
+ <if expr="is_android">
+ <message name="IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_TITLE" desc="Title text for dialog requesting permission for a site to access the device's microphone.">
+ Microphone
+ </message>
+ <message name="IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_TITLE" desc="Title text for dialog requesting permission for a site to access the device's camera.">
+ Camera
+ </message>
+ <message name="IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_TITLE" desc="Title text for dialog requesting permission for a site to access the device's microphone and camera.">
+ Media
+ </message>
+ </if>
<!-- Sensor messages -->
<message name="IDS_SENSORS_ALLOWED_TOOLTIP" desc="Location bar icon tooltip text when a page is allowed to use device's sensors.">
@@ -8416,6 +8454,9 @@
<message name="IDS_REQUEST_LARGE_QUOTA_INFOBAR_TEXT" desc="Mobile: For Android device. Text requesting permission for a site to use a new (larger) quota to persistently store large data on the user's device (e.g. for persistent-type filesystem).">
<ph name="URL">$1<ex>html5rocks.com</ex></ph> wants to permanently store large data on your device
</message>
+ <message name="IDS_REQUEST_QUOTA_PERMISSION_TITLE" desc="Mobile: For Android device. Title text for dialog requesting permission for a site to use a new (larger) quota to persistently store large data on the user's device (e.g. for persistent-type filesystem).">
+ Storage
+ </message>
</if>
<if expr="not is_android">
<message name="IDS_REQUEST_QUOTA_INFOBAR_TEXT" desc="Text requesting permission for a site to use a new (larger) quota to persistently store data on the user's local computer (e.g. for persistent-type filesystem).">
diff --git a/chrome/browser/chrome_quota_permission_context.cc b/chrome/browser/chrome_quota_permission_context.cc
index 79f9fcea..58a99fe 100644
--- a/chrome/browser/chrome_quota_permission_context.cc
+++ b/chrome/browser/chrome_quota_permission_context.cc
@@ -56,6 +56,7 @@
// PermissionRequest:
IconId GetIconId() const override;
#if defined(OS_ANDROID)
+ base::string16 GetTitleText() const override;
base::string16 GetMessageText() const override;
#endif
base::string16 GetMessageTextFragment() const override;
@@ -98,6 +99,10 @@
}
#if defined(OS_ANDROID)
+base::string16 QuotaPermissionRequest::GetTitleText() const {
+ return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_TITLE);
+}
+
base::string16 QuotaPermissionRequest::GetMessageText() const {
// If the site requested larger quota than this threshold, show a different
// message to the user.
diff --git a/chrome/browser/download/download_permission_request.cc b/chrome/browser/download/download_permission_request.cc
index dda8f22..502baf6c 100644
--- a/chrome/browser/download/download_permission_request.cc
+++ b/chrome/browser/download/download_permission_request.cc
@@ -35,6 +35,10 @@
}
#if defined(OS_ANDROID)
+base::string16 DownloadPermissionRequest::GetTitleText() const {
+ return l10n_util::GetStringUTF16(IDS_MULTI_DOWNLOAD_WARNING_TITLE);
+}
+
base::string16 DownloadPermissionRequest::GetMessageText() const {
return l10n_util::GetStringFUTF16(
IDS_MULTI_DOWNLOAD_WARNING,
diff --git a/chrome/browser/download/download_permission_request.h b/chrome/browser/download/download_permission_request.h
index 805e9c2..f44e2d1 100644
--- a/chrome/browser/download/download_permission_request.h
+++ b/chrome/browser/download/download_permission_request.h
@@ -24,6 +24,7 @@
// PermissionRequest:
IconId GetIconId() const override;
#if defined(OS_ANDROID)
+ base::string16 GetTitleText() const override;
base::string16 GetMessageText() const override;
#endif
base::string16 GetMessageTextFragment() const override;
diff --git a/chrome/browser/media/android/cdm/per_device_provisioning_permission.cc b/chrome/browser/media/android/cdm/per_device_provisioning_permission.cc
index ce182496..8b5cf70 100644
--- a/chrome/browser/media/android/cdm/per_device_provisioning_permission.cc
+++ b/chrome/browser/media/android/cdm/per_device_provisioning_permission.cc
@@ -80,6 +80,11 @@
return IDR_ANDROID_INFOBAR_PROTECTED_MEDIA_IDENTIFIER;
}
+ base::string16 GetTitleText() const final {
+ return l10n_util::GetStringUTF16(
+ IDS_PROTECTED_MEDIA_IDENTIFIER_PERMISSION_TITLE);
+ }
+
base::string16 GetMessageText() const final {
// Note that the string is specific to per-device provisioning.
return l10n_util::GetStringFUTF16(
diff --git a/chrome/browser/permissions/mock_permission_request.cc b/chrome/browser/permissions/mock_permission_request.cc
index 720e357..e06e6aa 100644
--- a/chrome/browser/permissions/mock_permission_request.cc
+++ b/chrome/browser/permissions/mock_permission_request.cc
@@ -72,6 +72,9 @@
}
#if defined(OS_ANDROID)
+base::string16 MockPermissionRequest::GetTitleText() const {
+ return text_;
+}
base::string16 MockPermissionRequest::GetMessageText() const {
return text_;
}
diff --git a/chrome/browser/permissions/mock_permission_request.h b/chrome/browser/permissions/mock_permission_request.h
index 4a7c695..c166b6f 100644
--- a/chrome/browser/permissions/mock_permission_request.h
+++ b/chrome/browser/permissions/mock_permission_request.h
@@ -27,6 +27,7 @@
IconId GetIconId() const override;
#if defined(OS_ANDROID)
+ base::string16 GetTitleText() const override;
base::string16 GetMessageText() const override;
#endif
base::string16 GetMessageTextFragment() const override;
diff --git a/chrome/browser/permissions/permission_dialog_delegate.cc b/chrome/browser/permissions/permission_dialog_delegate.cc
index a8e1613d..9f98da2d 100644
--- a/chrome/browser/permissions/permission_dialog_delegate.cc
+++ b/chrome/browser/permissions/permission_dialog_delegate.cc
@@ -65,6 +65,7 @@
env, reinterpret_cast<uintptr_t>(this), tab->GetJavaObject(),
base::android::ToJavaIntArray(env, content_settings_types),
ResourceMapper::MapFromChromiumId(permission_prompt_->GetIconId()),
+ ConvertUTF16ToJavaString(env, permission_prompt_->GetTitleText()),
ConvertUTF16ToJavaString(env, permission_prompt_->GetMessageText()),
primaryButtonText, secondaryButtonText));
}
diff --git a/chrome/browser/permissions/permission_prompt_android.cc b/chrome/browser/permissions/permission_prompt_android.cc
index 2c048dd2..e123033 100644
--- a/chrome/browser/permissions/permission_prompt_android.cc
+++ b/chrome/browser/permissions/permission_prompt_android.cc
@@ -96,6 +96,15 @@
return IDR_ANDROID_INFOBAR_MEDIA_STREAM_CAMERA;
}
+base::string16 PermissionPromptAndroid::GetTitleText() const {
+ const std::vector<PermissionRequest*>& requests = delegate_->Requests();
+ if (requests.size() == 1)
+ return requests[0]->GetTitleText();
+ CheckValidRequestGroup(requests);
+ return l10n_util::GetStringUTF16(
+ IDS_MEDIA_CAPTURE_AUDIO_AND_VIDEO_PERMISSION_TITLE);
+}
+
base::string16 PermissionPromptAndroid::GetMessageText() const {
const std::vector<PermissionRequest*>& requests = delegate_->Requests();
if (requests.size() == 1)
diff --git a/chrome/browser/permissions/permission_prompt_android.h b/chrome/browser/permissions/permission_prompt_android.h
index 4849b1d..6f56c94d 100644
--- a/chrome/browser/permissions/permission_prompt_android.h
+++ b/chrome/browser/permissions/permission_prompt_android.h
@@ -35,6 +35,7 @@
size_t PermissionCount() const;
ContentSettingsType GetContentSettingType(size_t position) const;
int GetIconId() const;
+ base::string16 GetTitleText() const;
base::string16 GetMessageText() const;
private:
diff --git a/chrome/browser/permissions/permission_request.h b/chrome/browser/permissions/permission_request.h
index 61522a7..5aeadb2 100644
--- a/chrome/browser/permissions/permission_request.h
+++ b/chrome/browser/permissions/permission_request.h
@@ -85,6 +85,10 @@
virtual IconId GetIconId() const = 0;
#if defined(OS_ANDROID)
+ // Returns the title of this permission as text. This is currently only used
+ // in touchless mode in Android.
+ virtual base::string16 GetTitleText() const = 0;
+
// Returns the full prompt text for this permission. This is currently only
// used on Android.
virtual base::string16 GetMessageText() const = 0;
diff --git a/chrome/browser/permissions/permission_request_impl.cc b/chrome/browser/permissions/permission_request_impl.cc
index 3eff821f..ff2d8360 100644
--- a/chrome/browser/permissions/permission_request_impl.cc
+++ b/chrome/browser/permissions/permission_request_impl.cc
@@ -90,6 +90,40 @@
}
#if defined(OS_ANDROID)
+base::string16 PermissionRequestImpl::GetTitleText() const {
+ int message_id;
+ switch (content_settings_type_) {
+ case CONTENT_SETTINGS_TYPE_GEOLOCATION:
+ message_id = IDS_GEOLOCATION_PERMISSION_TITLE;
+ break;
+ case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
+ message_id = IDS_NOTIFICATIONS_PERMISSION_TITLE;
+ break;
+ case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
+ message_id = IDS_MIDI_SYSEX_PERMISSION_TITLE;
+ break;
+ case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
+ message_id = IDS_PROTECTED_MEDIA_IDENTIFIER_PERMISSION_TITLE;
+ break;
+ case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
+ message_id = IDS_MEDIA_CAPTURE_AUDIO_ONLY_PERMISSION_TITLE;
+ break;
+ case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
+ message_id = IDS_MEDIA_CAPTURE_VIDEO_ONLY_PERMISSION_TITLE;
+ break;
+ case CONTENT_SETTINGS_TYPE_ACCESSIBILITY_EVENTS:
+ message_id = IDS_ACCESSIBILITY_EVENTS_PERMISSION_TITLE;
+ break;
+ case CONTENT_SETTINGS_TYPE_CLIPBOARD_READ:
+ message_id = IDS_CLIPBOARD_PERMISSION_TITLE;
+ break;
+ default:
+ NOTREACHED();
+ return base::string16();
+ }
+ return l10n_util::GetStringUTF16(message_id);
+}
+
base::string16 PermissionRequestImpl::GetMessageText() const {
int message_id;
switch (content_settings_type_) {
diff --git a/chrome/browser/permissions/permission_request_impl.h b/chrome/browser/permissions/permission_request_impl.h
index b991ff64..3524b3ca 100644
--- a/chrome/browser/permissions/permission_request_impl.h
+++ b/chrome/browser/permissions/permission_request_impl.h
@@ -33,6 +33,7 @@
// PermissionRequest:
IconId GetIconId() const override;
#if defined(OS_ANDROID)
+ base::string16 GetTitleText() const override;
base::string16 GetMessageText() const override;
#endif
base::string16 GetMessageTextFragment() const override;