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

Side by Side Diff: chrome/browser/ui/website_settings/permission_bubble_manager.cc

Issue 1251633002: Add BubbleManager to manage bubbles and ChromeBubbleManager for events. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update Created 5 years, 4 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
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 "base/metrics/user_metrics_action.h" 8 #include "base/metrics/user_metrics_action.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/website_settings/permission_bubble_delegate.h"
9 #include "chrome/browser/ui/website_settings/permission_bubble_request.h" 11 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
10 #include "chrome/common/chrome_switches.h" 12 #include "chrome/common/chrome_switches.h"
11 #include "content/public/browser/browser_thread.h" 13 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/navigation_details.h" 14 #include "content/public/browser/navigation_details.h"
13 #include "content/public/browser/user_metrics.h" 15 #include "content/public/browser/user_metrics.h"
14 16
15 namespace { 17 namespace {
16 18
17 class CancelledRequest : public PermissionBubbleRequest { 19 class CancelledRequest : public PermissionBubbleRequest {
18 public: 20 public:
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 return true; 74 return true;
73 } 75 }
74 76
75 PermissionBubbleManager::PermissionBubbleManager( 77 PermissionBubbleManager::PermissionBubbleManager(
76 content::WebContents* web_contents) 78 content::WebContents* web_contents)
77 : content::WebContentsObserver(web_contents), 79 : content::WebContentsObserver(web_contents),
78 require_user_gesture_(false), 80 require_user_gesture_(false),
79 #if !defined(OS_ANDROID) // No bubbles in android tests. 81 #if !defined(OS_ANDROID) // No bubbles in android tests.
80 view_factory_(base::Bind(&PermissionBubbleView::Create)), 82 view_factory_(base::Bind(&PermissionBubbleView::Create)),
81 #endif 83 #endif
82 view_(nullptr),
83 main_frame_has_fully_loaded_(false), 84 main_frame_has_fully_loaded_(false),
84 auto_response_for_test_(NONE), 85 auto_response_for_test_(NONE),
85 weak_factory_(this) { 86 weak_factory_(this) {
86 } 87 }
87 88
88 PermissionBubbleManager::~PermissionBubbleManager() { 89 PermissionBubbleManager::~PermissionBubbleManager() {
89 if (view_ != NULL) 90 HideBubble();
90 view_->SetDelegate(NULL);
91 91
92 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 92 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
93 for (requests_iter = requests_.begin(); 93 for (requests_iter = requests_.begin();
94 requests_iter != requests_.end(); 94 requests_iter != requests_.end();
95 requests_iter++) { 95 requests_iter++) {
96 (*requests_iter)->RequestFinished(); 96 (*requests_iter)->RequestFinished();
97 } 97 }
98 for (requests_iter = queued_requests_.begin(); 98 for (requests_iter = queued_requests_.begin();
99 requests_iter != queued_requests_.end(); 99 requests_iter != queued_requests_.end();
100 requests_iter++) { 100 requests_iter++) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 167
168 std::vector<bool>::iterator accepts_iter = accept_states_.begin(); 168 std::vector<bool>::iterator accepts_iter = accept_states_.begin();
169 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin(); 169 for (requests_iter = requests_.begin(), accepts_iter = accept_states_.begin();
170 requests_iter != requests_.end(); 170 requests_iter != requests_.end();
171 requests_iter++, accepts_iter++) { 171 requests_iter++, accepts_iter++) {
172 if (*requests_iter != request) 172 if (*requests_iter != request)
173 continue; 173 continue;
174 174
175 // We can simply erase the current entry in the request table if we aren't 175 // We can simply erase the current entry in the request table if we aren't
176 // showing the dialog, or if we are showing it and it can accept the update. 176 // showing the dialog, or if we are showing it and it can accept the update.
177 bool can_erase = !IsBubbleVisible() || view_->CanAcceptRequestUpdate(); 177 bool can_erase = !IsBubbleVisible();
178
179 // TODO(hcarmona): Don't forget this logic. Maybe improve it? Or remove it?
180 // bool can_erase = !IsBubbleVisible() || view_->CanAcceptRequestUpdate();
181
178 if (can_erase) { 182 if (can_erase) {
179 (*requests_iter)->RequestFinished(); 183 (*requests_iter)->RequestFinished();
180 requests_.erase(requests_iter); 184 requests_.erase(requests_iter);
181 accept_states_.erase(accepts_iter); 185 accept_states_.erase(accepts_iter);
182 186
183 if (IsBubbleVisible()) { 187 if (IsBubbleVisible()) {
184 view_->Hide(); 188 HideBubble();
185 // Will redraw the bubble if it is being shown. 189 // Will redraw the bubble if it is being shown.
186 TriggerShowBubble(); 190 TriggerShowBubble();
187 } 191 }
188 return; 192 return;
189 } 193 }
190 194
191 // Cancel the existing request and replace it with a dummy. 195 // Cancel the existing request and replace it with a dummy.
192 PermissionBubbleRequest* cancelled_request = 196 PermissionBubbleRequest* cancelled_request =
193 new CancelledRequest(*requests_iter); 197 new CancelledRequest(*requests_iter);
194 (*requests_iter)->RequestFinished(); 198 (*requests_iter)->RequestFinished();
195 *requests_iter = cancelled_request; 199 *requests_iter = cancelled_request;
196 return; 200 return;
197 } 201 }
198 202
199 NOTREACHED(); // Callers should not cancel requests that are not pending. 203 NOTREACHED(); // Callers should not cancel requests that are not pending.
200 } 204 }
201 205
202 void PermissionBubbleManager::HideBubble() { 206 void PermissionBubbleManager::HideBubble() {
203 // Disengage from the existing view if there is one. 207 if (!active_bubble_)
204 if (!view_)
205 return; 208 return;
206 209 browser_->bubble_manager()->HideBubble(active_bubble_);
207 view_->SetDelegate(nullptr);
208 view_->Hide();
209 view_.reset();
210 } 210 }
211 211
212 void PermissionBubbleManager::DisplayPendingRequests(Browser* browser) { 212 void PermissionBubbleManager::DisplayPendingRequests() {
213 if (IsBubbleVisible()) 213 if (IsBubbleVisible())
214 return; 214 return;
215 215
216 view_ = view_factory_.Run(browser);
217 view_->SetDelegate(this);
218
219 TriggerShowBubble(); 216 TriggerShowBubble();
220 } 217 }
221 218
222 void PermissionBubbleManager::UpdateAnchorPosition() {
223 if (view_)
224 view_->UpdateAnchorPosition();
225 }
226
227 bool PermissionBubbleManager::IsBubbleVisible() { 219 bool PermissionBubbleManager::IsBubbleVisible() {
228 return view_ && view_->IsVisible(); 220 // TODO(hcarmona): anything else for "visible check"?
229 } 221 return active_bubble_;
230
231 gfx::NativeWindow PermissionBubbleManager::GetBubbleWindow() {
232 if (view_)
233 return view_->GetNativeWindow();
234 return nullptr;
235 } 222 }
236 223
237 void PermissionBubbleManager::RequireUserGesture(bool required) { 224 void PermissionBubbleManager::RequireUserGesture(bool required) {
238 require_user_gesture_ = required; 225 require_user_gesture_ = required;
239 } 226 }
240 227
241 void PermissionBubbleManager::DidNavigateMainFrame( 228 void PermissionBubbleManager::DidNavigateMainFrame(
242 const content::LoadCommittedDetails& details, 229 const content::LoadCommittedDetails& details,
243 const content::FrameNavigateParams& params) { 230 const content::FrameNavigateParams& params) {
244 if (details.is_in_page) 231 if (details.is_in_page)
(...skipping 17 matching lines...) Expand all
262 ScheduleShowBubble(); 249 ScheduleShowBubble();
263 } 250 }
264 251
265 void PermissionBubbleManager::NavigationEntryCommitted( 252 void PermissionBubbleManager::NavigationEntryCommitted(
266 const content::LoadCommittedDetails& details) { 253 const content::LoadCommittedDetails& details) {
267 // No permissions requests pending. 254 // No permissions requests pending.
268 if (request_url_.is_empty()) 255 if (request_url_.is_empty())
269 return; 256 return;
270 257
271 // If we have navigated to a new url or reloaded the page... 258 // If we have navigated to a new url or reloaded the page...
272 // GetAsReferrer strips fragment and username/password, meaning 259 if (!details.is_in_page ||
273 // the navigation is really to the same page. 260 details.type == content::NAVIGATION_TYPE_SAME_PAGE ||
274 if ((request_url_.GetAsReferrer() != 261 details.type == content::NAVIGATION_TYPE_EXISTING_PAGE) {
275 web_contents()->GetLastCommittedURL().GetAsReferrer()) || 262 // kill off existing bubble and cancel any pending requests.
276 (details.type == content::NAVIGATION_TYPE_EXISTING_PAGE &&
277 !details.is_in_page)) {
278 // Kill off existing bubble and cancel any pending requests.
279 CancelPendingQueues(); 263 CancelPendingQueues();
280 FinalizeBubble(); 264 FinalizeBubble();
281 } 265 }
282 } 266 }
283 267
284 void PermissionBubbleManager::WebContentsDestroyed() { 268 void PermissionBubbleManager::WebContentsDestroyed() {
285 // If the web contents has been destroyed, treat the bubble as cancelled. 269 // If the web contents has been destroyed, treat the bubble as cancelled.
286 CancelPendingQueues(); 270 CancelPendingQueues();
287 FinalizeBubble(); 271 FinalizeBubble();
288 272
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 return; 324 return;
341 325
342 content::BrowserThread::PostTask( 326 content::BrowserThread::PostTask(
343 content::BrowserThread::UI, 327 content::BrowserThread::UI,
344 FROM_HERE, 328 FROM_HERE,
345 base::Bind(&PermissionBubbleManager::TriggerShowBubble, 329 base::Bind(&PermissionBubbleManager::TriggerShowBubble,
346 weak_factory_.GetWeakPtr())); 330 weak_factory_.GetWeakPtr()));
347 } 331 }
348 332
349 void PermissionBubbleManager::TriggerShowBubble() { 333 void PermissionBubbleManager::TriggerShowBubble() {
350 if (!view_)
351 return;
352 if (IsBubbleVisible()) 334 if (IsBubbleVisible())
353 return; 335 return;
354 if (!main_frame_has_fully_loaded_) 336 if (!main_frame_has_fully_loaded_)
355 return; 337 return;
356 if (requests_.empty() && queued_requests_.empty() && 338 if (requests_.empty() && queued_requests_.empty() &&
357 queued_frame_requests_.empty()) { 339 queued_frame_requests_.empty()) {
358 return; 340 return;
359 } 341 }
360 342
361 if (requests_.empty()) { 343 if (requests_.empty()) {
362 // Queues containing a user-gesture-generated request have priority. 344 // Queues containing a user-gesture-generated request have priority.
363 if (HasUserGestureRequest(queued_requests_)) 345 if (HasUserGestureRequest(queued_requests_))
364 requests_.swap(queued_requests_); 346 requests_.swap(queued_requests_);
365 else if (HasUserGestureRequest(queued_frame_requests_)) 347 else if (HasUserGestureRequest(queued_frame_requests_))
366 requests_.swap(queued_frame_requests_); 348 requests_.swap(queued_frame_requests_);
367 else if (queued_requests_.size()) 349 else if (queued_requests_.size())
368 requests_.swap(queued_requests_); 350 requests_.swap(queued_requests_);
369 else 351 else
370 requests_.swap(queued_frame_requests_); 352 requests_.swap(queued_frame_requests_);
371 353
372 // Sets the default value for each request to be 'accept'. 354 // Sets the default value for each request to be 'accept'.
373 // TODO(leng): Currently all requests default to true. If that changes: 355 // TODO(leng): Currently all requests default to true. If that changes:
374 // a) Add additional accept_state queues to store default values. 356 // a) Add additional accept_state queues to store default values.
375 // b) Change the request API to provide the default value. 357 // b) Change the request API to provide the default value.
376 accept_states_.resize(requests_.size(), true); 358 accept_states_.resize(requests_.size(), true);
377 } 359 }
378 360
379 view_->Show(requests_, accept_states_); 361 active_bubble_ = browser_->bubble_manager()->ShowBubble(
362 make_scoped_ptr(new PermissionBubbleDelegate(this, view_factory_)));
363
380 NotifyBubbleAdded(); 364 NotifyBubbleAdded();
381 365
382 // If in testing mode, automatically respond to the bubble that was shown. 366 // If in testing mode, automatically respond to the bubble that was shown.
383 if (auto_response_for_test_ != NONE) 367 if (auto_response_for_test_ != NONE)
384 DoAutoResponseForTesting(); 368 DoAutoResponseForTesting();
385 } 369 }
386 370
387 void PermissionBubbleManager::FinalizeBubble() { 371 void PermissionBubbleManager::FinalizeBubble() {
388 if (view_) 372 HideBubble();
389 view_->Hide();
390 373
391 std::vector<PermissionBubbleRequest*>::iterator requests_iter; 374 std::vector<PermissionBubbleRequest*>::iterator requests_iter;
392 for (requests_iter = requests_.begin(); 375 for (requests_iter = requests_.begin();
393 requests_iter != requests_.end(); 376 requests_iter != requests_.end();
394 requests_iter++) { 377 requests_iter++) {
395 (*requests_iter)->RequestFinished(); 378 (*requests_iter)->RequestFinished();
396 } 379 }
397 requests_.clear(); 380 requests_.clear();
398 accept_states_.clear(); 381 accept_states_.clear();
399 if (queued_requests_.size() || queued_frame_requests_.size()) 382 if (queued_requests_.size() || queued_frame_requests_.size())
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 case DENY_ALL: 452 case DENY_ALL:
470 Deny(); 453 Deny();
471 break; 454 break;
472 case DISMISS: 455 case DISMISS:
473 Closing(); 456 Closing();
474 break; 457 break;
475 case NONE: 458 case NONE:
476 NOTREACHED(); 459 NOTREACHED();
477 } 460 }
478 } 461 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698