| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |