Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.infobar; | 5 package org.chromium.chrome.browser.permissions; |
| 6 | 6 |
| 7 import android.app.Activity; | 7 import android.app.Activity; |
| 8 import android.content.DialogInterface; | 8 import android.content.DialogInterface; |
| 9 import android.content.pm.PackageManager; | 9 import android.content.pm.PackageManager; |
| 10 import android.graphics.Bitmap; | |
| 11 import android.support.v7.app.AlertDialog; | 10 import android.support.v7.app.AlertDialog; |
| 12 import android.support.v7.widget.SwitchCompat; | |
| 13 import android.util.SparseArray; | 11 import android.util.SparseArray; |
| 14 import android.view.View; | 12 import android.view.View; |
| 15 import android.widget.TextView; | 13 import android.widget.TextView; |
| 16 | 14 |
| 17 import org.chromium.base.annotations.CalledByNative; | |
| 18 import org.chromium.chrome.R; | 15 import org.chromium.chrome.R; |
| 19 import org.chromium.chrome.browser.ContentSettingsType; | 16 import org.chromium.chrome.browser.ContentSettingsType; |
| 20 import org.chromium.chrome.browser.ResourceId; | |
| 21 import org.chromium.chrome.browser.preferences.PrefServiceBridge; | 17 import org.chromium.chrome.browser.preferences.PrefServiceBridge; |
| 22 import org.chromium.chrome.browser.tab.Tab; | |
| 23 import org.chromium.ui.base.WindowAndroid; | 18 import org.chromium.ui.base.WindowAndroid; |
| 24 import org.chromium.ui.base.WindowAndroid.PermissionCallback; | 19 import org.chromium.ui.base.WindowAndroid.PermissionCallback; |
| 25 | 20 |
| 26 /** | 21 /** |
| 27 * An infobar used for prompting the user to grant a web API permission. | 22 * An object to handle requesting native permissions from Android when the user grants a website |
| 28 * | 23 * a permission. |
| 29 */ | 24 */ |
| 30 public class PermissionInfoBar extends ConfirmInfoBar { | 25 public class AndroidPermissionRequester { |
| 31 | |
| 32 /** Whether or not to show a toggle for opting out of persisting the decisio n. */ | |
| 33 private boolean mShowPersistenceToggle; | |
| 34 | 26 |
| 35 private WindowAndroid mWindowAndroid; | 27 private WindowAndroid mWindowAndroid; |
|
gone
2016/11/10 23:05:47
There a way around storing this WindowAndroid?
dominickn
2016/11/10 23:55:13
It'll require a bunch more refactoring which I'm h
| |
| 28 private RequestDelegate mDelegate; | |
| 36 | 29 |
| 37 /** | 30 /** |
| 38 * Mapping between the required {@link ContentSettingsType}s and their assoc iated Android | 31 * Mapping between the required {@link ContentSettingsType}s and their assoc iated Android |
| 39 * runtime permissions. Only {@link ContentSettingsType}s that are associat ed with runtime | 32 * runtime permissions. Only {@link ContentSettingsType}s that are associat ed with runtime |
| 40 * permissions will be included in this list while all others will be exclud ed. | 33 * permissions will be included in this list while all others will be exclud ed. |
| 41 */ | 34 */ |
| 42 private SparseArray<String> mContentSettingsToPermissionsMap; | 35 private SparseArray<String> mContentSettingsToPermissionsMap; |
| 43 | 36 |
| 44 protected PermissionInfoBar(int iconDrawableId, Bitmap iconBitmap, String me ssage, | 37 /** |
| 45 String linkText, String primaryButtonText, String secondaryButtonTex t, | 38 * An interface for classes which need to be informed of the outcome of askin g a user to grant an |
| 46 boolean showPersistenceToggle) { | 39 * Android permission. |
| 47 super(iconDrawableId, iconBitmap, message, linkText, primaryButtonText, | 40 */ |
| 48 secondaryButtonText); | 41 public interface RequestDelegate { |
| 49 mShowPersistenceToggle = showPersistenceToggle; | 42 void onAndroidPermissionAccepted(); |
| 43 void onAndroidPermissionCanceled(); | |
|
gone
2016/11/10 23:05:47
Welp, this is one of those words no one agrees on
dominickn
2016/11/10 23:55:13
I've been told both spellings on reviews before
| |
| 50 } | 44 } |
| 51 | 45 |
| 52 @Override | 46 public AndroidPermissionRequester(WindowAndroid windowAndroid, |
| 53 public void createContent(InfoBarLayout layout) { | 47 RequestDelegate delegate, int[] contentSettings) { |
| 54 super.createContent(layout); | |
| 55 | |
| 56 if (mShowPersistenceToggle) { | |
| 57 InfoBarControlLayout controlLayout = layout.addControlLayout(); | |
| 58 String description = | |
| 59 layout.getContext().getString(R.string.permission_prompt_per sist_text); | |
| 60 controlLayout.addSwitch( | |
| 61 0, 0, description, R.id.permission_infobar_persist_toggle, t rue); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 @Override | |
| 66 public void onTabReparented(Tab tab) { | |
| 67 mWindowAndroid = tab.getWindowAndroid(); | |
| 68 } | |
| 69 | |
| 70 /** | |
| 71 * Specifies the {@link ContentSettingsType}s that are controlled by this In foBar. | |
| 72 * | |
| 73 * @param windowAndroid The WindowAndroid that will be used to check for the necessary | |
| 74 * permissions. | |
| 75 * @param contentSettings The list of {@link ContentSettingsType}s whose acc ess is guarded | |
| 76 * by this InfoBar. | |
| 77 */ | |
| 78 protected void setContentSettings( | |
| 79 WindowAndroid windowAndroid, int[] contentSettings) { | |
| 80 mWindowAndroid = windowAndroid; | 48 mWindowAndroid = windowAndroid; |
| 81 assert windowAndroid != null | 49 mDelegate = delegate; |
| 82 : "A WindowAndroid must be specified to request access to conten t settings"; | |
| 83 | |
| 84 mContentSettingsToPermissionsMap = generatePermissionsMapping(contentSet tings); | 50 mContentSettingsToPermissionsMap = generatePermissionsMapping(contentSet tings); |
| 85 } | 51 } |
| 86 | 52 |
| 53 public void setWindowAndroid(WindowAndroid windowAndroid) { | |
| 54 mWindowAndroid = windowAndroid; | |
| 55 } | |
| 56 | |
| 87 private SparseArray<String> generatePermissionsMapping(int[] contentSettings ) { | 57 private SparseArray<String> generatePermissionsMapping(int[] contentSettings ) { |
| 88 SparseArray<String> permissionsToRequest = new SparseArray<String>(); | 58 SparseArray<String> permissionsToRequest = new SparseArray<String>(); |
| 89 for (int i = 0; i < contentSettings.length; i++) { | 59 for (int i = 0; i < contentSettings.length; i++) { |
| 90 String permission = PrefServiceBridge.getAndroidPermissionForContent Setting( | 60 String permission = PrefServiceBridge.getAndroidPermissionForContent Setting( |
| 91 contentSettings[i]); | 61 contentSettings[i]); |
| 92 if (permission != null && !mWindowAndroid.hasPermission(permission)) { | 62 if (permission != null && !mWindowAndroid.hasPermission(permission)) { |
| 93 permissionsToRequest.append(contentSettings[i], permission); | 63 permissionsToRequest.append(contentSettings[i], permission); |
| 94 } | 64 } |
| 95 } | 65 } |
| 96 return permissionsToRequest; | 66 return permissionsToRequest; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 112 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_MIC) { | 82 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_MIC) { |
| 113 return R.string.infobar_missing_microphone_permission_text; | 83 return R.string.infobar_missing_microphone_permission_text; |
| 114 } | 84 } |
| 115 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_CAMERA) { | 85 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_CAMERA) { |
| 116 return R.string.infobar_missing_camera_permission_text; | 86 return R.string.infobar_missing_camera_permission_text; |
| 117 } | 87 } |
| 118 assert false : "Unexpected content setting type received: " + contentSet tingsType; | 88 assert false : "Unexpected content setting type received: " + contentSet tingsType; |
| 119 return R.string.infobar_missing_multiple_permissions_text; | 89 return R.string.infobar_missing_multiple_permissions_text; |
| 120 } | 90 } |
| 121 | 91 |
| 122 @Override | 92 public boolean shouldSkipPermissionRequest() { |
| 123 public void onButtonClicked(final boolean isPrimaryButton) { | 93 return (mWindowAndroid == null || mContentSettingsToPermissionsMap == nu ll |
| 124 if (mWindowAndroid == null || !isPrimaryButton || getContext() == null | 94 || mContentSettingsToPermissionsMap.size() == 0); |
| 125 || mContentSettingsToPermissionsMap == null | |
| 126 || mContentSettingsToPermissionsMap.size() == 0) { | |
| 127 onButtonClickedInternal(isPrimaryButton); | |
| 128 return; | |
| 129 } | |
| 130 | |
| 131 requestAndroidPermissions(); | |
| 132 } | 95 } |
| 133 | 96 |
| 134 private void requestAndroidPermissions() { | 97 public void requestAndroidPermissions() { |
| 135 PermissionCallback callback = new PermissionCallback() { | 98 PermissionCallback callback = new PermissionCallback() { |
| 136 @Override | 99 @Override |
| 137 public void onRequestPermissionsResult( | 100 public void onRequestPermissionsResult( |
| 138 String[] permissions, int[] grantResults) { | 101 String[] permissions, int[] grantResults) { |
| 139 int deniedCount = 0; | 102 int deniedCount = 0; |
| 140 int requestableCount = 0; | 103 int requestableCount = 0; |
| 141 int deniedStringId = R.string.infobar_missing_multiple_permissio ns_text; | 104 int deniedStringId = R.string.infobar_missing_multiple_permissio ns_text; |
| 142 for (int i = 0; i < grantResults.length; i++) { | 105 for (int i = 0; i < grantResults.length; i++) { |
| 143 if (grantResults[i] == PackageManager.PERMISSION_DENIED) { | 106 if (grantResults[i] == PackageManager.PERMISSION_DENIED) { |
| 144 deniedCount++; | 107 deniedCount++; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 167 .setPositiveButton(R.string.infobar_update_permissio ns_button_text, | 130 .setPositiveButton(R.string.infobar_update_permissio ns_button_text, |
| 168 new DialogInterface.OnClickListener() { | 131 new DialogInterface.OnClickListener() { |
| 169 @Override | 132 @Override |
| 170 public void onClick(DialogInterface dial og, int id) { | 133 public void onClick(DialogInterface dial og, int id) { |
| 171 requestAndroidPermissions(); | 134 requestAndroidPermissions(); |
| 172 } | 135 } |
| 173 }) | 136 }) |
| 174 .setOnCancelListener(new DialogInterface.OnCancelLi stener() { | 137 .setOnCancelListener(new DialogInterface.OnCancelLi stener() { |
| 175 @Override | 138 @Override |
| 176 public void onCancel(DialogInterface dialog ) { | 139 public void onCancel(DialogInterface dialog ) { |
| 177 onCloseButtonClicked(); | 140 mDelegate.onAndroidPermissionCanceled() ; |
| 178 } | 141 } |
| 179 }); | 142 }); |
| 180 builder.create().show(); | 143 builder.create().show(); |
| 181 } else if (deniedCount > 0) { | 144 } else if (deniedCount > 0) { |
| 182 onCloseButtonClicked(); | 145 mDelegate.onAndroidPermissionCanceled(); |
| 183 } else { | 146 } else { |
| 184 onButtonClickedInternal(true); | 147 mDelegate.onAndroidPermissionAccepted(); |
| 185 } | 148 } |
| 186 } | 149 } |
| 187 }; | 150 }; |
| 188 | 151 |
| 189 String[] permissionsToRequest = new String[mContentSettingsToPermissions Map.size()]; | 152 String[] permissionsToRequest = new String[mContentSettingsToPermissions Map.size()]; |
| 190 for (int i = 0; i < mContentSettingsToPermissionsMap.size(); i++) { | 153 for (int i = 0; i < mContentSettingsToPermissionsMap.size(); i++) { |
| 191 permissionsToRequest[i] = mContentSettingsToPermissionsMap.valueAt(i ); | 154 permissionsToRequest[i] = mContentSettingsToPermissionsMap.valueAt(i ); |
| 192 } | 155 } |
| 193 mWindowAndroid.requestPermissions(permissionsToRequest, callback); | 156 mWindowAndroid.requestPermissions(permissionsToRequest, callback); |
| 194 } | 157 } |
| 195 | 158 |
| 196 private void onButtonClickedInternal(boolean isPrimaryButton) { | |
| 197 super.onButtonClicked(isPrimaryButton); | |
| 198 } | |
| 199 | |
| 200 /** | |
| 201 * Returns true if the persist switch exists and is toggled on. | |
| 202 */ | |
| 203 @CalledByNative | |
| 204 protected boolean isPersistSwitchOn() { | |
| 205 SwitchCompat persistSwitch = (SwitchCompat) getView().findViewById( | |
| 206 R.id.permission_infobar_persist_toggle); | |
| 207 if (mShowPersistenceToggle && persistSwitch != null) { | |
| 208 return persistSwitch.isChecked(); | |
| 209 } | |
| 210 return false; | |
| 211 } | |
| 212 | |
| 213 /** | |
| 214 * Creates and begins the process for showing a PermissionInfoBar. | |
| 215 * @param windowAndroid The owning window for the infobar. | |
| 216 * @param enumeratedIconId ID corresponding to the icon that will be shown f or the infobar. | |
| 217 * The ID must have been mapped using the ResourceMa pper class before | |
| 218 * passing it to this function. | |
| 219 * @param iconBitmap Bitmap to use if there is no equivalent Java resource f or | |
| 220 * enumeratedIconId. | |
| 221 * @param message Message to display to the user indicating what the infobar is for. | |
| 222 * @param linkText Link text to display in addition to the message. | |
| 223 * @param buttonOk String to display on the OK button. | |
| 224 * @param buttonCancel String to display on the Cancel button. | |
| 225 * @param contentSettings The list of ContentSettingTypes being requested by this infobar. | |
| 226 * @param showPersistenceToggle Whether or not a toggle to opt-out of persis ting a decision | |
| 227 * should be displayed. | |
| 228 */ | |
| 229 @CalledByNative | |
| 230 private static PermissionInfoBar create(WindowAndroid windowAndroid, int enu meratedIconId, | |
| 231 Bitmap iconBitmap, String message, String linkText, String buttonOk, | |
| 232 String buttonCancel, int[] contentSettings, boolean showPersistenceT oggle) { | |
| 233 int drawableId = ResourceId.mapToDrawableId(enumeratedIconId); | |
| 234 | |
| 235 PermissionInfoBar infoBar = new PermissionInfoBar(drawableId, iconBitmap , message, linkText, | |
| 236 buttonOk, buttonCancel, showPersistenceToggle); | |
| 237 infoBar.setContentSettings(windowAndroid, contentSettings); | |
| 238 | |
| 239 return infoBar; | |
| 240 } | |
| 241 } | 159 } |
| OLD | NEW |