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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/permissions/AndroidPermissionRequester.java

Issue 2682863002: [Android] Explicitly request all needed runtime permissions. (Closed)
Patch Set: Rebase Created 3 years, 10 months 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 unified diff | Download patch
OLDNEW
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.permissions; 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.support.v7.app.AlertDialog; 10 import android.support.v7.app.AlertDialog;
11 import android.util.SparseArray; 11 import android.util.SparseArray;
12 import android.view.View; 12 import android.view.View;
13 import android.widget.TextView; 13 import android.widget.TextView;
14 14
15 import org.chromium.chrome.R; 15 import org.chromium.chrome.R;
16 import org.chromium.chrome.browser.ContentSettingsType; 16 import org.chromium.chrome.browser.ContentSettingsType;
17 import org.chromium.chrome.browser.preferences.PrefServiceBridge; 17 import org.chromium.chrome.browser.preferences.PrefServiceBridge;
18 import org.chromium.chrome.browser.tab.Tab; 18 import org.chromium.chrome.browser.tab.Tab;
19 import org.chromium.ui.base.WindowAndroid; 19 import org.chromium.ui.base.WindowAndroid;
20 import org.chromium.ui.base.WindowAndroid.PermissionCallback; 20 import org.chromium.ui.base.WindowAndroid.PermissionCallback;
21 21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.List;
26 import java.util.Set;
27
22 /** 28 /**
23 * Methods to handle requesting native permissions from Android when the user gr ants a website a 29 * Methods to handle requesting native permissions from Android when the user gr ants a website a
24 * permission. 30 * permission.
25 */ 31 */
26 public class AndroidPermissionRequester { 32 public class AndroidPermissionRequester {
27 /** 33 /**
28 * An interface for classes which need to be informed of the outcome of askin g a user to grant an 34 * An interface for classes which need to be informed of the outcome of askin g a user to grant an
29 * Android permission. 35 * Android permission.
30 */ 36 */
31 public interface RequestDelegate { 37 public interface RequestDelegate {
32 void onAndroidPermissionAccepted(); 38 void onAndroidPermissionAccepted();
33 void onAndroidPermissionCanceled(); 39 void onAndroidPermissionCanceled();
34 } 40 }
35 41
36 private static SparseArray<String> generatePermissionsMapping( 42 private static SparseArray<String[]> generatePermissionsMapping(
37 WindowAndroid windowAndroid, int[] contentSettingsTypes) { 43 WindowAndroid windowAndroid, int[] contentSettingsTypes) {
38 SparseArray<String> permissionsToRequest = new SparseArray<String>(); 44 SparseArray<String[]> permissionsToRequest = new SparseArray<>();
39 for (int i = 0; i < contentSettingsTypes.length; i++) { 45 for (int i = 0; i < contentSettingsTypes.length; i++) {
40 String permission = PrefServiceBridge.getAndroidPermissionForContent Setting( 46 String[] permissions = PrefServiceBridge.getAndroidPermissionsForCon tentSetting(
41 contentSettingsTypes[i]); 47 contentSettingsTypes[i]);
42 if (permission != null && !windowAndroid.hasPermission(permission)) { 48 if (permissions == null) continue;
43 permissionsToRequest.append(contentSettingsTypes[i], permission) ; 49 List<String> missingPermissions = new ArrayList<>();
50 for (int j = 0; j < permissions.length; j++) {
51 String permission = permissions[j];
52 if (!windowAndroid.hasPermission(permission)) missingPermissions .add(permission);
53 }
54 if (!missingPermissions.isEmpty()) {
55 permissionsToRequest.append(contentSettingsTypes[i],
56 missingPermissions.toArray(new String[missingPermissions .size()]));
44 } 57 }
45 } 58 }
46 return permissionsToRequest; 59 return permissionsToRequest;
47 } 60 }
48 61
49 private static int getDeniedPermissionResourceId( 62 private static int getDeniedPermissionResourceId(
50 SparseArray<String> contentSettingsTypesToPermissionsMap, String per mission) { 63 SparseArray<String[]> contentSettingsTypesToPermissionsMap, String p ermission) {
51 int contentSettingsType = 0; 64 int contentSettingsType = 0;
52 // SparseArray#indexOfValue uses == instead of .equals, so we need to ma nually iterate 65 // SparseArray#indexOfValue uses == instead of .equals, so we need to ma nually iterate
53 // over the list. 66 // over the list.
54 for (int i = 0; i < contentSettingsTypesToPermissionsMap.size(); i++) { 67 for (int i = 0; i < contentSettingsTypesToPermissionsMap.size(); i++) {
55 if (permission.equals(contentSettingsTypesToPermissionsMap.valueAt(i ))) { 68 String[] contentSettingPermissions = contentSettingsTypesToPermissio nsMap.valueAt(i);
56 contentSettingsType = contentSettingsTypesToPermissionsMap.keyAt (i); 69 for (int j = 0; j < contentSettingPermissions.length; j++) {
70 if (permission.equals(contentSettingPermissions[j])) {
71 contentSettingsType = contentSettingsTypesToPermissionsMap.k eyAt(i);
72 break;
73 }
57 } 74 }
58 } 75 }
59 76
60 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_GEO LOCATION) { 77 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_GEO LOCATION) {
61 return R.string.infobar_missing_location_permission_text; 78 return R.string.infobar_missing_location_permission_text;
62 } 79 }
63 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_MIC) { 80 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_MIC) {
64 return R.string.infobar_missing_microphone_permission_text; 81 return R.string.infobar_missing_microphone_permission_text;
65 } 82 }
66 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_CAMERA) { 83 if (contentSettingsType == ContentSettingsType.CONTENT_SETTINGS_TYPE_MED IASTREAM_CAMERA) {
67 return R.string.infobar_missing_camera_permission_text; 84 return R.string.infobar_missing_camera_permission_text;
68 } 85 }
69 assert false : "Unexpected content setting type received: " + contentSet tingsType; 86 assert false : "Unexpected content setting type received: " + contentSet tingsType;
70 return R.string.infobar_missing_multiple_permissions_text; 87 return R.string.infobar_missing_multiple_permissions_text;
71 } 88 }
72 89
73 /** 90 /**
74 * Returns true if any of the permissions in contentSettingsTypes must be re quested from the 91 * Returns true if any of the permissions in contentSettingsTypes must be re quested from the
75 * system. Otherwise returns false. 92 * system. Otherwise returns false.
76 * 93 *
77 * If true is returned, this method will asynchronously request the necessar y permissions using 94 * If true is returned, this method will asynchronously request the necessar y permissions using
78 * a dialog, running methods on the RequestDelegate when the user has made a decision. 95 * a dialog, running methods on the RequestDelegate when the user has made a decision.
79 */ 96 */
80 public static boolean requestAndroidPermissions( 97 public static boolean requestAndroidPermissions(
81 final Tab tab, final int[] contentSettingsTypes, final RequestDelega te delegate) { 98 final Tab tab, final int[] contentSettingsTypes, final RequestDelega te delegate) {
82 final WindowAndroid windowAndroid = tab.getWindowAndroid(); 99 final WindowAndroid windowAndroid = tab.getWindowAndroid();
83 if (windowAndroid == null) return false; 100 if (windowAndroid == null) return false;
84 101
85 final SparseArray<String> contentSettingsTypesToPermissionsMap = 102 final SparseArray<String[]> contentSettingsTypesToPermissionsMap =
86 generatePermissionsMapping(windowAndroid, contentSettingsTypes); 103 generatePermissionsMapping(windowAndroid, contentSettingsTypes);
87 104
88 if (contentSettingsTypesToPermissionsMap.size() == 0) return false; 105 if (contentSettingsTypesToPermissionsMap.size() == 0) return false;
89 106
90 PermissionCallback callback = new PermissionCallback() { 107 PermissionCallback callback = new PermissionCallback() {
91 @Override 108 @Override
92 public void onRequestPermissionsResult( 109 public void onRequestPermissionsResult(
93 String[] permissions, int[] grantResults) { 110 String[] permissions, int[] grantResults) {
94 int deniedCount = 0; 111 int deniedCount = 0;
95 int requestableCount = 0; 112 int requestableCount = 0;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
135 }); 152 });
136 builder.create().show(); 153 builder.create().show();
137 } else if (deniedCount > 0) { 154 } else if (deniedCount > 0) {
138 delegate.onAndroidPermissionCanceled(); 155 delegate.onAndroidPermissionCanceled();
139 } else { 156 } else {
140 delegate.onAndroidPermissionAccepted(); 157 delegate.onAndroidPermissionAccepted();
141 } 158 }
142 } 159 }
143 }; 160 };
144 161
145 String[] permissionsToRequest = new String[contentSettingsTypesToPermiss ionsMap.size()]; 162 Set<String> permissionsToRequest = new HashSet<>();
146 for (int i = 0; i < contentSettingsTypesToPermissionsMap.size(); i++) { 163 for (int i = 0; i < contentSettingsTypesToPermissionsMap.size(); i++) {
147 permissionsToRequest[i] = contentSettingsTypesToPermissionsMap.value At(i); 164 Collections.addAll(
165 permissionsToRequest, contentSettingsTypesToPermissionsMap.v alueAt(i));
148 } 166 }
149 windowAndroid.requestPermissions(permissionsToRequest, callback); 167 windowAndroid.requestPermissions(
168 permissionsToRequest.toArray(new String[permissionsToRequest.siz e()]), callback);
150 return true; 169 return true;
151 } 170 }
152 } 171 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698