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

Side by Side 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: edited comment 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "chrome/browser/ui/website_settings/permission_bubble_request.h" 8 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
9 #include "chrome/common/chrome_switches.h" 9 #include "chrome/common/chrome_switches.h"
10 10
11 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PermissionBubbleManager); 11 DEFINE_WEB_CONTENTS_USER_DATA_KEY(PermissionBubbleManager);
12 12
13 namespace {
14
15 // This is how many ms to wait to see if there's another permission request
16 // we should coalesce.
17 const int kPermissionsCoalesceIntervalMs = 400;
18
19 }
20
13 // static 21 // static
14 bool PermissionBubbleManager::Enabled() { 22 bool PermissionBubbleManager::Enabled() {
15 return CommandLine::ForCurrentProcess()->HasSwitch( 23 return CommandLine::ForCurrentProcess()->HasSwitch(
16 switches::kEnablePermissionsBubbles); 24 switches::kEnablePermissionsBubbles);
17 } 25 }
18 26
19 void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) { 27 void PermissionBubbleManager::AddRequest(PermissionBubbleRequest* request) {
20 // Don't re-add an existing request. 28 // Don't re-add an existing request.
21 std::vector<PermissionBubbleRequest*>::iterator di; 29 std::vector<PermissionBubbleRequest*>::iterator di;
22 for (di = requests_.begin(); di != requests_.end(); di++) { 30 for (di = requests_.begin(); di != requests_.end(); di++) {
23 if (*di == request) 31 if (*di == request)
24 return; 32 return;
25 } 33 }
26 34
35 if (bubble_showing_) {
36 for (di = queued_requests_.begin(); di != queued_requests_.end(); di++) {
37 if (*di == request)
38 return;
39 }
40 queued_requests_.push_back(request);
41 return;
42 }
43
27 requests_.push_back(request); 44 requests_.push_back(request);
28 // TODO(gbillock): do we need to make default state a request property? 45 // TODO(gbillock): do we need to make default state a request property?
29 accept_state_.push_back(false); 46 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.
30 47
31 // TODO(gbillock): need significantly more complex logic here to deal 48 // Start the timer when there is both a view and a request.
32 // with various states of the manager. 49 if (view_ && !timer_->IsRunning()) {
33 50 timer_->Reset();
34 if (view_ && !bubble_showing_) {
35 view_->Show(requests_, accept_state_, customization_mode_);
36 bubble_showing_ = true;
37 } 51 }
38 } 52 }
39 53
40 void PermissionBubbleManager::SetView(PermissionBubbleView* view) { 54 void PermissionBubbleManager::SetView(PermissionBubbleView* view) {
41 if (view == view_) 55 if (view == view_)
42 return; 56 return;
43 57
44 if (view_ != NULL) { 58 if (view_ != NULL) {
45 view_->SetDelegate(NULL); 59 view_->SetDelegate(NULL);
46 view_->Hide(); 60 view_->Hide();
47 } 61 }
48 62
49 view_ = view; 63 view_ = view;
50 if (view_ == NULL) 64 if (view_ == NULL)
51 return; 65 return;
52 66
53 if (bubble_showing_) { 67 if (bubble_showing_) {
54 view_->SetDelegate(this); 68 view_->SetDelegate(this);
55 view_->Show(requests_, accept_state_, customization_mode_); 69 view_->Show(requests_, accept_states_, customization_mode_);
56 } else if (!requests_.empty()) { 70 } else if (!requests_.empty()) {
57 bubble_showing_ = true; 71 if (!timer_->IsRunning()) {
58 view_->SetDelegate(this); 72 timer_->Reset();
59 view_->Show(requests_, accept_state_, customization_mode_); 73 }
60 } else { 74 } else {
61 view_->Hide(); 75 view_->Hide();
62 return; 76 return;
63 } 77 }
64 } 78 }
65 79
66 PermissionBubbleManager::PermissionBubbleManager( 80 PermissionBubbleManager::PermissionBubbleManager(
67 content::WebContents* web_contents) 81 content::WebContents* web_contents)
68 : content::WebContentsObserver(web_contents), 82 : content::WebContentsObserver(web_contents),
69 bubble_showing_(false), 83 bubble_showing_(false),
70 view_(NULL), 84 view_(NULL),
71 customization_mode_(false) { 85 customization_mode_(false) {
86 timer_.reset(new base::Timer(FROM_HERE,
87 base::TimeDelta::FromMilliseconds(kPermissionsCoalesceIntervalMs),
88 base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)),
89 false));
72 } 90 }
73 91
74 PermissionBubbleManager::~PermissionBubbleManager() {} 92 PermissionBubbleManager::~PermissionBubbleManager() {}
75 93
94 void PermissionBubbleManager::DidFinishLoad(
95 int64 frame_id,
96 const GURL& validated_url,
97 bool is_main_frame,
98 content::RenderViewHost* render_view_host) {
99 // Allows extra time for additional requests to coalesce.
100 if (timer_->IsRunning())
101 timer_->Reset();
102 }
103
76 void PermissionBubbleManager::WebContentsDestroyed( 104 void PermissionBubbleManager::WebContentsDestroyed(
77 content::WebContents* web_contents) { 105 content::WebContents* web_contents) {
78 // Synthetic cancel event if the user closes the WebContents. 106 // Synthetic cancel event if the user closes the WebContents.
79 Closing(); 107 Closing();
80 108
81 // The WebContents is going away; be aggressively paranoid and delete 109 // The WebContents is going away; be aggressively paranoid and delete
82 // ourselves lest other parts of the system attempt to add permission bubbles 110 // ourselves lest other parts of the system attempt to add permission bubbles
83 // or use us otherwise during the destruction. 111 // or use us otherwise during the destruction.
84 web_contents->RemoveUserData(UserDataKey()); 112 web_contents->RemoveUserData(UserDataKey());
85 // That was the equivalent of "delete this". This object is now destroyed; 113 // That was the equivalent of "delete this". This object is now destroyed;
86 // returning from this function is the only safe thing to do. 114 // returning from this function is the only safe thing to do.
87 } 115 }
88 116
89 void PermissionBubbleManager::ToggleAccept(int request_index, bool new_value) { 117 void PermissionBubbleManager::ToggleAccept(int request_index, bool new_value) {
90 DCHECK(request_index < static_cast<int>(accept_state_.size())); 118 DCHECK(request_index < static_cast<int>(accept_states_.size()));
91 accept_state_[request_index] = new_value; 119 accept_states_[request_index] = new_value;
92 } 120 }
93 121
94 void PermissionBubbleManager::SetCustomizationMode() { 122 void PermissionBubbleManager::SetCustomizationMode() {
95 customization_mode_ = true; 123 customization_mode_ = true;
96 } 124 }
97 125
98 void PermissionBubbleManager::Accept() { 126 void PermissionBubbleManager::Accept() {
99 std::vector<PermissionBubbleRequest*>::iterator di; 127 std::vector<PermissionBubbleRequest*>::iterator di;
100 std::vector<bool>::iterator ai; 128 std::vector<bool>::iterator ai;
101 for (di = requests_.begin(), ai = accept_state_.begin(); 129 for (di = requests_.begin(), ai = accept_states_.begin();
102 di != requests_.end(); di++, ai++) { 130 di != requests_.end(); di++, ai++) {
103 if (*ai) 131 if (*ai)
104 (*di)->PermissionGranted(); 132 (*di)->PermissionGranted();
105 else 133 else
106 (*di)->PermissionDenied(); 134 (*di)->PermissionDenied();
107 } 135 }
108 FinalizeBubble(); 136 FinalizeBubble();
109 } 137 }
110 138
111 void PermissionBubbleManager::Deny() { 139 void PermissionBubbleManager::Deny() {
112 std::vector<PermissionBubbleRequest*>::iterator di; 140 std::vector<PermissionBubbleRequest*>::iterator di;
113 for (di = requests_.begin(); di != requests_.end(); di++) 141 for (di = requests_.begin(); di != requests_.end(); di++)
114 (*di)->PermissionDenied(); 142 (*di)->PermissionDenied();
115 FinalizeBubble(); 143 FinalizeBubble();
116 } 144 }
117 145
118 void PermissionBubbleManager::Closing() { 146 void PermissionBubbleManager::Closing() {
119 std::vector<PermissionBubbleRequest*>::iterator di; 147 std::vector<PermissionBubbleRequest*>::iterator di;
120 for (di = requests_.begin(); di != requests_.end(); di++) 148 for (di = requests_.begin(); di != requests_.end(); di++)
121 (*di)->Cancelled(); 149 (*di)->Cancelled();
122 FinalizeBubble(); 150 FinalizeBubble();
123 } 151 }
124 152
153 void PermissionBubbleManager::ShowBubble() {
154 if (view_ && !bubble_showing_ && requests_.size()) {
155 view_->SetDelegate(this);
156 view_->Show(requests_, accept_states_, customization_mode_);
157 bubble_showing_ = true;
158 }
159 }
160
125 void PermissionBubbleManager::FinalizeBubble() { 161 void PermissionBubbleManager::FinalizeBubble() {
126 std::vector<PermissionBubbleRequest*>::iterator di; 162 std::vector<PermissionBubbleRequest*>::iterator di;
127 for (di = requests_.begin(); di != requests_.end(); di++) 163 for (di = requests_.begin(); di != requests_.end(); di++)
128 (*di)->RequestFinished(); 164 (*di)->RequestFinished();
129 requests_.clear(); 165 requests_.clear();
130 accept_state_.clear(); 166 accept_states_.clear();
167 bubble_showing_ = false;
168 if (queued_requests_.size()) {
169 requests_ = queued_requests_;
170 queued_requests_.clear();
171 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.
172 // TODO(leng): Explore other options of showing the next bubble. The
173 // advantage of this is that it uses the same code path as the first bubble.
174 timer_->Reset();
175 }
131 } 176 }
132 177
178 void PermissionBubbleManager::SetCoalesceIntervalForTesting(int interval_ms) {
179 timer_.reset(new base::Timer(FROM_HERE,
180 base::TimeDelta::FromMilliseconds(interval_ms),
181 base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)),
182 false));
183 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698