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 2382613605e0c54a58fad7d316a9c5663c388a8e..a51d4c775d766a59adab474ed3b70f2be11a78c7 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); |
} |
void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { |
@@ -24,16 +32,22 @@ void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { |
return; |
} |
+ if (bubble_showing_) { |
+ for (di = queued_requests_.begin(); di != queued_requests_.end(); di++) { |
+ 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(false); |
- |
- // TODO(gbillock): need significantly more complex logic here to deal |
- // with various states of the manager. |
+ accept_states_.push_back(false); |
Greg Billock
2014/02/11 16:26:50
I think this'll need a merge -- should be 'true'
leng
2014/02/11 16:46:51
Done.
|
- if (view_ && !bubble_showing_) { |
- 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(); |
} |
} |
@@ -52,11 +66,11 @@ void PermissionBubbleManager::SetView(PermissionBubbleView* view) { |
if (bubble_showing_) { |
view_->SetDelegate(this); |
- view_->Show(requests_, accept_state_, customization_mode_); |
+ view_->Show(requests_, accept_states_, customization_mode_); |
} else if (!requests_.empty()) { |
- bubble_showing_ = true; |
- view_->SetDelegate(this); |
- view_->Show(requests_, accept_state_, customization_mode_); |
+ if (!timer_->IsRunning()) { |
+ timer_->Reset(); |
+ } |
} else { |
view_->Hide(); |
return; |
@@ -69,10 +83,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. |
@@ -87,8 +115,8 @@ 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() { |
@@ -98,7 +126,7 @@ void PermissionBubbleManager::SetCustomizationMode() { |
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(); |
@@ -122,11 +150,34 @@ 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() { |
std::vector<PermissionBubbleRequest*>::iterator di; |
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_; |
+ queued_requests_.clear(); |
+ accept_states_.resize(requests_.size(), true); |
Greg Billock
2014/02/11 16:26:50
LG. I'd move this right under 'requests_ = queued_
leng
2014/02/11 16:46:51
Done.
|
+ // 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)); |
+} |