| 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/ui/website_settings/permission_bubble_manager.h" | 5 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/metrics/user_metrics_action.h" | 8 #include "base/metrics/user_metrics_action.h" |
| 9 #include "chrome/browser/ui/browser.h" |
| 10 #include "chrome/browser/ui/website_settings/permission_bubble_delegate.h" |
| 9 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" | 11 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" |
| 10 #include "chrome/common/chrome_switches.h" | 12 #include "chrome/common/chrome_switches.h" |
| 13 #include "components/bubble/bubble_delegate.h" |
| 14 #include "components/bubble/bubble_manager.h" |
| 11 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 12 #include "content/public/browser/navigation_details.h" | 16 #include "content/public/browser/navigation_details.h" |
| 13 #include "content/public/browser/user_metrics.h" | 17 #include "content/public/browser/user_metrics.h" |
| 14 | 18 |
| 15 namespace { | 19 namespace { |
| 16 | 20 |
| 17 class CancelledRequest : public PermissionBubbleRequest { | 21 class CancelledRequest : public PermissionBubbleRequest { |
| 18 public: | 22 public: |
| 19 explicit CancelledRequest(PermissionBubbleRequest* cancelled) | 23 explicit CancelledRequest(PermissionBubbleRequest* cancelled) |
| 20 : icon_(cancelled->GetIconID()), | 24 : icon_(cancelled->GetIconID()), |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 69 if (base::CommandLine::ForCurrentProcess()->HasSwitch( | 73 if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 70 switches::kDisablePermissionsBubbles)) | 74 switches::kDisablePermissionsBubbles)) |
| 71 return false; | 75 return false; |
| 72 return true; | 76 return true; |
| 73 } | 77 } |
| 74 | 78 |
| 75 PermissionBubbleManager::PermissionBubbleManager( | 79 PermissionBubbleManager::PermissionBubbleManager( |
| 76 content::WebContents* web_contents) | 80 content::WebContents* web_contents) |
| 77 : content::WebContentsObserver(web_contents), | 81 : content::WebContentsObserver(web_contents), |
| 78 require_user_gesture_(false), | 82 require_user_gesture_(false), |
| 79 #if !defined(OS_ANDROID) // No bubbles in android tests. | 83 bubble_delegate_(nullptr), |
| 80 view_factory_(base::Bind(&PermissionBubbleView::Create)), | 84 bubble_manager_(nullptr), |
| 81 #endif | |
| 82 view_(nullptr), | |
| 83 main_frame_has_fully_loaded_(false), | 85 main_frame_has_fully_loaded_(false), |
| 84 auto_response_for_test_(NONE), | 86 auto_response_for_test_(NONE), |
| 85 weak_factory_(this) { | 87 weak_factory_(this) {} |
| 86 } | |
| 87 | 88 |
| 88 PermissionBubbleManager::~PermissionBubbleManager() { | 89 PermissionBubbleManager::~PermissionBubbleManager() { |
| 89 if (view_ != NULL) | 90 if (bubble_delegate_) { |
| 90 view_->SetDelegate(NULL); | 91 DCHECK(bubble_manager_); |
| 92 bubble_manager_->HideBubble(bubble_delegate_.get()); |
| 93 bubble_delegate_.reset(); |
| 94 } |
| 91 | 95 |
| 92 std::vector<PermissionBubbleRequest*>::iterator requests_iter; | 96 std::vector<PermissionBubbleRequest*>::iterator requests_iter; |
| 93 for (requests_iter = requests_.begin(); | 97 for (requests_iter = requests_.begin(); |
| 94 requests_iter != requests_.end(); | 98 requests_iter != requests_.end(); |
| 95 requests_iter++) { | 99 requests_iter++) { |
| 96 (*requests_iter)->RequestFinished(); | 100 (*requests_iter)->RequestFinished(); |
| 97 } | 101 } |
| 98 for (requests_iter = queued_requests_.begin(); | 102 for (requests_iter = queued_requests_.begin(); |
| 99 requests_iter != queued_requests_.end(); | 103 requests_iter != queued_requests_.end(); |
| 100 requests_iter++) { | 104 requests_iter++) { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 | 171 |
| 168 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); | 172 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); |
| 169 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); | 173 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); |
| 170 requests_iter != requests_.end(); | 174 requests_iter != requests_.end(); |
| 171 requests_iter++, accepts_iter++) { | 175 requests_iter++, accepts_iter++) { |
| 172 if (*requests_iter != request) | 176 if (*requests_iter != request) |
| 173 continue; | 177 continue; |
| 174 | 178 |
| 175 // We can simply erase the current entry in the request table if we aren't | 179 // We can simply erase the current entry in the request table if we aren't |
| 176 // showing the dialog, or if we are showing it and it can accept the update. | 180 // showing the dialog, or if we are showing it and it can accept the update. |
| 177 bool can_erase = !IsBubbleVisible() || view_->CanAcceptRequestUpdate(); | 181 bool can_erase = !IsBubbleVisible(); |
| 182 |
| 183 // TODO(hcarmona): Don't forget this logic. Maybe improve it? Or remove it? |
| 184 // bool can_erase = !IsBubbleVisible() || view_->CanAcceptRequestUpdate(); |
| 185 |
| 178 if (can_erase) { | 186 if (can_erase) { |
| 179 (*requests_iter)->RequestFinished(); | 187 (*requests_iter)->RequestFinished(); |
| 180 requests_.erase(requests_iter); | 188 requests_.erase(requests_iter); |
| 181 accept_states_.erase(accepts_iter); | 189 accept_states_.erase(accepts_iter); |
| 182 | 190 |
| 183 if (IsBubbleVisible()) { | 191 if (IsBubbleVisible()) { |
| 184 view_->Hide(); | 192 bubble_manager_->HideBubble(bubble_delegate_.get()); |
| 185 // Will redraw the bubble if it is being shown. | 193 // Will redraw the bubble if it is being shown. |
| 186 TriggerShowBubble(); | 194 TriggerShowBubble(); |
| 187 } | 195 } |
| 188 return; | 196 return; |
| 189 } | 197 } |
| 190 | 198 |
| 191 // Cancel the existing request and replace it with a dummy. | 199 // Cancel the existing request and replace it with a dummy. |
| 192 PermissionBubbleRequest* cancelled_request = | 200 PermissionBubbleRequest* cancelled_request = |
| 193 new CancelledRequest(*requests_iter); | 201 new CancelledRequest(*requests_iter); |
| 194 (*requests_iter)->RequestFinished(); | 202 (*requests_iter)->RequestFinished(); |
| 195 *requests_iter = cancelled_request; | 203 *requests_iter = cancelled_request; |
| 196 return; | 204 return; |
| 197 } | 205 } |
| 198 | 206 |
| 199 NOTREACHED(); // Callers should not cancel requests that are not pending. | 207 NOTREACHED(); // Callers should not cancel requests that are not pending. |
| 200 } | 208 } |
| 201 | 209 |
| 202 void PermissionBubbleManager::HideBubble() { | 210 void PermissionBubbleManager::HideBubble() { |
| 203 // Disengage from the existing view if there is one. | 211 // Disengage from the existing view if there is one. |
| 204 if (!view_) | 212 if (!bubble_delegate_) |
| 205 return; | 213 return; |
| 206 | 214 |
| 207 view_->SetDelegate(nullptr); | 215 // view_->SetDelegate(nullptr); |
| 208 view_->Hide(); | 216 DCHECK(bubble_manager_); |
| 209 view_.reset(); | 217 bubble_manager_->HideBubble(bubble_delegate_.get()); |
| 218 bubble_delegate_.reset(); |
| 210 } | 219 } |
| 211 | 220 |
| 212 void PermissionBubbleManager::DisplayPendingRequests(Browser* browser) { | 221 void PermissionBubbleManager::DisplayPendingRequests(Browser* browser) { |
| 213 if (IsBubbleVisible()) | 222 if (IsBubbleVisible()) |
| 214 return; | 223 return; |
| 215 | 224 |
| 216 view_ = view_factory_.Run(browser); | 225 bubble_manager_ = browser->bubble_manager(); |
| 217 view_->SetDelegate(this); | 226 bubble_delegate_ = |
| 227 make_scoped_ptr(new PermissionBubbleDelegate(browser, this)); |
| 228 // view_ = view_factory_.Run(browser); |
| 229 // view_->SetDelegate(this); |
| 218 | 230 |
| 219 TriggerShowBubble(); | 231 TriggerShowBubble(); |
| 220 } | 232 } |
| 221 | 233 |
| 222 void PermissionBubbleManager::UpdateAnchorPosition() { | 234 void PermissionBubbleManager::UpdateAnchorPosition() { |
| 223 if (view_) | 235 // TODO(hcarmona): get rid of this function when the manager is hooked in. |
| 224 view_->UpdateAnchorPosition(); | 236 if (bubble_delegate_) |
| 237 bubble_manager_->UpdateBubblePosition(bubble_delegate_.get()); |
| 225 } | 238 } |
| 226 | 239 |
| 227 bool PermissionBubbleManager::IsBubbleVisible() { | 240 bool PermissionBubbleManager::IsBubbleVisible() { |
| 228 return view_ && view_->IsVisible(); | 241 if (bubble_delegate_) { |
| 242 DCHECK(bubble_manager_); |
| 243 return bubble_manager_->IsBubbleVisible(bubble_delegate_.get()); |
| 244 } |
| 245 |
| 246 return false; |
| 229 } | 247 } |
| 230 | 248 |
| 231 gfx::NativeWindow PermissionBubbleManager::GetBubbleWindow() { | 249 gfx::NativeWindow PermissionBubbleManager::GetBubbleWindow() { |
| 250 /* |
| 251 * TODO(hcarmona): get rid of this function when the manager is hooked in. |
| 232 if (view_) | 252 if (view_) |
| 233 return view_->GetNativeWindow(); | 253 return view_->GetNativeWindow(); |
| 254 */ |
| 234 return nullptr; | 255 return nullptr; |
| 235 } | 256 } |
| 236 | 257 |
| 237 void PermissionBubbleManager::RequireUserGesture(bool required) { | 258 void PermissionBubbleManager::RequireUserGesture(bool required) { |
| 238 require_user_gesture_ = required; | 259 require_user_gesture_ = required; |
| 239 } | 260 } |
| 240 | 261 |
| 241 void PermissionBubbleManager::DidNavigateMainFrame( | 262 void PermissionBubbleManager::DidNavigateMainFrame( |
| 242 const content::LoadCommittedDetails& details, | 263 const content::LoadCommittedDetails& details, |
| 243 const content::FrameNavigateParams& params) { | 264 const content::FrameNavigateParams& params) { |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 339 return; | 360 return; |
| 340 | 361 |
| 341 content::BrowserThread::PostTask( | 362 content::BrowserThread::PostTask( |
| 342 content::BrowserThread::UI, | 363 content::BrowserThread::UI, |
| 343 FROM_HERE, | 364 FROM_HERE, |
| 344 base::Bind(&PermissionBubbleManager::TriggerShowBubble, | 365 base::Bind(&PermissionBubbleManager::TriggerShowBubble, |
| 345 weak_factory_.GetWeakPtr())); | 366 weak_factory_.GetWeakPtr())); |
| 346 } | 367 } |
| 347 | 368 |
| 348 void PermissionBubbleManager::TriggerShowBubble() { | 369 void PermissionBubbleManager::TriggerShowBubble() { |
| 349 if (!view_) | 370 if (!bubble_delegate_) |
| 350 return; | 371 return; |
| 351 if (IsBubbleVisible()) | 372 if (IsBubbleVisible()) |
| 352 return; | 373 return; |
| 353 if (!main_frame_has_fully_loaded_) | 374 if (!main_frame_has_fully_loaded_) |
| 354 return; | 375 return; |
| 355 if (requests_.empty() && queued_requests_.empty() && | 376 if (requests_.empty() && queued_requests_.empty() && |
| 356 queued_frame_requests_.empty()) { | 377 queued_frame_requests_.empty()) { |
| 357 return; | 378 return; |
| 358 } | 379 } |
| 359 | 380 |
| 360 if (requests_.empty()) { | 381 if (requests_.empty()) { |
| 361 // Queues containing a user-gesture-generated request have priority. | 382 // Queues containing a user-gesture-generated request have priority. |
| 362 if (HasUserGestureRequest(queued_requests_)) | 383 if (HasUserGestureRequest(queued_requests_)) |
| 363 requests_.swap(queued_requests_); | 384 requests_.swap(queued_requests_); |
| 364 else if (HasUserGestureRequest(queued_frame_requests_)) | 385 else if (HasUserGestureRequest(queued_frame_requests_)) |
| 365 requests_.swap(queued_frame_requests_); | 386 requests_.swap(queued_frame_requests_); |
| 366 else if (queued_requests_.size()) | 387 else if (queued_requests_.size()) |
| 367 requests_.swap(queued_requests_); | 388 requests_.swap(queued_requests_); |
| 368 else | 389 else |
| 369 requests_.swap(queued_frame_requests_); | 390 requests_.swap(queued_frame_requests_); |
| 370 | 391 |
| 371 // Sets the default value for each request to be 'accept'. | 392 // Sets the default value for each request to be 'accept'. |
| 372 // TODO(leng): Currently all requests default to true. If that changes: | 393 // TODO(leng): Currently all requests default to true. If that changes: |
| 373 // a) Add additional accept_state queues to store default values. | 394 // a) Add additional accept_state queues to store default values. |
| 374 // b) Change the request API to provide the default value. | 395 // b) Change the request API to provide the default value. |
| 375 accept_states_.resize(requests_.size(), true); | 396 accept_states_.resize(requests_.size(), true); |
| 376 } | 397 } |
| 377 | 398 |
| 378 view_->Show(requests_, accept_states_); | 399 DCHECK(bubble_manager_); |
| 400 bubble_manager_->ShowBubble(bubble_delegate_.get()); |
| 401 // view_->Show(requests_, accept_states_); |
| 402 |
| 379 NotifyBubbleAdded(); | 403 NotifyBubbleAdded(); |
| 380 | 404 |
| 381 // If in testing mode, automatically respond to the bubble that was shown. | 405 // If in testing mode, automatically respond to the bubble that was shown. |
| 382 if (auto_response_for_test_ != NONE) | 406 if (auto_response_for_test_ != NONE) |
| 383 DoAutoResponseForTesting(); | 407 DoAutoResponseForTesting(); |
| 384 } | 408 } |
| 385 | 409 |
| 386 void PermissionBubbleManager::FinalizeBubble() { | 410 void PermissionBubbleManager::FinalizeBubble() { |
| 387 if (view_) | 411 if (bubble_manager_) { |
| 388 view_->Hide(); | 412 DCHECK(bubble_manager_); |
| 413 bubble_manager_->HideBubble(bubble_delegate_.get()); |
| 414 } |
| 389 | 415 |
| 390 std::vector<PermissionBubbleRequest*>::iterator requests_iter; | 416 std::vector<PermissionBubbleRequest*>::iterator requests_iter; |
| 391 for (requests_iter = requests_.begin(); | 417 for (requests_iter = requests_.begin(); |
| 392 requests_iter != requests_.end(); | 418 requests_iter != requests_.end(); |
| 393 requests_iter++) { | 419 requests_iter++) { |
| 394 (*requests_iter)->RequestFinished(); | 420 (*requests_iter)->RequestFinished(); |
| 395 } | 421 } |
| 396 requests_.clear(); | 422 requests_.clear(); |
| 397 accept_states_.clear(); | 423 accept_states_.clear(); |
| 398 if (queued_requests_.size() || queued_frame_requests_.size()) | 424 if (queued_requests_.size() || queued_frame_requests_.size()) |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 case DENY_ALL: | 494 case DENY_ALL: |
| 469 Deny(); | 495 Deny(); |
| 470 break; | 496 break; |
| 471 case DISMISS: | 497 case DISMISS: |
| 472 Closing(); | 498 Closing(); |
| 473 break; | 499 break; |
| 474 case NONE: | 500 case NONE: |
| 475 NOTREACHED(); | 501 NOTREACHED(); |
| 476 } | 502 } |
| 477 } | 503 } |
| OLD | NEW |