Chromium Code Reviews| 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 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 return; | 126 return; | 
| 127 auto range = duplicate_requests_.equal_range(existing_request); | 127 auto range = duplicate_requests_.equal_range(existing_request); | 
| 128 for (auto it = range.first; it != range.second; ++it) { | 128 for (auto it = range.first; it != range.second; ++it) { | 
| 129 if (request == it->second) | 129 if (request == it->second) | 
| 130 return; | 130 return; | 
| 131 } | 131 } | 
| 132 duplicate_requests_.insert(std::make_pair(existing_request, request)); | 132 duplicate_requests_.insert(std::make_pair(existing_request, request)); | 
| 133 return; | 133 return; | 
| 134 } | 134 } | 
| 135 | 135 | 
| 136 if (IsBubbleVisible()) { | |
| 137 if (is_main_frame) { | |
| 138 base::RecordAction( | |
| 139 base::UserMetricsAction("PermissionBubbleRequestQueued")); | |
| 140 queued_requests_.push_back(request); | |
| 141 } else { | |
| 142 base::RecordAction( | |
| 143 base::UserMetricsAction("PermissionBubbleIFrameRequestQueued")); | |
| 144 queued_frame_requests_.push_back(request); | |
| 145 } | |
| 146 return; | |
| 147 } | |
| 148 | |
| 149 if (is_main_frame) { | 136 if (is_main_frame) { | 
| 150 requests_.push_back(request); | 137 if (IsBubbleVisible()) { | 
| 151 accept_states_.push_back(true); | 138 base::RecordAction( | 
| 139 base::UserMetricsAction("PermissionBubbleRequestQueued")); | |
| 140 } | |
| 141 queued_requests_.push_back(request); | |
| 152 } else { | 142 } else { | 
| 153 base::RecordAction( | 143 base::RecordAction( | 
| 154 base::UserMetricsAction("PermissionBubbleIFrameRequestQueued")); | 144 base::UserMetricsAction("PermissionBubbleIFrameRequestQueued")); | 
| 155 queued_frame_requests_.push_back(request); | 145 queued_frame_requests_.push_back(request); | 
| 156 } | 146 } | 
| 157 | 147 | 
| 158 ScheduleShowBubble(); | 148 if (!IsBubbleVisible()) | 
| 149 ScheduleShowBubble(); | |
| 159 } | 150 } | 
| 160 | 151 | 
| 161 void PermissionRequestManager::CancelRequest(PermissionRequest* request) { | 152 void PermissionRequestManager::CancelRequest(PermissionRequest* request) { | 
| 162 // First look in the queued requests, where we can simply finish the request | 153 // First look in the queued requests, where we can simply finish the request | 
| 163 // and go on. | 154 // and go on. | 
| 164 std::vector<PermissionRequest*>::iterator requests_iter; | 155 std::vector<PermissionRequest*>::iterator requests_iter; | 
| 165 for (requests_iter = queued_requests_.begin(); | 156 for (requests_iter = queued_requests_.begin(); | 
| 166 requests_iter != queued_requests_.end(); | 157 requests_iter != queued_requests_.end(); | 
| 167 requests_iter++) { | 158 requests_iter++) { | 
| 168 if (*requests_iter == request) { | 159 if (*requests_iter == request) { | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 182 | 173 | 
| 183 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); | 174 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); | 
| 184 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); | 175 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); | 
| 185 requests_iter != requests_.end(); | 176 requests_iter != requests_.end(); | 
| 186 requests_iter++, accepts_iter++) { | 177 requests_iter++, accepts_iter++) { | 
| 187 if (*requests_iter != request) | 178 if (*requests_iter != request) | 
| 188 continue; | 179 continue; | 
| 189 | 180 | 
| 190 // We can simply erase the current entry in the request table if we aren't | 181 // We can simply erase the current entry in the request table if we aren't | 
| 191 // showing the dialog, or if we are showing it and it can accept the update. | 182 // showing the dialog, or if we are showing it and it can accept the update. | 
| 192 bool can_erase = !IsBubbleVisible() || view_->CanAcceptRequestUpdate(); | 183 bool can_erase = !view_ || view_->CanAcceptRequestUpdate(); | 
| 193 if (can_erase) { | 184 if (can_erase) { | 
| 194 RequestFinishedIncludingDuplicates(*requests_iter); | 185 RequestFinishedIncludingDuplicates(*requests_iter); | 
| 195 requests_.erase(requests_iter); | 186 requests_.erase(requests_iter); | 
| 196 accept_states_.erase(accepts_iter); | 187 accept_states_.erase(accepts_iter); | 
| 197 | 188 | 
| 198 if (IsBubbleVisible()) { | 189 if (view_) { | 
| 199 view_->Hide(); | 190 view_->Hide(); | 
| 200 // Will redraw the bubble if it is being shown. | 191 // Will redraw the bubble if it is being shown. | 
| 201 TriggerShowBubble(); | 192 DequeueRequestsAndShowBubble(); | 
| 202 } | 193 } | 
| 203 return; | 194 return; | 
| 204 } | 195 } | 
| 205 | 196 | 
| 206 // Cancel the existing request and replace it with a dummy. | 197 // Cancel the existing request and replace it with a dummy. | 
| 207 PermissionRequest* cancelled_request = | 198 PermissionRequest* cancelled_request = | 
| 208 new CancelledRequest(*requests_iter); | 199 new CancelledRequest(*requests_iter); | 
| 209 RequestFinishedIncludingDuplicates(*requests_iter); | 200 RequestFinishedIncludingDuplicates(*requests_iter); | 
| 210 *requests_iter = cancelled_request; | 201 *requests_iter = cancelled_request; | 
| 211 return; | 202 return; | 
| (...skipping 27 matching lines...) Expand all Loading... | |
| 239 view_.reset(); | 230 view_.reset(); | 
| 240 } | 231 } | 
| 241 | 232 | 
| 242 void PermissionRequestManager::DisplayPendingRequests() { | 233 void PermissionRequestManager::DisplayPendingRequests() { | 
| 243 if (IsBubbleVisible()) | 234 if (IsBubbleVisible()) | 
| 244 return; | 235 return; | 
| 245 | 236 | 
| 246 view_ = view_factory_.Run(web_contents()); | 237 view_ = view_factory_.Run(web_contents()); | 
| 247 view_->SetDelegate(this); | 238 view_->SetDelegate(this); | 
| 248 | 239 | 
| 249 TriggerShowBubble(); | 240 if (!main_frame_has_fully_loaded_) | 
| 241 return; | |
| 242 | |
| 243 if (requests_.empty()) { | |
| 244 DequeueRequestsAndShowBubble(); | |
| 245 } else { | |
| 246 // We switched tabs away and back while a prompt was active. | |
| 
 
raymes
2017/05/08 03:14:26
Thanks, this is much clearer now!
 
 | |
| 247 ShowBubble(); | |
| 248 } | |
| 250 } | 249 } | 
| 251 | 250 | 
| 252 void PermissionRequestManager::UpdateAnchorPosition() { | 251 void PermissionRequestManager::UpdateAnchorPosition() { | 
| 253 if (view_) | 252 if (view_) | 
| 254 view_->UpdateAnchorPosition(); | 253 view_->UpdateAnchorPosition(); | 
| 255 } | 254 } | 
| 256 | 255 | 
| 257 bool PermissionRequestManager::IsBubbleVisible() { | 256 bool PermissionRequestManager::IsBubbleVisible() { | 
| 258 return view_ && view_->IsVisible(); | 257 return view_ && !requests_.empty(); | 
| 259 } | 258 } | 
| 260 | 259 | 
| 261 // static | 260 // static | 
| 262 bool PermissionRequestManager::IsEnabled() { | 261 bool PermissionRequestManager::IsEnabled() { | 
| 263 #if defined(OS_ANDROID) | 262 #if defined(OS_ANDROID) | 
| 264 return base::FeatureList::IsEnabled(features::kUseGroupedPermissionInfobars); | 263 return base::FeatureList::IsEnabled(features::kUseGroupedPermissionInfobars); | 
| 265 #else | 264 #else | 
| 266 return true; | 265 return true; | 
| 267 #endif | 266 #endif | 
| 268 } | 267 } | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 } | 363 } | 
| 365 | 364 | 
| 366 void PermissionRequestManager::ScheduleShowBubble() { | 365 void PermissionRequestManager::ScheduleShowBubble() { | 
| 367 // ::ScheduleShowBubble() will be called again when the main frame will be | 366 // ::ScheduleShowBubble() will be called again when the main frame will be | 
| 368 // loaded. | 367 // loaded. | 
| 369 if (!main_frame_has_fully_loaded_) | 368 if (!main_frame_has_fully_loaded_) | 
| 370 return; | 369 return; | 
| 371 | 370 | 
| 372 content::BrowserThread::PostTask( | 371 content::BrowserThread::PostTask( | 
| 373 content::BrowserThread::UI, FROM_HERE, | 372 content::BrowserThread::UI, FROM_HERE, | 
| 374 base::BindOnce(&PermissionRequestManager::TriggerShowBubble, | 373 base::BindOnce(&PermissionRequestManager::DequeueRequestsAndShowBubble, | 
| 375 weak_factory_.GetWeakPtr())); | 374 weak_factory_.GetWeakPtr())); | 
| 376 } | 375 } | 
| 377 | 376 | 
| 378 void PermissionRequestManager::TriggerShowBubble() { | 377 void PermissionRequestManager::DequeueRequestsAndShowBubble() { | 
| 379 if (!view_) | 378 if (!view_) | 
| 380 return; | 379 return; | 
| 381 if (IsBubbleVisible()) | 380 if (!requests_.empty()) | 
| 382 return; | 381 return; | 
| 383 if (!main_frame_has_fully_loaded_) | 382 if (!main_frame_has_fully_loaded_) | 
| 384 return; | 383 return; | 
| 385 if (requests_.empty() && queued_requests_.empty() && | 384 if (queued_requests_.empty() && queued_frame_requests_.empty()) | 
| 386 queued_frame_requests_.empty()) { | |
| 387 return; | 385 return; | 
| 388 } | |
| 389 | 386 | 
| 390 if (requests_.empty()) { | 387 if (queued_requests_.size()) | 
| 391 if (queued_requests_.size()) | 388 requests_.swap(queued_requests_); | 
| 392 requests_.swap(queued_requests_); | 389 else | 
| 393 else | 390 requests_.swap(queued_frame_requests_); | 
| 394 requests_.swap(queued_frame_requests_); | |
| 395 | 391 | 
| 396 // Sets the default value for each request to be 'accept'. | 392 // Sets the default value for each request to be 'accept'. | 
| 397 accept_states_.resize(requests_.size(), true); | 393 accept_states_.resize(requests_.size(), true); | 
| 398 } | 394 | 
| 395 ShowBubble(); | |
| 396 } | |
| 397 | |
| 398 void PermissionRequestManager::ShowBubble() { | |
| 399 DCHECK(view_); | |
| 400 DCHECK(!requests_.empty()); | |
| 401 DCHECK(main_frame_has_fully_loaded_); | |
| 399 | 402 | 
| 400 view_->Show(requests_, accept_states_); | 403 view_->Show(requests_, accept_states_); | 
| 401 PermissionUmaUtil::PermissionPromptShown(requests_); | 404 PermissionUmaUtil::PermissionPromptShown(requests_); | 
| 402 NotifyBubbleAdded(); | 405 NotifyBubbleAdded(); | 
| 403 | 406 | 
| 404 // If in testing mode, automatically respond to the bubble that was shown. | 407 // If in testing mode, automatically respond to the bubble that was shown. | 
| 405 if (auto_response_for_test_ != NONE) | 408 if (auto_response_for_test_ != NONE) | 
| 406 DoAutoResponseForTesting(); | 409 DoAutoResponseForTesting(); | 
| 407 } | 410 } | 
| 408 | 411 | 
| 409 void PermissionRequestManager::FinalizeBubble() { | 412 void PermissionRequestManager::FinalizeBubble() { | 
| 410 if (view_ && !view_->HidesAutomatically()) | 413 if (view_ && !view_->HidesAutomatically()) | 
| 411 view_->Hide(); | 414 view_->Hide(); | 
| 412 | 415 | 
| 413 std::vector<PermissionRequest*>::iterator requests_iter; | 416 std::vector<PermissionRequest*>::iterator requests_iter; | 
| 414 for (requests_iter = requests_.begin(); | 417 for (requests_iter = requests_.begin(); | 
| 415 requests_iter != requests_.end(); | 418 requests_iter != requests_.end(); | 
| 416 requests_iter++) { | 419 requests_iter++) { | 
| 417 RequestFinishedIncludingDuplicates(*requests_iter); | 420 RequestFinishedIncludingDuplicates(*requests_iter); | 
| 418 } | 421 } | 
| 419 requests_.clear(); | 422 requests_.clear(); | 
| 420 accept_states_.clear(); | 423 accept_states_.clear(); | 
| 421 if (queued_requests_.size() || queued_frame_requests_.size()) | 424 if (queued_requests_.size() || queued_frame_requests_.size()) | 
| 422 TriggerShowBubble(); | 425 DequeueRequestsAndShowBubble(); | 
| 423 } | 426 } | 
| 424 | 427 | 
| 425 void PermissionRequestManager::CancelPendingQueues() { | 428 void PermissionRequestManager::CancelPendingQueues() { | 
| 426 std::vector<PermissionRequest*>::iterator requests_iter; | 429 std::vector<PermissionRequest*>::iterator requests_iter; | 
| 427 for (requests_iter = queued_requests_.begin(); | 430 for (requests_iter = queued_requests_.begin(); | 
| 428 requests_iter != queued_requests_.end(); | 431 requests_iter != queued_requests_.end(); | 
| 429 requests_iter++) { | 432 requests_iter++) { | 
| 430 RequestFinishedIncludingDuplicates(*requests_iter); | 433 RequestFinishedIncludingDuplicates(*requests_iter); | 
| 431 } | 434 } | 
| 432 for (requests_iter = queued_frame_requests_.begin(); | 435 for (requests_iter = queued_frame_requests_.begin(); | 
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 532 Accept(); | 535 Accept(); | 
| 533 } | 536 } | 
| 534 break; | 537 break; | 
| 535 case DISMISS: | 538 case DISMISS: | 
| 536 Closing(); | 539 Closing(); | 
| 537 break; | 540 break; | 
| 538 case NONE: | 541 case NONE: | 
| 539 NOTREACHED(); | 542 NOTREACHED(); | 
| 540 } | 543 } | 
| 541 } | 544 } | 
| OLD | NEW |