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

Side by Side Diff: chrome/browser/geolocation/chrome_geolocation_permission_context.cc

Issue 9491009: Show queued geolocation InfoBars when InfoBar is hidden. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Marcus requested changes. Created 8 years, 9 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
« no previous file with comments | « no previous file | chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/geolocation/chrome_geolocation_permission_context.h" 5 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
6 6
7 #include <functional> 7 #include <functional>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/content_settings/host_content_settings_map.h" 13 #include "chrome/browser/content_settings/host_content_settings_map.h"
14 #include "chrome/browser/content_settings/tab_specific_content_settings.h" 14 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
15 #include "chrome/browser/extensions/extension_service.h" 15 #include "chrome/browser/extensions/extension_service.h"
16 #include "chrome/browser/google/google_util.h" 16 #include "chrome/browser/google/google_util.h"
17 #include "chrome/browser/infobars/infobar.h"
17 #include "chrome/browser/infobars/infobar_tab_helper.h" 18 #include "chrome/browser/infobars/infobar_tab_helper.h"
18 #include "chrome/browser/prefs/pref_service.h" 19 #include "chrome/browser/prefs/pref_service.h"
19 #include "chrome/browser/profiles/profile.h" 20 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h" 21 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
21 #include "chrome/browser/tab_contents/tab_util.h" 22 #include "chrome/browser/tab_contents/tab_util.h"
22 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 23 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
24 #include "chrome/common/chrome_notification_types.h"
23 #include "chrome/common/extensions/extension.h" 25 #include "chrome/common/extensions/extension.h"
24 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
25 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
26 #include "content/public/browser/navigation_details.h" 28 #include "content/public/browser/navigation_details.h"
27 #include "content/public/browser/navigation_entry.h" 29 #include "content/public/browser/navigation_entry.h"
30 #include "content/public/browser/notification_details.h"
28 #include "content/public/browser/notification_registrar.h" 31 #include "content/public/browser/notification_registrar.h"
29 #include "content/public/browser/notification_source.h" 32 #include "content/public/browser/notification_source.h"
30 #include "content/public/browser/notification_types.h" 33 #include "content/public/browser/notification_types.h"
31 #include "content/public/browser/render_view_host.h" 34 #include "content/public/browser/render_view_host.h"
32 #include "content/public/browser/web_contents.h" 35 #include "content/public/browser/web_contents.h"
33 #include "grit/generated_resources.h" 36 #include "grit/generated_resources.h"
34 #include "grit/locale_settings.h" 37 #include "grit/locale_settings.h"
35 #include "grit/theme_resources.h" 38 #include "grit/theme_resources.h"
36 #include "grit/theme_resources_standard.h" 39 #include "grit/theme_resources_standard.h"
37 #include "net/base/net_util.h" 40 #include "net/base/net_util.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 int bridge_id, 74 int bridge_id,
72 const GURL& requesting_frame, 75 const GURL& requesting_frame,
73 const GURL& emebedder, 76 const GURL& emebedder,
74 base::Callback<void(bool)> callback); 77 base::Callback<void(bool)> callback);
75 78
76 // Cancels a specific infobar request. 79 // Cancels a specific infobar request.
77 void CancelInfoBarRequest(int render_process_id, 80 void CancelInfoBarRequest(int render_process_id,
78 int render_view_id, 81 int render_view_id,
79 int bridge_id); 82 int bridge_id);
80 83
81 // Called by the InfoBarDelegate to notify it's closed. It'll display a new
82 // InfoBar if there's any request pending for this tab.
83 void OnInfoBarClosed(int render_process_id,
84 int render_view_id,
85 int bridge_id);
86
87 // Called by the InfoBarDelegate to notify permission has been set. 84 // Called by the InfoBarDelegate to notify permission has been set.
88 // It'll notify and dismiss any other pending InfoBar request for the same 85 // It'll notify and dismiss any other pending InfoBar request for the same
89 // |requesting_frame| and embedder. 86 // |requesting_frame| and embedder.
90 void OnPermissionSet(int render_process_id, 87 void OnPermissionSet(int render_process_id,
91 int render_view_id, 88 int render_view_id,
92 int bridge_id, 89 int bridge_id,
93 const GURL& requesting_frame, 90 const GURL& requesting_frame,
94 const GURL& embedder, 91 const GURL& embedder,
95 bool allowed); 92 bool allowed);
96 93
97 // content::NotificationObserver 94 // content::NotificationObserver
98 virtual void Observe(int type, 95 virtual void Observe(int type,
99 const content::NotificationSource& source, 96 const content::NotificationSource& source,
100 const content::NotificationDetails& details); 97 const content::NotificationDetails& details) OVERRIDE;
101 98
102 private: 99 private:
103 struct PendingInfoBarRequest; 100 struct PendingInfoBarRequest;
104 class RequestEquals; 101 class RequestEquals;
105 102
106 typedef std::vector<PendingInfoBarRequest> PendingInfoBarRequests; 103 typedef std::vector<PendingInfoBarRequest> PendingInfoBarRequests;
107 104
108 // Shows the first pending infobar for this tab. 105 // Shows the first pending infobar for this tab.
109 void ShowQueuedInfoBar(int render_process_id, int render_view_id); 106 void ShowQueuedInfoBar(int render_process_id, int render_view_id,
107 InfoBarTabHelper* helper);
110 108
111 // Cancels an InfoBar request and returns the next iterator position. 109 // Removes any pending requests for a given dead tab.
bulach 2012/03/23 11:01:46 nit: I'd just say "for a given tab", this method d
John Knottenbelt 2012/03/23 11:45:50 Done.
112 PendingInfoBarRequests::iterator CancelInfoBarRequestInternal( 110 void ClearPendingInfoBarRequestsFromTab(int render_process_id,
bulach 2012/03/23 11:01:46 nit: maybe s/From/For/ ?
John Knottenbelt 2012/03/23 11:45:50 Done.
113 PendingInfoBarRequests::iterator i); 111 int render_view_id);
112
113 InfoBarTabHelper* GetInfoBarHelper(int render_process_id, int render_view_id);
114 bool AlreadyShowingInfoBar(int render_process_id, int render_view_id);
114 115
115 content::NotificationRegistrar registrar_; 116 content::NotificationRegistrar registrar_;
116 117
117 ChromeGeolocationPermissionContext* const geolocation_permission_context_; 118 ChromeGeolocationPermissionContext* const geolocation_permission_context_;
118 Profile* const profile_; 119 Profile* const profile_;
119 PendingInfoBarRequests pending_infobar_requests_; 120 PendingInfoBarRequests pending_infobar_requests_;
120 }; 121 };
121 122
122 123
123 // GeolocationConfirmInfoBarDelegate ------------------------------------------ 124 // GeolocationConfirmInfoBarDelegate ------------------------------------------
124 125
125 namespace { 126 namespace {
126 127
127 class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { 128 class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
128 public: 129 public:
129 GeolocationConfirmInfoBarDelegate( 130 GeolocationConfirmInfoBarDelegate(
130 InfoBarTabHelper* infobar_helper, 131 InfoBarTabHelper* infobar_helper,
131 GeolocationInfoBarQueueController* controller, 132 GeolocationInfoBarQueueController* controller,
132 int render_process_id, 133 int render_process_id,
133 int render_view_id, 134 int render_view_id,
134 int bridge_id, 135 int bridge_id,
135 const GURL& requesting_frame_url, 136 const GURL& requesting_frame_url,
136 const std::string& display_languages); 137 const std::string& display_languages);
137 138
139 int render_process_id() const { return render_process_id_; }
140 int render_view_id() const { return render_view_id_; }
141
138 private: 142 private:
139 virtual ~GeolocationConfirmInfoBarDelegate();
140 143
141 // ConfirmInfoBarDelegate: 144 // ConfirmInfoBarDelegate:
142 virtual bool ShouldExpire( 145 virtual bool ShouldExpire(
143 const content::LoadCommittedDetails& details) const OVERRIDE; 146 const content::LoadCommittedDetails& details) const OVERRIDE;
144 virtual gfx::Image* GetIcon() const OVERRIDE; 147 virtual gfx::Image* GetIcon() const OVERRIDE;
145 virtual Type GetInfoBarType() const OVERRIDE; 148 virtual Type GetInfoBarType() const OVERRIDE;
146 virtual string16 GetMessageText() const OVERRIDE; 149 virtual string16 GetMessageText() const OVERRIDE;
147 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; 150 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
148 virtual bool Accept() OVERRIDE; 151 virtual bool Accept() OVERRIDE;
149 virtual bool Cancel() OVERRIDE; 152 virtual bool Cancel() OVERRIDE;
(...skipping 28 matching lines...) Expand all
178 render_view_id_(render_view_id), 181 render_view_id_(render_view_id),
179 bridge_id_(bridge_id), 182 bridge_id_(bridge_id),
180 requesting_frame_url_(requesting_frame_url), 183 requesting_frame_url_(requesting_frame_url),
181 display_languages_(display_languages) { 184 display_languages_(display_languages) {
182 const NavigationEntry* committed_entry = 185 const NavigationEntry* committed_entry =
183 infobar_helper->web_contents()->GetController().GetLastCommittedEntry(); 186 infobar_helper->web_contents()->GetController().GetLastCommittedEntry();
184 committed_contents_unique_id_ = committed_entry ? 187 committed_contents_unique_id_ = committed_entry ?
185 committed_entry->GetUniqueID() : 0; 188 committed_entry->GetUniqueID() : 0;
186 } 189 }
187 190
188 GeolocationConfirmInfoBarDelegate::~GeolocationConfirmInfoBarDelegate() {
189 controller_->OnInfoBarClosed(render_process_id_, render_view_id_,
190 bridge_id_);
191 }
192
193 bool GeolocationConfirmInfoBarDelegate::ShouldExpire( 191 bool GeolocationConfirmInfoBarDelegate::ShouldExpire(
194 const content::LoadCommittedDetails& details) const { 192 const content::LoadCommittedDetails& details) const {
195 if (details.did_replace_entry || !details.is_navigation_to_different_page()) 193 if (details.did_replace_entry || !details.is_navigation_to_different_page())
196 return false; 194 return false;
197 return committed_contents_unique_id_ != details.entry->GetUniqueID() || 195 return committed_contents_unique_id_ != details.entry->GetUniqueID() ||
198 content::PageTransitionStripQualifier( 196 content::PageTransitionStripQualifier(
199 details.entry->GetTransitionType()) == 197 details.entry->GetTransitionType()) ==
200 content::PAGE_TRANSITION_RELOAD; 198 content::PAGE_TRANSITION_RELOAD;
201 } 199 }
202 200
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 bool Equals(int p_render_process_id, 274 bool Equals(int p_render_process_id,
277 int p_render_view_id, 275 int p_render_view_id,
278 int p_bridge_id) const; 276 int p_bridge_id) const;
279 277
280 int render_process_id; 278 int render_process_id;
281 int render_view_id; 279 int render_view_id;
282 int bridge_id; 280 int bridge_id;
283 GURL requesting_frame; 281 GURL requesting_frame;
284 GURL embedder; 282 GURL embedder;
285 base::Callback<void(bool)> callback; 283 base::Callback<void(bool)> callback;
286 InfoBarDelegate* infobar_delegate; 284 GeolocationConfirmInfoBarDelegate* infobar_delegate;
287 }; 285 };
288 286
289 GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest( 287 GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest(
290 int render_process_id, 288 int render_process_id,
291 int render_view_id, 289 int render_view_id,
292 int bridge_id, 290 int bridge_id,
293 const GURL& requesting_frame, 291 const GURL& requesting_frame,
294 const GURL& embedder, 292 const GURL& embedder,
295 base::Callback<void(bool)> callback) 293 base::Callback<void(bool)> callback)
296 : render_process_id(render_process_id), 294 : render_process_id(render_process_id),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 : render_process_id_(render_process_id), 345 : render_process_id_(render_process_id),
348 render_view_id_(render_view_id), 346 render_view_id_(render_view_id),
349 bridge_id_(bridge_id) { 347 bridge_id_(bridge_id) {
350 } 348 }
351 349
352 bool GeolocationInfoBarQueueController::RequestEquals::operator()( 350 bool GeolocationInfoBarQueueController::RequestEquals::operator()(
353 const PendingInfoBarRequest& request) const { 351 const PendingInfoBarRequest& request) const {
354 return request.Equals(render_process_id_, render_view_id_, bridge_id_); 352 return request.Equals(render_process_id_, render_view_id_, bridge_id_);
355 } 353 }
356 354
357
358 // GeolocationInfoBarQueueController ------------------------------------------ 355 // GeolocationInfoBarQueueController ------------------------------------------
359 356
360 GeolocationInfoBarQueueController::GeolocationInfoBarQueueController( 357 GeolocationInfoBarQueueController::GeolocationInfoBarQueueController(
361 ChromeGeolocationPermissionContext* geolocation_permission_context, 358 ChromeGeolocationPermissionContext* geolocation_permission_context,
362 Profile* profile) 359 Profile* profile)
363 : geolocation_permission_context_(geolocation_permission_context), 360 : geolocation_permission_context_(geolocation_permission_context),
364 profile_(profile) { 361 profile_(profile) {
365 } 362 }
366 363
367 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { 364 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() {
368 } 365 }
369 366
370 void GeolocationInfoBarQueueController::CreateInfoBarRequest( 367 void GeolocationInfoBarQueueController::CreateInfoBarRequest(
371 int render_process_id, 368 int render_process_id,
372 int render_view_id, 369 int render_view_id,
373 int bridge_id, 370 int bridge_id,
374 const GURL& requesting_frame, 371 const GURL& requesting_frame,
375 const GURL& embedder, 372 const GURL& embedder,
376 base::Callback<void(bool)> callback) { 373 base::Callback<void(bool)> callback) {
377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 374 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
378 375
379 // We shouldn't get duplicate requests. 376 // We shouldn't get duplicate requests.
380 DCHECK(std::find_if(pending_infobar_requests_.begin(), 377 DCHECK(std::find_if(pending_infobar_requests_.begin(),
381 pending_infobar_requests_.end(), 378 pending_infobar_requests_.end(),
382 RequestEquals(render_process_id, render_view_id, bridge_id)) == 379 RequestEquals(render_process_id, render_view_id, bridge_id)) ==
383 pending_infobar_requests_.end()); 380 pending_infobar_requests_.end());
384 381
382 InfoBarTabHelper* helper = GetInfoBarHelper(render_process_id,
383 render_view_id);
384 if (!helper) {
385 // We won't be able to create any infobars, shortcut and remove any pending
386 // requests.
387 ClearPendingInfoBarRequestsFromTab(render_process_id, render_view_id);
388 return;
389 }
385 pending_infobar_requests_.push_back(PendingInfoBarRequest(render_process_id, 390 pending_infobar_requests_.push_back(PendingInfoBarRequest(render_process_id,
386 render_view_id, bridge_id, requesting_frame, embedder, callback)); 391 render_view_id, bridge_id, requesting_frame, embedder, callback));
387 ShowQueuedInfoBar(render_process_id, render_view_id); 392 if (!AlreadyShowingInfoBar(render_process_id, render_view_id))
393 ShowQueuedInfoBar(render_process_id, render_view_id, helper);
388 } 394 }
389 395
390 void GeolocationInfoBarQueueController::CancelInfoBarRequest( 396 void GeolocationInfoBarQueueController::CancelInfoBarRequest(
391 int render_process_id, 397 int render_process_id,
392 int render_view_id, 398 int render_view_id,
393 int bridge_id) { 399 int bridge_id) {
394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 400 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
395 401
396 PendingInfoBarRequests::iterator i = std::find_if( 402 PendingInfoBarRequests::iterator i = std::find_if(
397 pending_infobar_requests_.begin(), pending_infobar_requests_.end(), 403 pending_infobar_requests_.begin(), pending_infobar_requests_.end(),
398 RequestEquals(render_process_id, render_view_id, bridge_id)); 404 RequestEquals(render_process_id, render_view_id, bridge_id));
399 // TODO(pkasting): Can this conditional become a DCHECK()? 405 // TODO(pkasting): Can this conditional become a DCHECK()?
400 if (i != pending_infobar_requests_.end()) 406 if (i == pending_infobar_requests_.end())
401 CancelInfoBarRequestInternal(i); 407 return;
402 } 408 InfoBarDelegate* delegate = i->infobar_delegate;
403 409 if (!delegate) {
404 void GeolocationInfoBarQueueController::OnInfoBarClosed(int render_process_id,
405 int render_view_id,
406 int bridge_id) {
407 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
408
409 PendingInfoBarRequests::iterator i = std::find_if(
410 pending_infobar_requests_.begin(), pending_infobar_requests_.end(),
411 RequestEquals(render_process_id, render_view_id, bridge_id));
412 if (i != pending_infobar_requests_.end())
413 pending_infobar_requests_.erase(i); 410 pending_infobar_requests_.erase(i);
414 411 return;
415 ShowQueuedInfoBar(render_process_id, render_view_id); 412 }
413 InfoBarTabHelper* helper = GetInfoBarHelper(render_process_id,
414 render_view_id);
415 helper->RemoveInfoBar(delegate);
416 } 416 }
417 417
418 void GeolocationInfoBarQueueController::OnPermissionSet( 418 void GeolocationInfoBarQueueController::OnPermissionSet(
419 int render_process_id, 419 int render_process_id,
420 int render_view_id, 420 int render_view_id,
421 int bridge_id, 421 int bridge_id,
422 const GURL& requesting_frame, 422 const GURL& requesting_frame,
423 const GURL& embedder, 423 const GURL& embedder,
424 bool allowed) { 424 bool allowed) {
425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
426 426
427 ContentSetting content_setting = 427 ContentSetting content_setting =
428 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 428 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
429 profile_->GetHostContentSettingsMap()->SetContentSetting( 429 profile_->GetHostContentSettingsMap()->SetContentSetting(
430 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), 430 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()),
431 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), 431 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()),
432 CONTENT_SETTINGS_TYPE_GEOLOCATION, 432 CONTENT_SETTINGS_TYPE_GEOLOCATION,
433 std::string(), 433 std::string(),
434 content_setting); 434 content_setting);
435 435
436 // Cancel this request first, then notify listeners. TODO(pkasting): Why
437 // is this order important?
438 PendingInfoBarRequests requests_to_notify, infobars_to_remove;
bulach 2012/03/23 11:01:46 nit: one per line..
John Knottenbelt 2012/03/23 11:45:50 Done.
436 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 439 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
437 i != pending_infobar_requests_.end(); ) { 440 i != pending_infobar_requests_.end(); ) {
438 if (i->IsForPair(requesting_frame, embedder)) { 441 if (i->IsForPair(requesting_frame, embedder)) {
439 // Cancel this request first, then notify listeners. TODO(pkasting): Why 442 requests_to_notify.push_back(*i);
440 // is this order important? 443 if (i->Equals(render_process_id, render_view_id, bridge_id)) {
441 // NOTE: If the pending request had an infobar, TabContents will close it 444 // Don't erase or call RemoveInfoBar() with the delegate that's
442 // either synchronously or asynchronously, which will then pump the queue 445 // currently calling us. That delegate is in either Accept() or
443 // via OnInfoBarClosed(). 446 // Cancel(), so its owning InfoBar will call RemoveInfoBar() later on in
444 PendingInfoBarRequest copied_request = *i; 447 // this callstack anyway; and if we do it here, and it causes the
445 // Don't let CancelInfoBarRequestInternal() call RemoveInfoBar() with the 448 // delegate to be deleted, our GURL& args will point to garbage and we
446 // delegate that's currently calling us. That delegate is in either 449 // may also cause other problems during stack unwinding.
bulach 2012/03/23 11:01:46 nit: not sure if this would clarify, but how about
John Knottenbelt 2012/03/23 11:45:50 Done.
447 // Accept() or Cancel(), so its owning InfoBar will call RemoveInfoBar() 450 ++i;
448 // later on in this callstack anyway; and if we do it here, and it causes 451 } else if (i->infobar_delegate) {
449 // the delegate to be deleted, our GURL& args will point to garbage and we 452 // We need to ask the infobar helper to remove it, but not while in this
450 // may also cause other problems during stack unwinding. 453 // loop because doing so modifies pending_infobar_requests_.
bulach 2012/03/23 11:01:46 and here: // This InfoBar is for the same frame/
John Knottenbelt 2012/03/23 11:45:50 Done.
451 if (i->Equals(render_process_id, render_view_id, bridge_id)) 454 infobars_to_remove.push_back(*i);
452 i->infobar_delegate = NULL; 455 ++i;
453 i = CancelInfoBarRequestInternal(i); 456 } else {
bulach 2012/03/23 11:01:46 // We haven't created an InfoBar yet, just remove
John Knottenbelt 2012/03/23 11:45:50 Done.
454 457 i = pending_infobar_requests_.erase(i);
455 geolocation_permission_context_->NotifyPermissionSet( 458 }
456 copied_request.render_process_id, copied_request.render_view_id,
457 copied_request.bridge_id, copied_request.requesting_frame,
458 copied_request.callback, allowed);
459 } else { 459 } else {
460 ++i; 460 ++i;
461 } 461 }
462 } 462 }
463
464 // Remove any showing InfoBars.
bulach 2012/03/23 11:01:46 // Remove all InfoBars for the same |requesting_fr
John Knottenbelt 2012/03/23 11:45:50 Done.
465 for (PendingInfoBarRequests::iterator i = infobars_to_remove.begin();
466 i != infobars_to_remove.end(); ++i ) {
467 InfoBarTabHelper* helper = GetInfoBarHelper(i->render_process_id,
468 i->render_view_id);
469 helper->RemoveInfoBar(i->infobar_delegate);
470 }
471
472 // Send out the permission notifications.
473 for (PendingInfoBarRequests::iterator i = requests_to_notify.begin();
474 i != requests_to_notify.end(); ++i ) {
475 geolocation_permission_context_->NotifyPermissionSet(
476 i->render_process_id, i->render_view_id,
477 i->bridge_id, i->requesting_frame,
478 i->callback, allowed);
479 }
463 } 480 }
464 481
465 void GeolocationInfoBarQueueController::Observe( 482 void GeolocationInfoBarQueueController::Observe(
466 int type, const content::NotificationSource& source, 483 int type,
484 const content::NotificationSource& source,
467 const content::NotificationDetails& details) { 485 const content::NotificationDetails& details) {
468 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 486 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
469 source); 487 // We will receive this notification for all infobar closures, so we need to
470 WebContents* web_contents = content::Source<WebContents>(source).ptr(); 488 // check whether this is the geolocation infobar we're tracking.
489 InfoBarDelegate* delegate =
490 content::Details<InfoBarRemovedDetails>(details)->first;
471 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 491 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
472 i != pending_infobar_requests_.end();) { 492 i != pending_infobar_requests_.end(); ++i) {
473 if (i->infobar_delegate == NULL && 493 GeolocationConfirmInfoBarDelegate* confirm_delegate = i->infobar_delegate;
474 web_contents == tab_util::GetWebContentsByID(i->render_process_id, 494 if (confirm_delegate == delegate) {
475 i->render_view_id)) { 495 InfoBarTabHelper* helper =
476 i = pending_infobar_requests_.erase(i); 496 content::Source<InfoBarTabHelper>(source).ptr();
477 } else { 497 registrar_.Remove(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
478 ++i; 498 source);
499 int render_process_id = i->render_process_id;
500 int render_view_id = i->render_view_id;
501 pending_infobar_requests_.erase(i);
502 ShowQueuedInfoBar(render_process_id, render_view_id, helper);
503 return;
479 } 504 }
480 } 505 }
481 } 506 }
482 507
483 void GeolocationInfoBarQueueController::ShowQueuedInfoBar(int render_process_id, 508 void GeolocationInfoBarQueueController::ClearPendingInfoBarRequestsFromTab(
484 int render_view_id) { 509 int render_process_id,
485 WebContents* tab_contents = 510 int render_view_id) {
486 tab_util::GetWebContentsByID(render_process_id, render_view_id);
487 TabContentsWrapper* wrapper = NULL;
488 if (tab_contents)
489 wrapper = TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
490 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 511 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
491 i != pending_infobar_requests_.end(); ) { 512 i != pending_infobar_requests_.end(); ) {
492 if (i->IsForTab(render_process_id, render_view_id)) { 513 if (i->IsForTab(render_process_id, render_view_id))
493 if (!wrapper) { 514 i = pending_infobar_requests_.erase(i);
494 i = pending_infobar_requests_.erase(i); 515 else
495 continue; 516 ++i;
496 }
497
498 if (!i->infobar_delegate) {
499 if (!registrar_.IsRegistered(
500 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
501 content::Source<WebContents>(tab_contents))) {
502 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
503 content::Source<WebContents>(tab_contents));
504 }
505 i->infobar_delegate = new GeolocationConfirmInfoBarDelegate(
506 wrapper->infobar_tab_helper(), this, render_process_id,
507 render_view_id, i->bridge_id, i->requesting_frame,
508 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
509 wrapper->infobar_tab_helper()->AddInfoBar(i->infobar_delegate);
510 }
511 break;
512 }
513 ++i;
514 } 517 }
515 } 518 }
516 519
517 GeolocationInfoBarQueueController::PendingInfoBarRequests::iterator 520 InfoBarTabHelper* GeolocationInfoBarQueueController::GetInfoBarHelper(
518 GeolocationInfoBarQueueController::CancelInfoBarRequestInternal( 521 int render_process_id,
519 PendingInfoBarRequests::iterator i) { 522 int render_view_id) {
520 InfoBarDelegate* delegate = i->infobar_delegate; 523 WebContents* tab_contents =
521 if (!delegate) 524 tab_util::GetWebContentsByID(render_process_id, render_view_id);
522 return pending_infobar_requests_.erase(i); 525 if (!tab_contents)
523 526 return NULL;
524 WebContents* web_contents =
525 tab_util::GetWebContentsByID(i->render_process_id, i->render_view_id);
526 if (!web_contents)
527 return pending_infobar_requests_.erase(i);
528
529 // WebContents will destroy the InfoBar, which will remove from our vector
530 // asynchronously.
531 TabContentsWrapper* wrapper = 527 TabContentsWrapper* wrapper =
532 TabContentsWrapper::GetCurrentWrapperForContents(web_contents); 528 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
533 wrapper->infobar_tab_helper()->RemoveInfoBar(i->infobar_delegate); 529 if (!wrapper)
534 return ++i; 530 return NULL;
531 return wrapper->infobar_tab_helper();
535 } 532 }
536 533
534 bool GeolocationInfoBarQueueController::AlreadyShowingInfoBar(
535 int render_process_id,
536 int render_view_id) {
537 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
538 i != pending_infobar_requests_.end(); ++i) {
539 if (i->IsForTab(render_process_id, render_view_id) && i->infobar_delegate)
540 return true;
541 }
542 return false;
543 }
544
545 void GeolocationInfoBarQueueController::ShowQueuedInfoBar(
546 int render_process_id,
547 int render_view_id,
548 InfoBarTabHelper* helper) {
549 DCHECK(helper);
550 DCHECK(!AlreadyShowingInfoBar(render_process_id, render_view_id));
551 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
552 i != pending_infobar_requests_.end(); ++i) {
553 if (i->IsForTab(render_process_id, render_view_id) &&
554 !i->infobar_delegate) {
555 DCHECK(!registrar_.IsRegistered(
556 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
557 content::Source<InfoBarTabHelper>(helper)));
558 registrar_.Add(
559 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
560 content::Source<InfoBarTabHelper>(helper));
561 i->infobar_delegate = new GeolocationConfirmInfoBarDelegate(
562 helper, this, render_process_id,
563 render_view_id, i->bridge_id, i->requesting_frame,
564 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
565 helper->AddInfoBar(i->infobar_delegate);
566 break;
567 }
568 }
569 }
537 570
538 // GeolocationPermissionContext ----------------------------------------------- 571 // GeolocationPermissionContext -----------------------------------------------
539 572
540 ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext( 573 ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext(
541 Profile* profile) 574 Profile* profile)
542 : profile_(profile), 575 : profile_(profile),
543 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_( 576 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_(
544 new GeolocationInfoBarQueueController(this, profile))) { 577 new GeolocationInfoBarQueueController(this, profile))) {
545 } 578 }
546 579
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 BrowserThread::UI, FROM_HERE, 696 BrowserThread::UI, FROM_HERE,
664 base::Bind( 697 base::Bind(
665 &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest, 698 &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest,
666 this, render_process_id, render_view_id, bridge_id)); 699 this, render_process_id, render_view_id, bridge_id));
667 return; 700 return;
668 } 701 }
669 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 702 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
670 geolocation_infobar_queue_controller_->CancelInfoBarRequest(render_process_id, 703 geolocation_infobar_queue_controller_->CancelInfoBarRequest(render_process_id,
671 render_view_id, bridge_id); 704 render_view_id, bridge_id);
672 } 705 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698