Index: chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java b/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java |
index 2de2fe09a95d6ab0142a5602ca2b17afe4149f20..15e858a81710f128bf67658cc8adc3e6dfe8c826 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/infobar/ConfirmInfoBar.java |
@@ -4,19 +4,23 @@ |
package org.chromium.chrome.browser.infobar; |
+import android.app.Activity; |
+import android.app.AlertDialog; |
import android.content.Context; |
+import android.content.DialogInterface; |
import android.content.pm.PackageManager; |
import android.graphics.Bitmap; |
import android.os.Process; |
+import android.util.SparseArray; |
+import android.view.View; |
+import android.widget.TextView; |
+import org.chromium.chrome.R; |
import org.chromium.chrome.browser.ContentSettingsType; |
import org.chromium.chrome.browser.preferences.PrefServiceBridge; |
import org.chromium.ui.base.WindowAndroid; |
import org.chromium.ui.base.WindowAndroid.PermissionCallback; |
-import java.util.ArrayList; |
-import java.util.List; |
- |
/** |
* An infobar that presents the user with several buttons. |
* |
@@ -38,10 +42,11 @@ public class ConfirmInfoBar extends InfoBar { |
private WindowAndroid mWindowAndroid; |
/** |
- * The list of {@link ContentSettingsType}s being requested by this infobar. Can be null or |
- * empty if none apply. |
+ * Mapping between the required {@link ContentSettingsType}s and their associated Android |
+ * runtime permissions. Only {@link ContentSettingsType}s that are associated with runtime |
+ * permissions will be included in this list while all others will be excluded. |
*/ |
- private int[] mContentSettings; |
+ private SparseArray<String> mContentSettingsToPermissionsMap; |
public ConfirmInfoBar(InfoBarListeners.Confirm confirmListener, int iconDrawableId, |
Bitmap iconBitmap, String message, String linkText, String primaryButtonText, |
@@ -64,10 +69,10 @@ public class ConfirmInfoBar extends InfoBar { |
protected void setContentSettings( |
WindowAndroid windowAndroid, int[] contentSettings) { |
mWindowAndroid = windowAndroid; |
- mContentSettings = contentSettings; |
- |
assert windowAndroid != null |
: "A WindowAndroid must be specified to request access to content settings"; |
+ |
+ mContentSettingsToPermissionsMap = generatePermissionsMapping(contentSettings); |
} |
@Override |
@@ -80,46 +85,103 @@ public class ConfirmInfoBar extends InfoBar { |
!= PackageManager.PERMISSION_DENIED; |
} |
- private List<String> getPermissionsToRequest() { |
- Context context = getContext(); |
- List<String> permissionsToRequest = new ArrayList<String>(); |
- for (int i = 0; i < mContentSettings.length; i++) { |
+ private SparseArray<String> generatePermissionsMapping(int[] contentSettings) { |
+ Context context = mWindowAndroid.getApplicationContext(); |
+ SparseArray<String> permissionsToRequest = new SparseArray<String>(); |
+ for (int i = 0; i < contentSettings.length; i++) { |
String permission = PrefServiceBridge.getAndroidPermissionForContentSetting( |
- mContentSettings[i]); |
+ contentSettings[i]); |
if (permission != null) { |
- if (!hasPermission(context, permission)) permissionsToRequest.add(permission); |
+ if (!hasPermission(context, permission)) { |
+ permissionsToRequest.append(contentSettings[i], permission); |
+ } |
} |
} |
return permissionsToRequest; |
} |
+ private int getDeniedPermissionResourceId(String permission) { |
+ int contentSettingsType = 0; |
+ // SparseArray#indexOfValue uses == instead of .equals, so we need to manually iterate |
+ // over the list. |
+ for (int i = 0; i < mContentSettingsToPermissionsMap.size(); i++) { |
+ if (permission.equals(mContentSettingsToPermissionsMap.valueAt(i))) { |
+ contentSettingsType = mContentSettingsToPermissionsMap.keyAt(i); |
+ } |
+ } |
+ switch (contentSettingsType) { |
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_GEOLOCATION: |
+ return R.string.infobar_missing_location_permission_text; |
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC: |
+ return R.string.infobar_missing_microphone_permission_text; |
+ case ContentSettingsType.CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA: |
+ return R.string.infobar_missing_camera_permission_text; |
+ default: |
+ assert false; |
+ return R.string.infobar_missing_multiple_permissions_text; |
+ |
+ } |
+ } |
+ |
@Override |
public void onButtonClicked(final boolean isPrimaryButton) { |
- if (mWindowAndroid == null || mContentSettings == null |
- || !isPrimaryButton || getContext() == null) { |
+ if (mWindowAndroid == null || !isPrimaryButton || getContext() == null |
+ || mContentSettingsToPermissionsMap == null |
+ || mContentSettingsToPermissionsMap.size() == 0) { |
onButtonClickedInternal(isPrimaryButton); |
return; |
} |
- List<String> permissionsToRequest = getPermissionsToRequest(); |
- if (permissionsToRequest.isEmpty()) { |
- onButtonClickedInternal(isPrimaryButton); |
- return; |
- } |
+ requestAndroidPermissions(); |
+ } |
+ private void requestAndroidPermissions() { |
PermissionCallback callback = new PermissionCallback() { |
@Override |
public void onRequestPermissionsResult( |
String[] permissions, int[] grantResults) { |
- boolean grantedAllPermissions = true; |
+ int deniedCount = 0; |
+ int requestableCount = 0; |
+ int deniedStringId = R.string.infobar_missing_multiple_permissions_text; |
for (int i = 0; i < grantResults.length; i++) { |
if (grantResults[i] == PackageManager.PERMISSION_DENIED) { |
- grantedAllPermissions = false; |
- break; |
+ deniedCount++; |
+ if (deniedCount > 1) { |
+ deniedStringId = R.string.infobar_missing_multiple_permissions_text; |
+ } else { |
+ deniedStringId = getDeniedPermissionResourceId(permissions[i]); |
+ } |
+ |
+ if (mWindowAndroid.canRequestPermission(permissions[i])) { |
+ requestableCount++; |
+ } |
} |
} |
- if (!grantedAllPermissions) { |
+ Activity activity = mWindowAndroid.getActivity().get(); |
+ if (deniedCount > 0 && requestableCount > 0 && activity != null) { |
+ View view = activity.getLayoutInflater().inflate( |
+ R.layout.update_permissions_dialog, null); |
+ TextView dialogText = (TextView) view.findViewById(R.id.text); |
+ dialogText.setText(deniedStringId); |
+ |
+ AlertDialog.Builder builder = new AlertDialog.Builder(getContext()) |
+ .setView(view) |
+ .setPositiveButton(R.string.infobar_update_permissions_button_text, |
+ new DialogInterface.OnClickListener() { |
+ @Override |
+ public void onClick(DialogInterface dialog, int id) { |
+ requestAndroidPermissions(); |
+ } |
+ }) |
+ .setOnCancelListener(new DialogInterface.OnCancelListener() { |
+ @Override |
+ public void onCancel(DialogInterface dialog) { |
+ onCloseButtonClicked(); |
+ } |
+ }); |
+ builder.create().show(); |
+ } else if (deniedCount > 0) { |
onCloseButtonClicked(); |
} else { |
onButtonClickedInternal(true); |
@@ -127,9 +189,11 @@ public class ConfirmInfoBar extends InfoBar { |
} |
}; |
- mWindowAndroid.requestPermissions( |
- permissionsToRequest.toArray(new String[permissionsToRequest.size()]), |
- callback); |
+ String[] permissionsToRequest = new String[mContentSettingsToPermissionsMap.size()]; |
+ for (int i = 0; i < mContentSettingsToPermissionsMap.size(); i++) { |
+ permissionsToRequest[i] = mContentSettingsToPermissionsMap.valueAt(i); |
+ } |
+ mWindowAndroid.requestPermissions(permissionsToRequest, callback); |
} |
private void onButtonClickedInternal(boolean isPrimaryButton) { |