Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(15)

Unified Diff: chrome/browser/ui/website_settings/permission_bubble_manager.cc

Issue 150103013: Add basic coalescing behavior to the permission bubble manager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits addressed Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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..990d124df440414409cc28736b54a2edc59db926 100644
--- a/chrome/browser/ui/website_settings/permission_bubble_manager.cc
+++ b/chrome/browser/ui/website_settings/permission_bubble_manager.cc
@@ -10,6 +10,14 @@
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(
@@ -18,24 +26,32 @@ bool PermissionBubbleManager::Enabled() {
void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) {
// Don't re-add an existing request.
- std::vector<PermissionBubbleRequest*>::iterator di;
- for (di = requests_.begin(); di != requests_.end(); di++) {
- if (*di == request)
+ std::vector<PermissionBubbleRequest*>::iterator requests_iter;
+ for (requests_iter = requests_.begin();
+ requests_iter != requests_.end();
+ requests_iter++) {
+ if (*requests_iter == request)
return;
}
+ if (bubble_showing_) {
+ for (requests_iter = queued_requests_.begin();
+ requests_iter != queued_requests_.end();
+ requests_iter++) {
+ if (*requests_iter == 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);
+ accept_states_.push_back(true);
- // TODO(gbillock): need significantly more complex logic here to deal
- // with various states of the manager.
-
- 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 +61,7 @@ void PermissionBubbleManager::SetView(PermissionBubbleView* view) {
if (view_ != NULL) {
view_->SetDelegate(NULL);
view_->Hide();
+ bubble_showing_ = false;
}
view_ = view;
@@ -53,11 +70,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 +84,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,53 +116,86 @@ 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();
- di != requests_.end(); di++, ai++) {
- if (*ai)
- (*di)->PermissionGranted();
+ std::vector<PermissionBubbleRequest*>::iterator requests_iter;
+ std::vector<bool>::iterator accepts_iter = accept_states_.begin();
+ for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin();
+ requests_iter != requests_.end();
+ requests_iter++, accepts_iter++) {
+ if (*accepts_iter)
+ (*requests_iter)->PermissionGranted();
else
- (*di)->PermissionDenied();
+ (*requests_iter)->PermissionDenied();
}
FinalizeBubble();
}
void PermissionBubbleManager::Deny() {
- std::vector<PermissionBubbleRequest*>::iterator di;
- for (di = requests_.begin(); di != requests_.end(); di++)
- (*di)->PermissionDenied();
+ std::vector<PermissionBubbleRequest*>::iterator requests_iter;
+ for (requests_iter = requests_.begin();
+ requests_iter != requests_.end();
+ requests_iter++) {
+ (*requests_iter)->PermissionDenied();
+ }
FinalizeBubble();
}
void PermissionBubbleManager::Closing() {
- std::vector<PermissionBubbleRequest*>::iterator di;
- for (di = requests_.begin(); di != requests_.end(); di++)
- (*di)->Cancelled();
+ std::vector<PermissionBubbleRequest*>::iterator requests_iter;
+ for (requests_iter = requests_.begin();
+ requests_iter != requests_.end();
+ requests_iter++) {
+ (*requests_iter)->Cancelled();
+ }
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);
view_->Hide();
}
- std::vector<PermissionBubbleRequest*>::iterator di;
- for (di = requests_.begin(); di != requests_.end(); di++)
- (*di)->RequestFinished();
+ std::vector<PermissionBubbleRequest*>::iterator requests_iter;
+ for (requests_iter = requests_.begin();
+ requests_iter != requests_.end();
+ requests_iter++) {
+ (*requests_iter)->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));
+}

Powered by Google App Engine
This is Rietveld 408576698