OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 } |
OLD | NEW |