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

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

Issue 2913393002: Only show grouped permission bubbles for mic/camera permissions (Closed)
Patch Set: Remove grouped requests Created 3 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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_request_manager.h" 5 #include "chrome/browser/permissions/permission_request_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/feature_list.h" 10 #include "base/feature_list.h"
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 PermissionRequest* b) { 53 PermissionRequest* b) {
54 if (a == b) 54 if (a == b)
55 return true; 55 return true;
56 if (a->GetMessageTextFragment() == b->GetMessageTextFragment() && 56 if (a->GetMessageTextFragment() == b->GetMessageTextFragment() &&
57 a->GetOrigin() == b->GetOrigin()) { 57 a->GetOrigin() == b->GetOrigin()) {
58 return true; 58 return true;
59 } 59 }
60 return false; 60 return false;
61 } 61 }
62 62
63 // We only group together media requests. We don't display grouped requests for
64 // any other permissions at present.
65 bool ShouldGroupRequests(PermissionRequest* a, PermissionRequest* b) {
66 if (a->GetOrigin() != b->GetOrigin())
67 return false;
68
69 if (a->GetPermissionRequestType() ==
70 PermissionRequestType::PERMISSION_MEDIASTREAM_MIC) {
71 return b->GetPermissionRequestType() ==
72 PermissionRequestType::PERMISSION_MEDIASTREAM_CAMERA;
73 }
74
75 if (a->GetPermissionRequestType() ==
76 PermissionRequestType::PERMISSION_MEDIASTREAM_CAMERA) {
77 return b->GetPermissionRequestType() ==
78 PermissionRequestType::PERMISSION_MEDIASTREAM_MIC;
79 }
80
81 return false;
82 }
83
63 } // namespace 84 } // namespace
64 85
65 // PermissionRequestManager::Observer ------------------------------------------ 86 // PermissionRequestManager::Observer ------------------------------------------
66 87
67 PermissionRequestManager::Observer::~Observer() { 88 PermissionRequestManager::Observer::~Observer() {
68 } 89 }
69 90
70 void PermissionRequestManager::Observer::OnBubbleAdded() { 91 void PermissionRequestManager::Observer::OnBubbleAdded() {
71 } 92 }
72 93
(...skipping 17 matching lines...) Expand all
90 } 111 }
91 112
92 PermissionRequestManager::~PermissionRequestManager() { 113 PermissionRequestManager::~PermissionRequestManager() {
93 if (view_ != NULL) 114 if (view_ != NULL)
94 view_->SetDelegate(NULL); 115 view_->SetDelegate(NULL);
95 116
96 for (PermissionRequest* request : requests_) 117 for (PermissionRequest* request : requests_)
97 request->RequestFinished(); 118 request->RequestFinished();
98 for (PermissionRequest* request : queued_requests_) 119 for (PermissionRequest* request : queued_requests_)
99 request->RequestFinished(); 120 request->RequestFinished();
100 for (PermissionRequest* request : queued_frame_requests_)
101 request->RequestFinished();
102 for (const auto& entry : duplicate_requests_) 121 for (const auto& entry : duplicate_requests_)
103 entry.second->RequestFinished(); 122 entry.second->RequestFinished();
104 } 123 }
105 124
106 void PermissionRequestManager::AddRequest(PermissionRequest* request) { 125 void PermissionRequestManager::AddRequest(PermissionRequest* request) {
107 // TODO(tsergeant): change the UMA to no longer mention bubbles. 126 // TODO(tsergeant): change the UMA to no longer mention bubbles.
108 base::RecordAction(base::UserMetricsAction("PermissionBubbleRequest")); 127 base::RecordAction(base::UserMetricsAction("PermissionBubbleRequest"));
109 128
110 // TODO(gbillock): is there a race between an early request on a 129 // TODO(gbillock): is there a race between an early request on a
111 // newly-navigated page and the to-be-cleaned-up requests on the previous 130 // newly-navigated page and the to-be-cleaned-up requests on the previous
(...skipping 19 matching lines...) Expand all
131 } 150 }
132 duplicate_requests_.insert(std::make_pair(existing_request, request)); 151 duplicate_requests_.insert(std::make_pair(existing_request, request));
133 return; 152 return;
134 } 153 }
135 154
136 if (is_main_frame) { 155 if (is_main_frame) {
137 if (IsBubbleVisible()) { 156 if (IsBubbleVisible()) {
138 base::RecordAction( 157 base::RecordAction(
139 base::UserMetricsAction("PermissionBubbleRequestQueued")); 158 base::UserMetricsAction("PermissionBubbleRequestQueued"));
140 } 159 }
141 queued_requests_.push_back(request);
142 } else { 160 } else {
143 base::RecordAction( 161 base::RecordAction(
144 base::UserMetricsAction("PermissionBubbleIFrameRequestQueued")); 162 base::UserMetricsAction("PermissionBubbleIFrameRequestQueued"));
145 queued_frame_requests_.push_back(request);
146 } 163 }
164 queued_requests_.push_back(request);
147 165
148 if (!IsBubbleVisible()) 166 if (!IsBubbleVisible())
149 ScheduleShowBubble(); 167 ScheduleShowBubble();
150 } 168 }
151 169
152 void PermissionRequestManager::CancelRequest(PermissionRequest* request) { 170 void PermissionRequestManager::CancelRequest(PermissionRequest* request) {
153 // First look in the queued requests, where we can simply finish the request 171 // First look in the queued requests, where we can simply finish the request
154 // and go on. 172 // and go on.
155 std::vector<PermissionRequest*>::iterator requests_iter; 173 std::deque<PermissionRequest*>::iterator queued_requests_iter;
156 for (requests_iter = queued_requests_.begin(); 174 for (queued_requests_iter = queued_requests_.begin();
157 requests_iter != queued_requests_.end(); 175 queued_requests_iter != queued_requests_.end(); queued_requests_iter++) {
158 requests_iter++) { 176 if (*queued_requests_iter == request) {
159 if (*requests_iter == request) { 177 RequestFinishedIncludingDuplicates(*queued_requests_iter);
160 RequestFinishedIncludingDuplicates(*requests_iter); 178 queued_requests_.erase(queued_requests_iter);
161 queued_requests_.erase(requests_iter);
162 return;
163 }
164 }
165 for (requests_iter = queued_frame_requests_.begin();
166 requests_iter != queued_frame_requests_.end(); requests_iter++) {
167 if (*requests_iter == request) {
168 RequestFinishedIncludingDuplicates(*requests_iter);
169 queued_frame_requests_.erase(requests_iter);
170 return; 179 return;
171 } 180 }
172 } 181 }
173 182
183 std::vector<PermissionRequest*>::iterator requests_iter;
174 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); 184 std::vector<bool>::iterator accepts_iter = accept_states_.begin();
175 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); 185 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin();
176 requests_iter != requests_.end(); 186 requests_iter != requests_.end();
177 requests_iter++, accepts_iter++) { 187 requests_iter++, accepts_iter++) {
178 if (*requests_iter != request) 188 if (*requests_iter != request)
179 continue; 189 continue;
180 190
181 // We can simply erase the current entry in the request table if we aren't 191 // We can simply erase the current entry in the request table if we aren't
182 // showing the dialog, or if we are showing it and it can accept the update. 192 // showing the dialog, or if we are showing it and it can accept the update.
183 bool can_erase = !view_ || view_->CanAcceptRequestUpdate(); 193 bool can_erase = !view_ || view_->CanAcceptRequestUpdate();
(...skipping 11 matching lines...) Expand all
195 } 205 }
196 206
197 // Cancel the existing request and replace it with a dummy. 207 // Cancel the existing request and replace it with a dummy.
198 PermissionRequest* cancelled_request = 208 PermissionRequest* cancelled_request =
199 new CancelledRequest(*requests_iter); 209 new CancelledRequest(*requests_iter);
200 RequestFinishedIncludingDuplicates(*requests_iter); 210 RequestFinishedIncludingDuplicates(*requests_iter);
201 *requests_iter = cancelled_request; 211 *requests_iter = cancelled_request;
202 return; 212 return;
203 } 213 }
204 214
205 // Since |request| wasn't found in queued_requests_, queued_frame_requests_ or 215 // Since |request| wasn't found in queued_requests_ or
206 // requests_ it must have been marked as a duplicate. We can't search 216 // requests_ it must have been marked as a duplicate. We can't search
207 // duplicate_requests_ by value, so instead use GetExistingRequest to find the 217 // duplicate_requests_ by value, so instead use GetExistingRequest to find the
208 // key (request it was duped against), and iterate through duplicates of that. 218 // key (request it was duped against), and iterate through duplicates of that.
209 PermissionRequest* existing_request = GetExistingRequest(request); 219 PermissionRequest* existing_request = GetExistingRequest(request);
210 auto range = duplicate_requests_.equal_range(existing_request); 220 auto range = duplicate_requests_.equal_range(existing_request);
211 for (auto it = range.first; it != range.second; ++it) { 221 for (auto it = range.first; it != range.second; ++it) {
212 if (request == it->second) { 222 if (request == it->second) {
213 it->second->RequestFinished(); 223 it->second->RequestFinished();
214 duplicate_requests_.erase(it); 224 duplicate_requests_.erase(it);
215 return; 225 return;
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
382 weak_factory_.GetWeakPtr())); 392 weak_factory_.GetWeakPtr()));
383 } 393 }
384 394
385 void PermissionRequestManager::DequeueRequestsAndShowBubble() { 395 void PermissionRequestManager::DequeueRequestsAndShowBubble() {
386 if (!view_) 396 if (!view_)
387 return; 397 return;
388 if (!requests_.empty()) 398 if (!requests_.empty())
389 return; 399 return;
390 if (!main_frame_has_fully_loaded_) 400 if (!main_frame_has_fully_loaded_)
391 return; 401 return;
392 if (queued_requests_.empty() && queued_frame_requests_.empty()) 402 if (queued_requests_.empty())
393 return; 403 return;
394 404
395 if (queued_requests_.size()) 405 requests_.push_back(queued_requests_.front());
396 requests_.swap(queued_requests_); 406 queued_requests_.pop_front();
397 else 407
398 requests_.swap(queued_frame_requests_); 408 if (!queued_requests_.empty() &&
409 ShouldGroupRequests(requests_.front(), queued_requests_.front())) {
410 requests_.push_back(queued_requests_.front());
411 queued_requests_.pop_front();
412 }
399 413
400 // Sets the default value for each request to be 'accept'. 414 // Sets the default value for each request to be 'accept'.
401 accept_states_.resize(requests_.size(), true); 415 accept_states_.resize(requests_.size(), true);
402 416
403 ShowBubble(); 417 ShowBubble();
404 } 418 }
405 419
406 void PermissionRequestManager::ShowBubble() { 420 void PermissionRequestManager::ShowBubble() {
407 DCHECK(view_); 421 DCHECK(view_);
408 DCHECK(!requests_.empty()); 422 DCHECK(!requests_.empty());
(...skipping 13 matching lines...) Expand all
422 view_->Hide(); 436 view_->Hide();
423 437
424 std::vector<PermissionRequest*>::iterator requests_iter; 438 std::vector<PermissionRequest*>::iterator requests_iter;
425 for (requests_iter = requests_.begin(); 439 for (requests_iter = requests_.begin();
426 requests_iter != requests_.end(); 440 requests_iter != requests_.end();
427 requests_iter++) { 441 requests_iter++) {
428 RequestFinishedIncludingDuplicates(*requests_iter); 442 RequestFinishedIncludingDuplicates(*requests_iter);
429 } 443 }
430 requests_.clear(); 444 requests_.clear();
431 accept_states_.clear(); 445 accept_states_.clear();
432 if (queued_requests_.size() || queued_frame_requests_.size()) 446 if (queued_requests_.size())
433 DequeueRequestsAndShowBubble(); 447 DequeueRequestsAndShowBubble();
434 } 448 }
435 449
436 void PermissionRequestManager::CancelPendingQueues() { 450 void PermissionRequestManager::CancelPendingQueues() {
437 std::vector<PermissionRequest*>::iterator requests_iter; 451 std::deque<PermissionRequest*>::iterator requests_iter;
438 for (requests_iter = queued_requests_.begin(); 452 for (requests_iter = queued_requests_.begin();
439 requests_iter != queued_requests_.end(); 453 requests_iter != queued_requests_.end();
440 requests_iter++) { 454 requests_iter++) {
441 RequestFinishedIncludingDuplicates(*requests_iter); 455 RequestFinishedIncludingDuplicates(*requests_iter);
442 } 456 }
443 for (requests_iter = queued_frame_requests_.begin();
444 requests_iter != queued_frame_requests_.end();
445 requests_iter++) {
446 RequestFinishedIncludingDuplicates(*requests_iter);
447 }
448 queued_requests_.clear(); 457 queued_requests_.clear();
449 queued_frame_requests_.clear();
450 } 458 }
451 459
452 PermissionRequest* PermissionRequestManager::GetExistingRequest( 460 PermissionRequest* PermissionRequestManager::GetExistingRequest(
453 PermissionRequest* request) { 461 PermissionRequest* request) {
454 for (PermissionRequest* existing_request : requests_) 462 for (PermissionRequest* existing_request : requests_)
455 if (IsMessageTextEqual(existing_request, request)) 463 if (IsMessageTextEqual(existing_request, request))
456 return existing_request; 464 return existing_request;
457 for (PermissionRequest* existing_request : queued_requests_) 465 for (PermissionRequest* existing_request : queued_requests_)
458 if (IsMessageTextEqual(existing_request, request)) 466 if (IsMessageTextEqual(existing_request, request))
459 return existing_request; 467 return existing_request;
460 for (PermissionRequest* existing_request : queued_frame_requests_)
461 if (IsMessageTextEqual(existing_request, request))
462 return existing_request;
463 return nullptr; 468 return nullptr;
464 } 469 }
465 470
466 void PermissionRequestManager::PermissionGrantedIncludingDuplicates( 471 void PermissionRequestManager::PermissionGrantedIncludingDuplicates(
467 PermissionRequest* request) { 472 PermissionRequest* request) {
468 DCHECK_EQ(request, GetExistingRequest(request)) 473 DCHECK_EQ(request, GetExistingRequest(request))
469 << "Only requests in [queued_[frame_]]requests_ can have duplicates"; 474 << "Only requests in [queued_[frame_]]requests_ can have duplicates";
470 request->set_persist(persist_); 475 request->set_persist(persist_);
471 request->PermissionGranted(); 476 request->PermissionGranted();
472 auto range = duplicate_requests_.equal_range(request); 477 auto range = duplicate_requests_.equal_range(request);
473 for (auto it = range.first; it != range.second; ++it) { 478 for (auto it = range.first; it != range.second; ++it) {
474 it->second->set_persist(persist_); 479 it->second->set_persist(persist_);
475 it->second->PermissionGranted(); 480 it->second->PermissionGranted();
476 } 481 }
477 } 482 }
478 void PermissionRequestManager::PermissionDeniedIncludingDuplicates( 483 void PermissionRequestManager::PermissionDeniedIncludingDuplicates(
479 PermissionRequest* request) { 484 PermissionRequest* request) {
480 DCHECK_EQ(request, GetExistingRequest(request)) 485 DCHECK_EQ(request, GetExistingRequest(request))
481 << "Only requests in [queued_[frame_]]requests_ can have duplicates"; 486 << "Only requests in [queued_]requests_ can have duplicates";
482 request->set_persist(persist_); 487 request->set_persist(persist_);
483 request->PermissionDenied(); 488 request->PermissionDenied();
484 auto range = duplicate_requests_.equal_range(request); 489 auto range = duplicate_requests_.equal_range(request);
485 for (auto it = range.first; it != range.second; ++it) { 490 for (auto it = range.first; it != range.second; ++it) {
486 it->second->set_persist(persist_); 491 it->second->set_persist(persist_);
487 it->second->PermissionDenied(); 492 it->second->PermissionDenied();
488 } 493 }
489 } 494 }
490 void PermissionRequestManager::CancelledIncludingDuplicates( 495 void PermissionRequestManager::CancelledIncludingDuplicates(
491 PermissionRequest* request) { 496 PermissionRequest* request) {
492 DCHECK_EQ(request, GetExistingRequest(request)) 497 DCHECK_EQ(request, GetExistingRequest(request))
493 << "Only requests in [queued_[frame_]]requests_ can have duplicates"; 498 << "Only requests in [queued_]requests_ can have duplicates";
494 request->Cancelled(); 499 request->Cancelled();
495 auto range = duplicate_requests_.equal_range(request); 500 auto range = duplicate_requests_.equal_range(request);
496 for (auto it = range.first; it != range.second; ++it) 501 for (auto it = range.first; it != range.second; ++it)
497 it->second->Cancelled(); 502 it->second->Cancelled();
498 } 503 }
499 void PermissionRequestManager::RequestFinishedIncludingDuplicates( 504 void PermissionRequestManager::RequestFinishedIncludingDuplicates(
500 PermissionRequest* request) { 505 PermissionRequest* request) {
501 // We can't call GetExistingRequest here, because other entries in requests_, 506 // We can't call GetExistingRequest here, because other entries in requests_,
502 // queued_requests_ or queued_frame_requests_ might already have been deleted. 507 // queued_requests_ might already have been deleted.
503 DCHECK_EQ(1, std::count(requests_.begin(), requests_.end(), request) + 508 DCHECK_EQ(1, std::count(requests_.begin(), requests_.end(), request) +
504 std::count(queued_requests_.begin(), queued_requests_.end(), 509 std::count(queued_requests_.begin(), queued_requests_.end(),
505 request) + 510 request))
506 std::count(queued_frame_requests_.begin(), 511 << "Only requests in [queued_]requests_ can have duplicates";
507 queued_frame_requests_.end(), request))
508 << "Only requests in [queued_[frame_]]requests_ can have duplicates";
509 request->RequestFinished(); 512 request->RequestFinished();
510 // Beyond this point, |request| has probably been deleted. 513 // Beyond this point, |request| has probably been deleted.
511 auto range = duplicate_requests_.equal_range(request); 514 auto range = duplicate_requests_.equal_range(request);
512 for (auto it = range.first; it != range.second; ++it) 515 for (auto it = range.first; it != range.second; ++it)
513 it->second->RequestFinished(); 516 it->second->RequestFinished();
514 // Additionally, we can now remove the duplicates. 517 // Additionally, we can now remove the duplicates.
515 duplicate_requests_.erase(request); 518 duplicate_requests_.erase(request);
516 } 519 }
517 520
518 void PermissionRequestManager::AddObserver(Observer* observer) { 521 void PermissionRequestManager::AddObserver(Observer* observer) {
(...skipping 24 matching lines...) Expand all
543 Accept(); 546 Accept();
544 } 547 }
545 break; 548 break;
546 case DISMISS: 549 case DISMISS:
547 Closing(); 550 Closing();
548 break; 551 break;
549 case NONE: 552 case NONE:
550 NOTREACHED(); 553 NOTREACHED();
551 } 554 }
552 } 555 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698