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

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: fixed unit tests 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);
markusheintz_ 2014/02/12 17:20:07 nit: please us the correct indentation. (indent +2
leng 2014/02/12 23:09:10 Done.
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++) {
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.
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(true); 46 accept_states_.push_back(true);
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_->SetDelegate(this);
36 view_->Show(requests_, accept_state_, customization_mode_);
37 bubble_showing_ = true;
38 }
39 } 51 }
40 52
41 void PermissionBubbleManager::SetView(PermissionBubbleView* view) { 53 void PermissionBubbleManager::SetView(PermissionBubbleView* view) {
42 if (view == view_) 54 if (view == view_)
43 return; 55 return;
44 56
45 if (view_ != NULL) { 57 if (view_ != NULL) {
46 view_->SetDelegate(NULL); 58 view_->SetDelegate(NULL);
47 view_->Hide(); 59 view_->Hide();
60 bubble_showing_ = false;
48 } 61 }
49 62
50 view_ = view; 63 view_ = view;
51 if (view_) 64 if (view_)
52 view_->SetDelegate(this); 65 view_->SetDelegate(this);
53 else 66 else
54 return; 67 return;
55 68
56 if (!requests_.empty()) 69 // Even if there are requests queued up, add a short delay before the bubble
57 bubble_showing_ = true; 70 // appears.
58 71 if (!requests_.empty() && !timer_->IsRunning())
59 if (bubble_showing_) 72 timer_->Reset();
60 view_->Show(requests_, accept_state_, customization_mode_);
61 else 73 else
62 view_->Hide(); 74 view_->Hide();
63 } 75 }
64 76
65 PermissionBubbleManager::PermissionBubbleManager( 77 PermissionBubbleManager::PermissionBubbleManager(
66 content::WebContents* web_contents) 78 content::WebContents* web_contents)
67 : content::WebContentsObserver(web_contents), 79 : content::WebContentsObserver(web_contents),
68 bubble_showing_(false), 80 bubble_showing_(false),
69 view_(NULL), 81 view_(NULL),
70 customization_mode_(false) { 82 customization_mode_(false) {
83 timer_.reset(new base::Timer(FROM_HERE,
84 base::TimeDelta::FromMilliseconds(kPermissionsCoalesceIntervalMs),
85 base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)),
86 false));
71 } 87 }
72 88
73 PermissionBubbleManager::~PermissionBubbleManager() {} 89 PermissionBubbleManager::~PermissionBubbleManager() {}
74 90
91 void PermissionBubbleManager::DidFinishLoad(
92 int64 frame_id,
93 const GURL& validated_url,
94 bool is_main_frame,
95 content::RenderViewHost* render_view_host) {
96 // Allows extra time for additional requests to coalesce.
97 if (timer_->IsRunning())
98 timer_->Reset();
99 }
100
75 void PermissionBubbleManager::WebContentsDestroyed( 101 void PermissionBubbleManager::WebContentsDestroyed(
76 content::WebContents* web_contents) { 102 content::WebContents* web_contents) {
77 // Synthetic cancel event if the user closes the WebContents. 103 // Synthetic cancel event if the user closes the WebContents.
78 Closing(); 104 Closing();
79 105
80 // The WebContents is going away; be aggressively paranoid and delete 106 // The WebContents is going away; be aggressively paranoid and delete
81 // ourselves lest other parts of the system attempt to add permission bubbles 107 // ourselves lest other parts of the system attempt to add permission bubbles
82 // or use us otherwise during the destruction. 108 // or use us otherwise during the destruction.
83 web_contents->RemoveUserData(UserDataKey()); 109 web_contents->RemoveUserData(UserDataKey());
84 // That was the equivalent of "delete this". This object is now destroyed; 110 // That was the equivalent of "delete this". This object is now destroyed;
85 // returning from this function is the only safe thing to do. 111 // returning from this function is the only safe thing to do.
86 } 112 }
87 113
88 void PermissionBubbleManager::ToggleAccept(int request_index, bool new_value) { 114 void PermissionBubbleManager::ToggleAccept(int request_index, bool new_value) {
89 DCHECK(request_index < static_cast<int>(accept_state_.size())); 115 DCHECK(request_index < static_cast<int>(accept_states_.size()));
90 accept_state_[request_index] = new_value; 116 accept_states_[request_index] = new_value;
91 } 117 }
92 118
93 void PermissionBubbleManager::SetCustomizationMode() { 119 void PermissionBubbleManager::SetCustomizationMode() {
94 customization_mode_ = true; 120 customization_mode_ = true;
95 if (view_) 121 if (view_)
96 view_->Show(requests_, accept_state_, customization_mode_); 122 view_->Show(requests_, accept_states_, customization_mode_);
97 } 123 }
98 124
99 void PermissionBubbleManager::Accept() { 125 void PermissionBubbleManager::Accept() {
100 std::vector<PermissionBubbleRequest*>::iterator di; 126 std::vector<PermissionBubbleRequest*>::iterator di;
101 std::vector<bool>::iterator ai; 127 std::vector<bool>::iterator ai;
102 for (di = requests_.begin(), ai = accept_state_.begin(); 128 for (di = requests_.begin(), ai = accept_states_.begin();
103 di != requests_.end(); di++, ai++) { 129 di != requests_.end(); di++, ai++) {
104 if (*ai) 130 if (*ai)
105 (*di)->PermissionGranted(); 131 (*di)->PermissionGranted();
106 else 132 else
107 (*di)->PermissionDenied(); 133 (*di)->PermissionDenied();
108 } 134 }
109 FinalizeBubble(); 135 FinalizeBubble();
110 } 136 }
111 137
112 void PermissionBubbleManager::Deny() { 138 void PermissionBubbleManager::Deny() {
113 std::vector<PermissionBubbleRequest*>::iterator di; 139 std::vector<PermissionBubbleRequest*>::iterator di;
114 for (di = requests_.begin(); di != requests_.end(); di++) 140 for (di = requests_.begin(); di != requests_.end(); di++)
115 (*di)->PermissionDenied(); 141 (*di)->PermissionDenied();
116 FinalizeBubble(); 142 FinalizeBubble();
117 } 143 }
118 144
119 void PermissionBubbleManager::Closing() { 145 void PermissionBubbleManager::Closing() {
120 std::vector<PermissionBubbleRequest*>::iterator di; 146 std::vector<PermissionBubbleRequest*>::iterator di;
121 for (di = requests_.begin(); di != requests_.end(); di++) 147 for (di = requests_.begin(); di != requests_.end(); di++)
122 (*di)->Cancelled(); 148 (*di)->Cancelled();
123 FinalizeBubble(); 149 FinalizeBubble();
124 } 150 }
125 151
152 void PermissionBubbleManager::ShowBubble() {
153 if (view_ && !bubble_showing_ && requests_.size()) {
154 view_->SetDelegate(this);
155 view_->Show(requests_, accept_states_, customization_mode_);
156 bubble_showing_ = true;
157 }
158 }
159
126 void PermissionBubbleManager::FinalizeBubble() { 160 void PermissionBubbleManager::FinalizeBubble() {
127 if (view_) { 161 if (view_) {
128 view_->SetDelegate(NULL); 162 view_->SetDelegate(NULL);
129 view_->Hide(); 163 view_->Hide();
130 } 164 }
131 165
132 std::vector<PermissionBubbleRequest*>::iterator di; 166 std::vector<PermissionBubbleRequest*>::iterator di;
133 for (di = requests_.begin(); di != requests_.end(); di++) 167 for (di = requests_.begin(); di != requests_.end(); di++)
134 (*di)->RequestFinished(); 168 (*di)->RequestFinished();
135 requests_.clear(); 169 requests_.clear();
136 accept_state_.clear(); 170 accept_states_.clear();
171 bubble_showing_ = false;
172 if (queued_requests_.size()) {
173 requests_ = queued_requests_;
174 accept_states_.resize(requests_.size(), true);
175 queued_requests_.clear();
176 // TODO(leng): Explore other options of showing the next bubble. The
177 // advantage of this is that it uses the same code path as the first bubble.
178 timer_->Reset();
179 }
137 } 180 }
138 181
182 void PermissionBubbleManager::SetCoalesceIntervalForTesting(int interval_ms) {
183 timer_.reset(new base::Timer(FROM_HERE,
184 base::TimeDelta::FromMilliseconds(interval_ms),
185 base::Bind(&PermissionBubbleManager::ShowBubble, base::Unretained(this)),
186 false));
187 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698