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

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: Refactor to make logic clearer. 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 // Cancels an InfoBar request and returns the next iterator position.
112 PendingInfoBarRequests::iterator CancelInfoBarRequestInternal( 110 PendingInfoBarRequests::iterator CancelInfoBarRequestInternal(
113 PendingInfoBarRequests::iterator i); 111 PendingInfoBarRequests::iterator i,
112 bool remove_showing_infobar);
113
114 // Removes any pending requests for a given dead tab.
115 void ClearInfoBarRequestsFromTab(int render_process_id, int render_view_id);
bulach 2012/03/22 17:01:46 nit: maybe ClearPendingInfoBarRequestsFromTab, to
John Knottenbelt 2012/03/22 18:09:02 Done.
116
117 InfoBarTabHelper* GetInfoBarHelper(int render_process_id, int render_view_id);
118 bool AlreadyShowingQueuedInfoBar(int render_process_id, int render_view_id);
bulach 2012/03/22 17:01:46 nit: and in this case the could probably remove th
John Knottenbelt 2012/03/22 18:09:02 Done.
114 119
115 content::NotificationRegistrar registrar_; 120 content::NotificationRegistrar registrar_;
116 121
117 ChromeGeolocationPermissionContext* const geolocation_permission_context_; 122 ChromeGeolocationPermissionContext* const geolocation_permission_context_;
118 Profile* const profile_; 123 Profile* const profile_;
119 PendingInfoBarRequests pending_infobar_requests_; 124 PendingInfoBarRequests pending_infobar_requests_;
120 }; 125 };
121 126
122 127
123 // GeolocationConfirmInfoBarDelegate ------------------------------------------ 128 // GeolocationConfirmInfoBarDelegate ------------------------------------------
124 129
125 namespace { 130 namespace {
126 131
127 class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate { 132 class GeolocationConfirmInfoBarDelegate : public ConfirmInfoBarDelegate {
128 public: 133 public:
129 GeolocationConfirmInfoBarDelegate( 134 GeolocationConfirmInfoBarDelegate(
130 InfoBarTabHelper* infobar_helper, 135 InfoBarTabHelper* infobar_helper,
131 GeolocationInfoBarQueueController* controller, 136 GeolocationInfoBarQueueController* controller,
132 int render_process_id, 137 int render_process_id,
133 int render_view_id, 138 int render_view_id,
134 int bridge_id, 139 int bridge_id,
135 const GURL& requesting_frame_url, 140 const GURL& requesting_frame_url,
136 const std::string& display_languages); 141 const std::string& display_languages);
137 142
143 int render_process_id() const { return render_process_id_; }
144 int render_view_id() const { return render_view_id_; }
145
138 private: 146 private:
139 virtual ~GeolocationConfirmInfoBarDelegate();
140 147
141 // ConfirmInfoBarDelegate: 148 // ConfirmInfoBarDelegate:
142 virtual bool ShouldExpire( 149 virtual bool ShouldExpire(
143 const content::LoadCommittedDetails& details) const OVERRIDE; 150 const content::LoadCommittedDetails& details) const OVERRIDE;
144 virtual gfx::Image* GetIcon() const OVERRIDE; 151 virtual gfx::Image* GetIcon() const OVERRIDE;
145 virtual Type GetInfoBarType() const OVERRIDE; 152 virtual Type GetInfoBarType() const OVERRIDE;
146 virtual string16 GetMessageText() const OVERRIDE; 153 virtual string16 GetMessageText() const OVERRIDE;
147 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE; 154 virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
148 virtual bool Accept() OVERRIDE; 155 virtual bool Accept() OVERRIDE;
149 virtual bool Cancel() OVERRIDE; 156 virtual bool Cancel() OVERRIDE;
(...skipping 28 matching lines...) Expand all
178 render_view_id_(render_view_id), 185 render_view_id_(render_view_id),
179 bridge_id_(bridge_id), 186 bridge_id_(bridge_id),
180 requesting_frame_url_(requesting_frame_url), 187 requesting_frame_url_(requesting_frame_url),
181 display_languages_(display_languages) { 188 display_languages_(display_languages) {
182 const NavigationEntry* committed_entry = 189 const NavigationEntry* committed_entry =
183 infobar_helper->web_contents()->GetController().GetLastCommittedEntry(); 190 infobar_helper->web_contents()->GetController().GetLastCommittedEntry();
184 committed_contents_unique_id_ = committed_entry ? 191 committed_contents_unique_id_ = committed_entry ?
185 committed_entry->GetUniqueID() : 0; 192 committed_entry->GetUniqueID() : 0;
186 } 193 }
187 194
188 GeolocationConfirmInfoBarDelegate::~GeolocationConfirmInfoBarDelegate() {
189 controller_->OnInfoBarClosed(render_process_id_, render_view_id_,
190 bridge_id_);
191 }
192
193 bool GeolocationConfirmInfoBarDelegate::ShouldExpire( 195 bool GeolocationConfirmInfoBarDelegate::ShouldExpire(
194 const content::LoadCommittedDetails& details) const { 196 const content::LoadCommittedDetails& details) const {
195 if (details.did_replace_entry || !details.is_navigation_to_different_page()) 197 if (details.did_replace_entry || !details.is_navigation_to_different_page())
196 return false; 198 return false;
197 return committed_contents_unique_id_ != details.entry->GetUniqueID() || 199 return committed_contents_unique_id_ != details.entry->GetUniqueID() ||
198 content::PageTransitionStripQualifier( 200 content::PageTransitionStripQualifier(
199 details.entry->GetTransitionType()) == 201 details.entry->GetTransitionType()) ==
200 content::PAGE_TRANSITION_RELOAD; 202 content::PAGE_TRANSITION_RELOAD;
201 } 203 }
202 204
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 bool Equals(int p_render_process_id, 278 bool Equals(int p_render_process_id,
277 int p_render_view_id, 279 int p_render_view_id,
278 int p_bridge_id) const; 280 int p_bridge_id) const;
279 281
280 int render_process_id; 282 int render_process_id;
281 int render_view_id; 283 int render_view_id;
282 int bridge_id; 284 int bridge_id;
283 GURL requesting_frame; 285 GURL requesting_frame;
284 GURL embedder; 286 GURL embedder;
285 base::Callback<void(bool)> callback; 287 base::Callback<void(bool)> callback;
286 InfoBarDelegate* infobar_delegate; 288 GeolocationConfirmInfoBarDelegate* infobar_delegate;
289 bool notified;
bulach 2012/03/22 17:01:46 unused?
John Knottenbelt 2012/03/22 18:09:02 Removed. On 2012/03/22 17:01:46, bulach wrote:
287 }; 290 };
288 291
289 GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest( 292 GeolocationInfoBarQueueController::PendingInfoBarRequest::PendingInfoBarRequest(
290 int render_process_id, 293 int render_process_id,
291 int render_view_id, 294 int render_view_id,
292 int bridge_id, 295 int bridge_id,
293 const GURL& requesting_frame, 296 const GURL& requesting_frame,
294 const GURL& embedder, 297 const GURL& embedder,
295 base::Callback<void(bool)> callback) 298 base::Callback<void(bool)> callback)
296 : render_process_id(render_process_id), 299 : render_process_id(render_process_id),
297 render_view_id(render_view_id), 300 render_view_id(render_view_id),
298 bridge_id(bridge_id), 301 bridge_id(bridge_id),
299 requesting_frame(requesting_frame), 302 requesting_frame(requesting_frame),
300 embedder(embedder), 303 embedder(embedder),
301 callback(callback), 304 callback(callback),
302 infobar_delegate(NULL) { 305 infobar_delegate(NULL),
306 notified(false) {
303 } 307 }
304 308
305 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForTab( 309 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForTab(
306 int p_render_process_id, 310 int p_render_process_id,
307 int p_render_view_id) const { 311 int p_render_view_id) const {
308 return (render_process_id == p_render_process_id) && 312 return (render_process_id == p_render_process_id) &&
309 (render_view_id == p_render_view_id); 313 (render_view_id == p_render_view_id);
310 } 314 }
311 315
312 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForPair( 316 bool GeolocationInfoBarQueueController::PendingInfoBarRequest::IsForPair(
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 : render_process_id_(render_process_id), 351 : render_process_id_(render_process_id),
348 render_view_id_(render_view_id), 352 render_view_id_(render_view_id),
349 bridge_id_(bridge_id) { 353 bridge_id_(bridge_id) {
350 } 354 }
351 355
352 bool GeolocationInfoBarQueueController::RequestEquals::operator()( 356 bool GeolocationInfoBarQueueController::RequestEquals::operator()(
353 const PendingInfoBarRequest& request) const { 357 const PendingInfoBarRequest& request) const {
354 return request.Equals(render_process_id_, render_view_id_, bridge_id_); 358 return request.Equals(render_process_id_, render_view_id_, bridge_id_);
355 } 359 }
356 360
357
358 // GeolocationInfoBarQueueController ------------------------------------------ 361 // GeolocationInfoBarQueueController ------------------------------------------
359 362
360 GeolocationInfoBarQueueController::GeolocationInfoBarQueueController( 363 GeolocationInfoBarQueueController::GeolocationInfoBarQueueController(
361 ChromeGeolocationPermissionContext* geolocation_permission_context, 364 ChromeGeolocationPermissionContext* geolocation_permission_context,
362 Profile* profile) 365 Profile* profile)
363 : geolocation_permission_context_(geolocation_permission_context), 366 : geolocation_permission_context_(geolocation_permission_context),
364 profile_(profile) { 367 profile_(profile) {
365 } 368 }
366 369
367 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() { 370 GeolocationInfoBarQueueController::~GeolocationInfoBarQueueController() {
368 } 371 }
369 372
370 void GeolocationInfoBarQueueController::CreateInfoBarRequest( 373 void GeolocationInfoBarQueueController::CreateInfoBarRequest(
371 int render_process_id, 374 int render_process_id,
372 int render_view_id, 375 int render_view_id,
373 int bridge_id, 376 int bridge_id,
374 const GURL& requesting_frame, 377 const GURL& requesting_frame,
375 const GURL& embedder, 378 const GURL& embedder,
376 base::Callback<void(bool)> callback) { 379 base::Callback<void(bool)> callback) {
377 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 380 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
378 381
379 // We shouldn't get duplicate requests. 382 // We shouldn't get duplicate requests.
380 DCHECK(std::find_if(pending_infobar_requests_.begin(), 383 DCHECK(std::find_if(pending_infobar_requests_.begin(),
381 pending_infobar_requests_.end(), 384 pending_infobar_requests_.end(),
382 RequestEquals(render_process_id, render_view_id, bridge_id)) == 385 RequestEquals(render_process_id, render_view_id, bridge_id)) ==
383 pending_infobar_requests_.end()); 386 pending_infobar_requests_.end());
384 387
385 pending_infobar_requests_.push_back(PendingInfoBarRequest(render_process_id, 388 pending_infobar_requests_.push_back(PendingInfoBarRequest(render_process_id,
386 render_view_id, bridge_id, requesting_frame, embedder, callback)); 389 render_view_id, bridge_id, requesting_frame, embedder, callback));
387 ShowQueuedInfoBar(render_process_id, render_view_id); 390
391 InfoBarTabHelper* helper = GetInfoBarHelper(render_process_id,
392 render_view_id);
393 if (!helper) {
bulach 2012/03/22 17:01:46 maybe move 388 after this and add a comment saying
John Knottenbelt 2012/03/22 18:09:02 Done.
394 ClearInfoBarRequestsFromTab(render_process_id, render_view_id);
395 return;
396 }
397 if (!AlreadyShowingQueuedInfoBar(render_process_id, render_view_id))
398 ShowQueuedInfoBar(render_process_id, render_view_id, helper);
388 } 399 }
389 400
390 void GeolocationInfoBarQueueController::CancelInfoBarRequest( 401 void GeolocationInfoBarQueueController::CancelInfoBarRequest(
391 int render_process_id, 402 int render_process_id,
392 int render_view_id, 403 int render_view_id,
393 int bridge_id) { 404 int bridge_id) {
394 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 405 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
395 406
396 PendingInfoBarRequests::iterator i = std::find_if( 407 PendingInfoBarRequests::iterator i = std::find_if(
397 pending_infobar_requests_.begin(), pending_infobar_requests_.end(), 408 pending_infobar_requests_.begin(), pending_infobar_requests_.end(),
398 RequestEquals(render_process_id, render_view_id, bridge_id)); 409 RequestEquals(render_process_id, render_view_id, bridge_id));
399 // TODO(pkasting): Can this conditional become a DCHECK()? 410 // TODO(pkasting): Can this conditional become a DCHECK()?
400 if (i != pending_infobar_requests_.end()) 411 if (i != pending_infobar_requests_.end())
401 CancelInfoBarRequestInternal(i); 412 CancelInfoBarRequestInternal(i, true);
402 }
403
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);
414
415 ShowQueuedInfoBar(render_process_id, render_view_id);
416 } 413 }
417 414
418 void GeolocationInfoBarQueueController::OnPermissionSet( 415 void GeolocationInfoBarQueueController::OnPermissionSet(
419 int render_process_id, 416 int render_process_id,
420 int render_view_id, 417 int render_view_id,
421 int bridge_id, 418 int bridge_id,
422 const GURL& requesting_frame, 419 const GURL& requesting_frame,
423 const GURL& embedder, 420 const GURL& embedder,
424 bool allowed) { 421 bool allowed) {
425 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 422 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
426 423
427 ContentSetting content_setting = 424 ContentSetting content_setting =
428 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK; 425 allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
429 profile_->GetHostContentSettingsMap()->SetContentSetting( 426 profile_->GetHostContentSettingsMap()->SetContentSetting(
430 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()), 427 ContentSettingsPattern::FromURLNoWildcard(requesting_frame.GetOrigin()),
431 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()), 428 ContentSettingsPattern::FromURLNoWildcard(embedder.GetOrigin()),
432 CONTENT_SETTINGS_TYPE_GEOLOCATION, 429 CONTENT_SETTINGS_TYPE_GEOLOCATION,
433 std::string(), 430 std::string(),
434 content_setting); 431 content_setting);
435 432
433 // Cancel this request first, then notify listeners. TODO(pkasting): Why
434 // is this order important?
435 PendingInfoBarRequests requests_to_notify;
436 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 436 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
437 i != pending_infobar_requests_.end(); ) { 437 i != pending_infobar_requests_.end(); ) {
438 if (i->IsForPair(requesting_frame, embedder)) { 438 if (i->IsForPair(requesting_frame, embedder)) {
439 // Cancel this request first, then notify listeners. TODO(pkasting): Why 439 requests_to_notify.push_back(*i);
440 // is this order important?
441 // NOTE: If the pending request had an infobar, TabContents will close it
442 // either synchronously or asynchronously, which will then pump the queue
443 // via OnInfoBarClosed().
444 PendingInfoBarRequest copied_request = *i;
445 // Don't let CancelInfoBarRequestInternal() call RemoveInfoBar() with the 440 // Don't let CancelInfoBarRequestInternal() call RemoveInfoBar() with the
446 // delegate that's currently calling us. That delegate is in either 441 // delegate that's currently calling us. That delegate is in either
447 // Accept() or Cancel(), so its owning InfoBar will call RemoveInfoBar() 442 // Accept() or Cancel(), so its owning InfoBar will call RemoveInfoBar()
448 // later on in this callstack anyway; and if we do it here, and it causes 443 // later on in this callstack anyway; and if we do it here, and it causes
449 // the delegate to be deleted, our GURL& args will point to garbage and we 444 // the delegate to be deleted, our GURL& args will point to garbage and we
450 // may also cause other problems during stack unwinding. 445 // may also cause other problems during stack unwinding.
451 if (i->Equals(render_process_id, render_view_id, bridge_id)) 446 if (!i->Equals(render_process_id, render_view_id, bridge_id)) {
452 i->infobar_delegate = NULL; 447 i = CancelInfoBarRequestInternal(i, true);
453 i = CancelInfoBarRequestInternal(i); 448 continue;
449 }
450 }
451 ++i;
452 }
454 453
455 geolocation_permission_context_->NotifyPermissionSet( 454 for (PendingInfoBarRequests::iterator i = requests_to_notify.begin();
456 copied_request.render_process_id, copied_request.render_view_id, 455 i != requests_to_notify.end(); ++i ) {
457 copied_request.bridge_id, copied_request.requesting_frame, 456 geolocation_permission_context_->NotifyPermissionSet(
458 copied_request.callback, allowed); 457 i->render_process_id, i->render_view_id,
459 } else { 458 i->bridge_id, i->requesting_frame,
460 ++i; 459 i->callback, allowed);
460 }
461 }
462
463 void GeolocationInfoBarQueueController::Observe(
464 int type,
465 const content::NotificationSource& source,
466 const content::NotificationDetails& details) {
467 DCHECK_EQ(chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED, type);
468 // We will receive this notification for all infobar closures, so we need to
469 // check whether this is the geolocation infobar we're tracking.
470 InfoBarDelegate* delegate =
471 content::Details<InfoBarRemovedDetails>(details)->first;
472 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
473 i != pending_infobar_requests_.end(); ++i) {
474 GeolocationConfirmInfoBarDelegate* confirm_delegate = i->infobar_delegate;
475 if (confirm_delegate == delegate) {
476 // We're being called from InfoBarTabHelper, so pass in false to
477 // stop CancelInfoBarRequestInternal calling helper->RemoveInfoBar.
478 CancelInfoBarRequestInternal(i, false);
bulach 2012/03/22 17:01:46 see below, I think it'd be nicer to ShowQueuedInfo
479 return;
461 } 480 }
462 } 481 }
463 } 482 }
464 483
465 void GeolocationInfoBarQueueController::Observe( 484 void GeolocationInfoBarQueueController::ClearInfoBarRequestsFromTab(
466 int type, const content::NotificationSource& source, 485 int render_process_id,
467 const content::NotificationDetails& details) { 486 int render_view_id) {
468 registrar_.Remove(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
469 source);
470 WebContents* web_contents = content::Source<WebContents>(source).ptr();
471 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 487 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
472 i != pending_infobar_requests_.end();) { 488 i != pending_infobar_requests_.end(); ) {
473 if (i->infobar_delegate == NULL && 489 if (i->IsForTab(render_process_id, render_view_id))
474 web_contents == tab_util::GetWebContentsByID(i->render_process_id,
475 i->render_view_id)) {
476 i = pending_infobar_requests_.erase(i); 490 i = pending_infobar_requests_.erase(i);
477 } else { 491 else
478 ++i; 492 ++i;
479 }
480 } 493 }
481 } 494 }
482 495
483 void GeolocationInfoBarQueueController::ShowQueuedInfoBar(int render_process_id, 496 InfoBarTabHelper* GeolocationInfoBarQueueController::GetInfoBarHelper(
484 int render_view_id) { 497 int render_process_id,
498 int render_view_id) {
485 WebContents* tab_contents = 499 WebContents* tab_contents =
486 tab_util::GetWebContentsByID(render_process_id, render_view_id); 500 tab_util::GetWebContentsByID(render_process_id, render_view_id);
487 TabContentsWrapper* wrapper = NULL; 501 if (!tab_contents)
488 if (tab_contents) 502 return NULL;
489 wrapper = TabContentsWrapper::GetCurrentWrapperForContents(tab_contents); 503 TabContentsWrapper* wrapper =
504 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
505 if (!wrapper)
506 return NULL;
507 return wrapper->infobar_tab_helper();
508 }
509
510 bool GeolocationInfoBarQueueController::AlreadyShowingQueuedInfoBar(
511 int render_process_id,
512 int render_view_id) {
490 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); 513 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
491 i != pending_infobar_requests_.end(); ) { 514 i != pending_infobar_requests_.end(); ++i) {
492 if (i->IsForTab(render_process_id, render_view_id)) { 515 if (i->IsForTab(render_process_id, render_view_id) && i->infobar_delegate)
493 if (!wrapper) { 516 return true;
494 i = pending_infobar_requests_.erase(i); 517 }
495 continue; 518 return false;
496 } 519 }
497 520
498 if (!i->infobar_delegate) { 521 void GeolocationInfoBarQueueController::ShowQueuedInfoBar(
499 if (!registrar_.IsRegistered( 522 int render_process_id,
500 this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 523 int render_view_id,
501 content::Source<WebContents>(tab_contents))) { 524 InfoBarTabHelper* helper) {
502 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED, 525 DCHECK(helper);
503 content::Source<WebContents>(tab_contents)); 526 DCHECK(!AlreadyShowingQueuedInfoBar(render_process_id, render_view_id));
504 } 527 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin();
528 i != pending_infobar_requests_.end(); ++i) {
529 if (i->IsForTab(render_process_id, render_view_id) &&
530 !i->infobar_delegate) {
531 DCHECK(!registrar_.IsRegistered(
532 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
533 content::Source<InfoBarTabHelper>(helper)));
534 registrar_.Add(
535 this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
536 content::Source<InfoBarTabHelper>(helper));
505 i->infobar_delegate = new GeolocationConfirmInfoBarDelegate( 537 i->infobar_delegate = new GeolocationConfirmInfoBarDelegate(
506 wrapper->infobar_tab_helper(), this, render_process_id, 538 helper, this, render_process_id,
507 render_view_id, i->bridge_id, i->requesting_frame, 539 render_view_id, i->bridge_id, i->requesting_frame,
508 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)); 540 profile_->GetPrefs()->GetString(prefs::kAcceptLanguages));
509 wrapper->infobar_tab_helper()->AddInfoBar(i->infobar_delegate); 541 helper->AddInfoBar(i->infobar_delegate);
510 } 542 break;
511 break;
512 } 543 }
513 ++i;
514 } 544 }
515 } 545 }
516 546
517 GeolocationInfoBarQueueController::PendingInfoBarRequests::iterator 547 GeolocationInfoBarQueueController::PendingInfoBarRequests::iterator
518 GeolocationInfoBarQueueController::CancelInfoBarRequestInternal( 548 GeolocationInfoBarQueueController::CancelInfoBarRequestInternal(
519 PendingInfoBarRequests::iterator i) { 549 PendingInfoBarRequests::iterator i,
550 bool remove_showing_infobar) {
520 InfoBarDelegate* delegate = i->infobar_delegate; 551 InfoBarDelegate* delegate = i->infobar_delegate;
521 if (!delegate) 552 if (!delegate)
522 return pending_infobar_requests_.erase(i); 553 return pending_infobar_requests_.erase(i);
523 554 InfoBarTabHelper* helper = GetInfoBarHelper(i->render_process_id,
524 WebContents* web_contents = 555 i->render_view_id);
525 tab_util::GetWebContentsByID(i->render_process_id, i->render_view_id); 556 if (!helper)
526 if (!web_contents)
527 return pending_infobar_requests_.erase(i); 557 return pending_infobar_requests_.erase(i);
528 558 registrar_.Remove(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
529 // WebContents will destroy the InfoBar, which will remove from our vector 559 content::Source<InfoBarTabHelper>(helper));
530 // asynchronously. 560 if (remove_showing_infobar)
531 TabContentsWrapper* wrapper = 561 helper->RemoveInfoBar(delegate);
532 TabContentsWrapper::GetCurrentWrapperForContents(web_contents); 562 int render_process_id = i->render_process_id;
533 wrapper->infobar_tab_helper()->RemoveInfoBar(i->infobar_delegate); 563 int render_view_id = i->render_view_id;
534 return ++i; 564 PendingInfoBarRequests::iterator next = pending_infobar_requests_.erase(i);
565 ShowQueuedInfoBar(render_process_id, render_view_id, helper);
bulach 2012/03/22 17:01:46 hmm.. I'm not sure we want to create the infobar h
566 return next;
535 } 567 }
536 568
537
538 // GeolocationPermissionContext ----------------------------------------------- 569 // GeolocationPermissionContext -----------------------------------------------
539 570
540 ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext( 571 ChromeGeolocationPermissionContext::ChromeGeolocationPermissionContext(
541 Profile* profile) 572 Profile* profile)
542 : profile_(profile), 573 : profile_(profile),
543 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_( 574 ALLOW_THIS_IN_INITIALIZER_LIST(geolocation_infobar_queue_controller_(
544 new GeolocationInfoBarQueueController(this, profile))) { 575 new GeolocationInfoBarQueueController(this, profile))) {
545 } 576 }
546 577
547 ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() { 578 ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 BrowserThread::UI, FROM_HERE, 694 BrowserThread::UI, FROM_HERE,
664 base::Bind( 695 base::Bind(
665 &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest, 696 &ChromeGeolocationPermissionContext::CancelPendingInfoBarRequest,
666 this, render_process_id, render_view_id, bridge_id)); 697 this, render_process_id, render_view_id, bridge_id));
667 return; 698 return;
668 } 699 }
669 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 700 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
670 geolocation_infobar_queue_controller_->CancelInfoBarRequest(render_process_id, 701 geolocation_infobar_queue_controller_->CancelInfoBarRequest(render_process_id,
671 render_view_id, bridge_id); 702 render_view_id, bridge_id);
672 } 703 }
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