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

Side by Side Diff: chrome/browser/permissions/permission_manager.cc

Issue 1316863010: browser: implement multiple permission requesting (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@request-multiple-content
Patch Set: Rebase on master Created 5 years, 2 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 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 #include "chrome/browser/permissions/permission_manager.h" 5 #include "chrome/browser/permissions/permission_manager.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" 8 #include "chrome/browser/content_settings/host_content_settings_map_factory.h"
9 #include "chrome/browser/permissions/permission_context.h" 9 #include "chrome/browser/permissions/permission_context.h"
10 #include "chrome/browser/permissions/permission_context_base.h" 10 #include "chrome/browser/permissions/permission_context_base.h"
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 // return nullptr in PermissionContext::Get since they don't have a context. 86 // return nullptr in PermissionContext::Get since they don't have a context.
87 bool IsConstantPermission(PermissionType type) { 87 bool IsConstantPermission(PermissionType type) {
88 switch (type) { 88 switch (type) {
89 case PermissionType::MIDI: 89 case PermissionType::MIDI:
90 return true; 90 return true;
91 default: 91 default:
92 return false; 92 return false;
93 } 93 }
94 } 94 }
95 95
96 void PermissionRequestResponseCallbackWrapper(
97 const base::Callback<void(PermissionStatus)>& callback,
98 const std::vector<PermissionStatus>& vector) {
99 DCHECK_EQ(1ul, vector.size());
100 callback.Run(vector[0]);
101 }
102
96 // Function used for handling permission types which do not change their 103 // Function used for handling permission types which do not change their
97 // value i.e. they are always approved or always denied etc. 104 // value i.e. they are always approved or always denied etc.
98 // CONTENT_SETTING_DEFAULT is returned if the permission needs further handling. 105 // CONTENT_SETTING_DEFAULT is returned if the permission needs further handling.
99 // This function should only be called when IsConstantPermission has returned 106 // This function should only be called when IsConstantPermission has returned
100 // true for the PermissionType. 107 // true for the PermissionType.
101 ContentSetting GetContentSettingForConstantPermission(PermissionType type) { 108 ContentSetting GetContentSettingForConstantPermission(PermissionType type) {
102 DCHECK(IsConstantPermission(type)); 109 DCHECK(IsConstantPermission(type));
103 switch (type) { 110 switch (type) {
104 case PermissionType::MIDI: 111 case PermissionType::MIDI:
105 return CONTENT_SETTING_ALLOW; 112 return CONTENT_SETTING_ALLOW;
106 default: 113 default:
107 return CONTENT_SETTING_DEFAULT; 114 return CONTENT_SETTING_DEFAULT;
108 } 115 }
109 } 116 }
110 117
111 PermissionStatus GetPermissionStatusForConstantPermission(PermissionType type) { 118 PermissionStatus GetPermissionStatusForConstantPermission(PermissionType type) {
112 return ContentSettingToPermissionStatus( 119 return ContentSettingToPermissionStatus(
113 GetContentSettingForConstantPermission(type)); 120 GetContentSettingForConstantPermission(type));
114 } 121 }
115 122
116 } // anonymous namespace 123 } // anonymous namespace
117 124
118 struct PermissionManager::PendingRequest { 125 struct PermissionManager::PendingRequest {
119 PendingRequest(PermissionType permission, 126 PendingRequest(content::RenderFrameHost* render_frame_host,
120 content::RenderFrameHost* render_frame_host) 127 const GURL& requesting_origin,
121 : permission(permission), 128 const std::vector<PermissionType> permissions,
129 const base::Callback<void(
130 const std::vector<PermissionStatus>&)>& callback)
131 : pending_responses(permissions.size()),
122 render_process_id(render_frame_host->GetProcess()->GetID()), 132 render_process_id(render_frame_host->GetProcess()->GetID()),
123 render_frame_id(render_frame_host->GetRoutingID()) { 133 render_frame_id(render_frame_host->GetRoutingID()),
134 requesting_origin(requesting_origin),
135 callback(callback),
136 permissions(permissions),
137 result(permissions.size(), content::PERMISSION_STATUS_DENIED) {
124 } 138 }
125 139
126 PermissionType permission; 140 void SetPermission(int type_index, PermissionStatus status) {
141 result[type_index] = status;
142 pending_responses--;
143 }
144
145 bool IsComplete() {
146 return pending_responses == 0;
147 }
148
149 size_t pending_responses;
127 int render_process_id; 150 int render_process_id;
128 int render_frame_id; 151 int render_frame_id;
152 const GURL requesting_origin;
153 const base::Callback<void(
154 const std::vector<PermissionStatus>&)> callback;
155 std::vector<PermissionType> permissions;
156 std::vector<PermissionStatus> result;
129 }; 157 };
130 158
131 struct PermissionManager::Subscription { 159 struct PermissionManager::Subscription {
132 PermissionType permission; 160 PermissionType permission;
133 GURL requesting_origin; 161 GURL requesting_origin;
134 GURL embedding_origin; 162 GURL embedding_origin;
135 base::Callback<void(PermissionStatus)> callback; 163 base::Callback<void(PermissionStatus)> callback;
136 ContentSetting current_value; 164 ContentSetting current_value;
137 }; 165 };
138 166
139 PermissionManager::PermissionManager(Profile* profile) 167 PermissionManager::PermissionManager(Profile* profile)
140 : profile_(profile), 168 : profile_(profile),
141 weak_ptr_factory_(this) { 169 weak_ptr_factory_(this) {
142 } 170 }
143 171
144 PermissionManager::~PermissionManager() { 172 PermissionManager::~PermissionManager() {
145 if (!subscriptions_.IsEmpty()) 173 if (!subscriptions_.IsEmpty())
146 HostContentSettingsMapFactory::GetForProfile(profile_) 174 HostContentSettingsMapFactory::GetForProfile(profile_)
147 ->RemoveObserver(this); 175 ->RemoveObserver(this);
148 } 176 }
149 177
150 int PermissionManager::RequestPermission( 178 int PermissionManager::RequestPermission(
151 PermissionType permission, 179 PermissionType permission,
152 content::RenderFrameHost* render_frame_host, 180 content::RenderFrameHost* render_frame_host,
153 const GURL& requesting_origin, 181 const GURL& requesting_origin,
154 bool user_gesture, 182 bool user_gesture,
155 const base::Callback<void(PermissionStatus)>& callback) { 183 const base::Callback<void(PermissionStatus)>& callback) {
156 if (IsConstantPermission(permission)) { 184 return RequestPermissions(
157 callback.Run(GetPermissionStatusForConstantPermission(permission)); 185 std::vector<PermissionType>(1, permission),
158 return kNoPendingOperation; 186 render_frame_host,
159 } 187 requesting_origin,
188 user_gesture,
189 base::Bind(&PermissionRequestResponseCallbackWrapper, callback));
190 }
160 191
161 PermissionContextBase* context = PermissionContext::Get(profile_, permission); 192 int PermissionManager::RequestPermissions(
162 if (!context) { 193 const std::vector<PermissionType>& permissions,
163 callback.Run(content::PERMISSION_STATUS_DENIED); 194 content::RenderFrameHost* render_frame_host,
195 const GURL& requesting_origin,
196 bool user_gesture,
197 const base::Callback<void(
198 const std::vector<PermissionStatus>&)>& callback) {
199 if (permissions.empty()) {
200 callback.Run(std::vector<PermissionStatus>());
164 return kNoPendingOperation; 201 return kNoPendingOperation;
165 } 202 }
166 203
167 content::WebContents* web_contents = 204 content::WebContents* web_contents =
168 content::WebContents::FromRenderFrameHost(render_frame_host); 205 content::WebContents::FromRenderFrameHost(render_frame_host);
169 if (IsPermissionBubbleManagerMissing(web_contents)) { 206 GURL embedding_origin = web_contents->GetLastCommittedURL().GetOrigin();
170 callback.Run(
171 GetPermissionStatus(permission, requesting_origin,
172 web_contents->GetLastCommittedURL().GetOrigin()));
173 return kNoPendingOperation;
174 }
175 207
176 PendingRequest* pending_request = new PendingRequest( 208 PendingRequest* pending_request = new PendingRequest(
177 permission, render_frame_host); 209 render_frame_host, requesting_origin, permissions, callback);
178 int request_id = pending_requests_.Add(pending_request); 210 int request_id = pending_requests_.Add(pending_request);
179 const PermissionRequestID request(pending_request->render_process_id,
180 pending_request->render_frame_id,
181 request_id);
182 211
183 context->RequestPermission( 212 const PermissionRequestID request(render_frame_host, request_id);
184 web_contents, request, requesting_origin, user_gesture, 213
185 base::Bind(&PermissionManager::OnPermissionRequestResponse, 214 for (size_t i = 0; i < permissions.size(); ++i) {
186 weak_ptr_factory_.GetWeakPtr(), 215 const PermissionType permission = permissions[i];
187 request_id, 216
188 callback)); 217 if (IsConstantPermission(permission) ||
218 IsPermissionBubbleManagerMissing(web_contents) ||
219 !PermissionContext::Get(profile_, permission)) {
220 OnPermissionsRequestResponseStatus(request_id, i,
221 GetPermissionStatus(
222 permission, requesting_origin, embedding_origin));
223 continue;
224 }
225
226 PermissionContextBase* context = PermissionContext::Get(
227 profile_, permission);
228 context->RequestPermission(
229 web_contents, request, requesting_origin, user_gesture,
230 base::Bind(&PermissionManager::OnPermissionsRequestResponse,
231 weak_ptr_factory_.GetWeakPtr(),
232 request_id, i));
233 }
189 return request_id; 234 return request_id;
190 } 235 }
191 236
192 void PermissionManager::OnPermissionRequestResponse( 237 void PermissionManager::OnPermissionsRequestResponse(
193 int request_id, 238 int request_id,
194 const base::Callback<void(PermissionStatus)>& callback, 239 int type_index,
195 ContentSetting content_setting) { 240 ContentSetting content_setting) {
196 pending_requests_.Remove(request_id); 241 OnPermissionsRequestResponseStatus(request_id, type_index,
197 callback.Run(ContentSettingToPermissionStatus(content_setting)); 242 ContentSettingToPermissionStatus(content_setting));
198 } 243 }
199 244
200 void PermissionManager::CancelPermissionRequest( 245 void PermissionManager::OnPermissionsRequestResponseStatus(
201 PermissionType permission,
202 content::RenderFrameHost* render_frame_host,
203 int request_id, 246 int request_id,
204 const GURL& requesting_origin) { 247 int type_index,
248 PermissionStatus status) {
249 PendingRequest* pending_request = pending_requests_.Lookup(request_id);
250 pending_request->SetPermission(type_index, status);
251
252 if (pending_request->IsComplete()) {
253 pending_request->callback.Run(pending_request->result);
254 pending_requests_.Remove(request_id);
255 }
256 }
257
258 void PermissionManager::CancelPermissionRequest(int request_id) {
205 PendingRequest* pending_request = pending_requests_.Lookup(request_id); 259 PendingRequest* pending_request = pending_requests_.Lookup(request_id);
206 if (!pending_request) 260 if (!pending_request)
207 return; 261 return;
208 262
209 PermissionContextBase* context = PermissionContext::Get(profile_, permission); 263 content::WebContents* web_contents = tab_util::GetWebContentsByFrameID(
210 if (!context) 264 pending_request->render_process_id, pending_request->render_frame_id);
265 DCHECK(web_contents);
266 if (IsPermissionBubbleManagerMissing(web_contents)) {
267 pending_requests_.Remove(request_id);
211 return; 268 return;
269 }
212 270
213 content::WebContents* web_contents = 271 const PermissionRequestID request(pending_request->render_process_id,
214 content::WebContents::FromRenderFrameHost(render_frame_host); 272 pending_request->render_frame_id,
215 if (IsPermissionBubbleManagerMissing(web_contents))
216 return;
217
218 int render_process_id = render_frame_host->GetProcess()->GetID();
219 int render_frame_id = render_frame_host->GetRoutingID();
220 const PermissionRequestID request(render_process_id,
221 render_frame_id,
222 request_id); 273 request_id);
223 274 for (PermissionType permission : pending_request->permissions) {
224 context->CancelPermissionRequest(web_contents, request); 275 PermissionContextBase* context = PermissionContext::Get(
276 profile_, permission);
277 if (!context)
278 continue;
279 context->CancelPermissionRequest(web_contents, request);
280 }
225 pending_requests_.Remove(request_id); 281 pending_requests_.Remove(request_id);
226 } 282 }
227 283
228 void PermissionManager::ResetPermission(PermissionType permission, 284 void PermissionManager::ResetPermission(PermissionType permission,
229 const GURL& requesting_origin, 285 const GURL& requesting_origin,
230 const GURL& embedding_origin) { 286 const GURL& embedding_origin) {
231 PermissionContextBase* context = PermissionContext::Get(profile_, permission); 287 PermissionContextBase* context = PermissionContext::Get(profile_, permission);
232 if (!context) 288 if (!context)
233 return; 289 return;
234 290
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 // Add the callback to |callbacks| which will be run after the loop to 399 // Add the callback to |callbacks| which will be run after the loop to
344 // prevent re-entrance issues. 400 // prevent re-entrance issues.
345 callbacks.push_back( 401 callbacks.push_back(
346 base::Bind(subscription->callback, 402 base::Bind(subscription->callback,
347 ContentSettingToPermissionStatus(new_value))); 403 ContentSettingToPermissionStatus(new_value)));
348 } 404 }
349 405
350 for (const auto& callback : callbacks) 406 for (const auto& callback : callbacks)
351 callback.Run(); 407 callback.Run();
352 } 408 }
OLDNEW
« no previous file with comments | « chrome/browser/permissions/permission_manager.h ('k') | chrome/browser/permissions/permission_request_id.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698