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

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

Issue 2966963003: Ensure media permission requests are correctly cancelled when permission prompts are ignored (Closed)
Patch Set: Ensure media permission requests are correctly cancelled when permission prompts are ignored Created 3 years, 5 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 <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 189
190 private: 190 private:
191 int render_process_id_; 191 int render_process_id_;
192 int render_frame_id_; 192 int render_frame_id_;
193 const base::Callback<void(const std::vector<ContentSetting>&)> callback_; 193 const base::Callback<void(const std::vector<ContentSetting>&)> callback_;
194 std::vector<ContentSettingsType> permissions_; 194 std::vector<ContentSettingsType> permissions_;
195 std::vector<ContentSetting> results_; 195 std::vector<ContentSetting> results_;
196 size_t remaining_results_; 196 size_t remaining_results_;
197 }; 197 };
198 198
199 // Object to track the callback passed to
200 // PermissionContextBase::RequestPermission. The callback passed in will never
201 // be run when a permission prompt has been ignored, but it's important that we
202 // know when a prompt is ignored to clean up |pending_requests_| correctly.
203 // If the callback is destroyed without being run, the destructor here will
204 // cancel the request to clean up.
205 class PermissionManager::PermissionResponseCallback {
206 public:
207 PermissionResponseCallback(
208 const base::WeakPtr<PermissionManager>& permission_manager,
209 int request_id,
210 int permission_id)
211 : permission_manager_(permission_manager),
212 request_id_(request_id),
213 permission_id_(permission_id),
214 request_answered_(false) {}
215
216 ~PermissionResponseCallback() {
217 if (!request_answered_ &&
218 permission_manager_->pending_requests_.Lookup(request_id_)) {
Timothy Loh 2017/07/05 07:32:49 Is this check needed?
raymes 2017/07/06 00:05:43 The request may contain multiple permissions and c
219 permission_manager_->pending_requests_.Remove(request_id_);
220 }
221 }
222
223 void OnPermissionsRequestResponseStatus(ContentSetting content_setting) {
224 request_answered_ = true;
225 permission_manager_->OnPermissionsRequestResponseStatus(
226 request_id_, permission_id_, content_setting);
227 }
228
229 private:
230 base::WeakPtr<PermissionManager> permission_manager_;
231 int request_id_;
232 int permission_id_;
233
234 bool request_answered_;
235
236 DISALLOW_COPY_AND_ASSIGN(PermissionResponseCallback);
237 };
238
199 struct PermissionManager::Subscription { 239 struct PermissionManager::Subscription {
200 ContentSettingsType permission; 240 ContentSettingsType permission;
201 GURL requesting_origin; 241 GURL requesting_origin;
202 GURL embedding_origin; 242 GURL embedding_origin;
203 base::Callback<void(ContentSetting)> callback; 243 base::Callback<void(ContentSetting)> callback;
204 ContentSetting current_value; 244 ContentSetting current_value;
205 }; 245 };
206 246
207 // static 247 // static
208 PermissionManager* PermissionManager::Get(Profile* profile) { 248 PermissionManager* PermissionManager::Get(Profile* profile) {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 profile, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA); 283 profile, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA);
244 permission_contexts_[CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC] = 284 permission_contexts_[CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC] =
245 base::MakeUnique<BackgroundSyncPermissionContext>(profile); 285 base::MakeUnique<BackgroundSyncPermissionContext>(profile);
246 #if BUILDFLAG(ENABLE_PLUGINS) 286 #if BUILDFLAG(ENABLE_PLUGINS)
247 permission_contexts_[CONTENT_SETTINGS_TYPE_PLUGINS] = 287 permission_contexts_[CONTENT_SETTINGS_TYPE_PLUGINS] =
248 base::MakeUnique<FlashPermissionContext>(profile); 288 base::MakeUnique<FlashPermissionContext>(profile);
249 #endif 289 #endif
250 } 290 }
251 291
252 PermissionManager::~PermissionManager() { 292 PermissionManager::~PermissionManager() {
293 DCHECK(pending_requests_.IsEmpty());
Timothy Loh 2017/07/05 07:32:49 I'm not sure this works, do we need to move the lo
raymes 2017/07/06 00:05:43 The PermissionManager is a profile-keyed service w
253 DCHECK(subscriptions_.IsEmpty()); 294 DCHECK(subscriptions_.IsEmpty());
254 } 295 }
255 296
256 void PermissionManager::Shutdown() { 297 void PermissionManager::Shutdown() {
257 if (!subscriptions_.IsEmpty()) { 298 if (!subscriptions_.IsEmpty()) {
258 HostContentSettingsMapFactory::GetForProfile(profile_) 299 HostContentSettingsMapFactory::GetForProfile(profile_)
259 ->RemoveObserver(this); 300 ->RemoveObserver(this);
260 subscriptions_.Clear(); 301 subscriptions_.Clear();
261 } 302 }
262 } 303 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 int request_id = pending_requests_.Add(base::MakeUnique<PendingRequest>( 342 int request_id = pending_requests_.Add(base::MakeUnique<PendingRequest>(
302 render_frame_host, permissions, callback)); 343 render_frame_host, permissions, callback));
303 344
304 const PermissionRequestID request(render_frame_host, request_id); 345 const PermissionRequestID request(render_frame_host, request_id);
305 346
306 for (size_t i = 0; i < permissions.size(); ++i) { 347 for (size_t i = 0; i < permissions.size(); ++i) {
307 const ContentSettingsType permission = permissions[i]; 348 const ContentSettingsType permission = permissions[i];
308 349
309 PermissionContextBase* context = GetPermissionContext(permission); 350 PermissionContextBase* context = GetPermissionContext(permission);
310 DCHECK(context); 351 DCHECK(context);
352 auto callback = base::MakeUnique<PermissionResponseCallback>(
353 weak_ptr_factory_.GetWeakPtr(), request_id, i);
311 context->RequestPermission( 354 context->RequestPermission(
312 web_contents, request, requesting_origin, user_gesture, 355 web_contents, request, requesting_origin, user_gesture,
313 base::Bind(&PermissionManager::OnPermissionsRequestResponseStatus, 356 base::Bind(
314 weak_ptr_factory_.GetWeakPtr(), request_id, i)); 357 &PermissionResponseCallback::OnPermissionsRequestResponseStatus,
358 base::Passed(&callback)));
315 } 359 }
316 360
317 // The request might have been resolved already. 361 // The request might have been resolved already.
318 if (!pending_requests_.Lookup(request_id)) 362 if (!pending_requests_.Lookup(request_id))
319 return kNoPendingOperation; 363 return kNoPendingOperation;
320 364
321 return request_id; 365 return request_id;
322 } 366 }
323 367
324 PermissionResult PermissionManager::GetPermissionStatus( 368 PermissionResult PermissionManager::GetPermissionStatus(
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 450
407 const PermissionRequestID request(pending_request->render_process_id(), 451 const PermissionRequestID request(pending_request->render_process_id(),
408 pending_request->render_frame_id(), 452 pending_request->render_frame_id(),
409 request_id); 453 request_id);
410 for (ContentSettingsType permission : pending_request->permissions()) { 454 for (ContentSettingsType permission : pending_request->permissions()) {
411 PermissionContextBase* context = GetPermissionContext(permission); 455 PermissionContextBase* context = GetPermissionContext(permission);
412 if (!context) 456 if (!context)
413 continue; 457 continue;
414 context->CancelPermissionRequest(web_contents, request); 458 context->CancelPermissionRequest(web_contents, request);
415 } 459 }
416 pending_requests_.Remove(request_id); 460 // The request should be automatically removed from |pending_requests_| as a
461 // result of it being cancelled but not necessarily immediately.
417 } 462 }
418 463
419 void PermissionManager::ResetPermission(PermissionType permission, 464 void PermissionManager::ResetPermission(PermissionType permission,
420 const GURL& requesting_origin, 465 const GURL& requesting_origin,
421 const GURL& embedding_origin) { 466 const GURL& embedding_origin) {
422 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 467 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
423 PermissionContextBase* context = 468 PermissionContextBase* context =
424 GetPermissionContext(PermissionTypeToContentSetting(permission)); 469 GetPermissionContext(PermissionTypeToContentSetting(permission));
425 if (!context) 470 if (!context)
426 return; 471 return;
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 const GURL& embedding_origin) { 581 const GURL& embedding_origin) {
537 PermissionContextBase* context = GetPermissionContext(permission); 582 PermissionContextBase* context = GetPermissionContext(permission);
538 PermissionResult result = context->GetPermissionStatus( 583 PermissionResult result = context->GetPermissionStatus(
539 render_frame_host, requesting_origin.GetOrigin(), 584 render_frame_host, requesting_origin.GetOrigin(),
540 embedding_origin.GetOrigin()); 585 embedding_origin.GetOrigin());
541 DCHECK(result.content_setting == CONTENT_SETTING_ALLOW || 586 DCHECK(result.content_setting == CONTENT_SETTING_ALLOW ||
542 result.content_setting == CONTENT_SETTING_ASK || 587 result.content_setting == CONTENT_SETTING_ASK ||
543 result.content_setting == CONTENT_SETTING_BLOCK); 588 result.content_setting == CONTENT_SETTING_BLOCK);
544 return result; 589 return result;
545 } 590 }
OLDNEW
« no previous file with comments | « chrome/browser/permissions/permission_manager.h ('k') | chrome/browser/permissions/permission_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698