Chromium Code Reviews| Index: chrome/browser/ui/website_settings/permission_bubble_manager.cc |
| diff --git a/chrome/browser/ui/website_settings/permission_bubble_manager.cc b/chrome/browser/ui/website_settings/permission_bubble_manager.cc |
| index cb3df39d6b39ba73206ca70d492a2a430354a009..8baef54a9cd103fc4d3973f435177e6bf68b9e0b 100644 |
| --- a/chrome/browser/ui/website_settings/permission_bubble_manager.cc |
| +++ b/chrome/browser/ui/website_settings/permission_bubble_manager.cc |
| @@ -10,10 +10,18 @@ |
| DEFINE_WEB_CONTENTS_USER_DATA_KEY(PermissionBubbleManager); |
| +namespace { |
| + |
| +// This is how many ms to wait to see if there's another permission request |
| +// we should coalesce. |
| +const int kPermissionsCoalesceIntervalMs = 400; |
| + |
| +} |
| + |
| // static |
| bool PermissionBubbleManager::Enabled() { |
| return CommandLine::ForCurrentProcess()->HasSwitch( |
| - switches::kEnablePermissionsBubbles); |
| + switches::kEnablePermissionsBubbles); |
|
markusheintz_
2014/02/12 17:20:07
nit: please us the correct indentation. (indent +2
leng
2014/02/12 23:09:10
Done.
|
| } |
| void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { |
| @@ -24,18 +32,22 @@ void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { |
| return; |
| } |
| + if (bubble_showing_) { |
| + for (di = queued_requests_.begin(); di != queued_requests_.end(); di++) { |
|
markusheintz_
2014/02/12 17:20:07
Could we use a better name than "di" for the itera
leng
2014/02/12 23:09:10
Done.
|
| + if (*di == request) |
| + return; |
| + } |
| + queued_requests_.push_back(request); |
| + return; |
| + } |
| + |
| requests_.push_back(request); |
| // TODO(gbillock): do we need to make default state a request property? |
| - accept_state_.push_back(true); |
| - |
| - // TODO(gbillock): need significantly more complex logic here to deal |
| - // with various states of the manager. |
| + accept_states_.push_back(true); |
| - if (view_ && !bubble_showing_) { |
| - view_->SetDelegate(this); |
| - view_->Show(requests_, accept_state_, customization_mode_); |
| - bubble_showing_ = true; |
| - } |
| + // Start the timer when there is both a view and a request. |
| + if (view_ && !timer_->IsRunning()) |
| + timer_->Reset(); |
| } |
| void PermissionBubbleManager::SetView(PermissionBubbleView* view) { |
| @@ -45,6 +57,7 @@ void PermissionBubbleManager::SetView(PermissionBubbleView* view) { |
| if (view_ != NULL) { |
| view_->SetDelegate(NULL); |
| view_->Hide(); |
| + bubble_showing_ = false; |
| } |
| view_ = view; |
| @@ -53,11 +66,10 @@ void PermissionBubbleManager::SetView(PermissionBubbleView* view) { |
| else |
| return; |
| - if (!requests_.empty()) |
| - bubble_showing_ = true; |
| - |
| - if (bubble_showing_) |
| - view_->Show(requests_, accept_state_, customization_mode_); |
| + // Even if there are requests queued up, add a short delay before the bubble |
| + // appears. |
| + if (!requests_.empty() && !timer_->IsRunning()) |
| + timer_->Reset(); |
| else |
| view_->Hide(); |
| } |
| @@ -68,10 +80,24 @@ PermissionBubbleManager::PermissionBubbleManager( |
| bubble_showing_(false), |
| view_(NULL), |
| customization_mode_(false) { |
| + timer_.reset(new base::Timer(FROM_HERE, |
| + base::TimeDelta::FromMilliseconds(kPermissionsCoalesceIntervalMs), |
| + base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)), |
| + false)); |
| } |
| PermissionBubbleManager::~PermissionBubbleManager() {} |
| +void PermissionBubbleManager::DidFinishLoad( |
| + int64 frame_id, |
| + const GURL& validated_url, |
| + bool is_main_frame, |
| + content::RenderViewHost* render_view_host) { |
| + // Allows extra time for additional requests to coalesce. |
| + if (timer_->IsRunning()) |
| + timer_->Reset(); |
| +} |
| + |
| void PermissionBubbleManager::WebContentsDestroyed( |
| content::WebContents* web_contents) { |
| // Synthetic cancel event if the user closes the WebContents. |
| @@ -86,20 +112,20 @@ void PermissionBubbleManager::WebContentsDestroyed( |
| } |
| void PermissionBubbleManager::ToggleAccept(int request_index, bool new_value) { |
| - DCHECK(request_index < static_cast<int>(accept_state_.size())); |
| - accept_state_[request_index] = new_value; |
| + DCHECK(request_index < static_cast<int>(accept_states_.size())); |
| + accept_states_[request_index] = new_value; |
| } |
| void PermissionBubbleManager::SetCustomizationMode() { |
| customization_mode_ = true; |
| if (view_) |
| - view_->Show(requests_, accept_state_, customization_mode_); |
| + view_->Show(requests_, accept_states_, customization_mode_); |
| } |
| void PermissionBubbleManager::Accept() { |
| std::vector<PermissionBubbleRequest*>::iterator di; |
| std::vector<bool>::iterator ai; |
| - for (di = requests_.begin(), ai = accept_state_.begin(); |
| + for (di = requests_.begin(), ai = accept_states_.begin(); |
| di != requests_.end(); di++, ai++) { |
| if (*ai) |
| (*di)->PermissionGranted(); |
| @@ -123,6 +149,14 @@ void PermissionBubbleManager::Closing() { |
| FinalizeBubble(); |
| } |
| +void PermissionBubbleManager::ShowBubble() { |
| + if (view_ && !bubble_showing_ && requests_.size()) { |
| + view_->SetDelegate(this); |
| + view_->Show(requests_, accept_states_, customization_mode_); |
| + bubble_showing_ = true; |
| + } |
| +} |
| + |
| void PermissionBubbleManager::FinalizeBubble() { |
| if (view_) { |
| view_->SetDelegate(NULL); |
| @@ -133,6 +167,21 @@ void PermissionBubbleManager::FinalizeBubble() { |
| for (di = requests_.begin(); di != requests_.end(); di++) |
| (*di)->RequestFinished(); |
| requests_.clear(); |
| - accept_state_.clear(); |
| + accept_states_.clear(); |
| + bubble_showing_ = false; |
| + if (queued_requests_.size()) { |
| + requests_ = queued_requests_; |
| + accept_states_.resize(requests_.size(), true); |
| + queued_requests_.clear(); |
| + // TODO(leng): Explore other options of showing the next bubble. The |
| + // advantage of this is that it uses the same code path as the first bubble. |
| + timer_->Reset(); |
| + } |
| } |
| +void PermissionBubbleManager::SetCoalesceIntervalForTesting(int interval_ms) { |
| + timer_.reset(new base::Timer(FROM_HERE, |
| + base::TimeDelta::FromMilliseconds(interval_ms), |
| + base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)), |
| + false)); |
| +} |