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 // Removes any pending requests for a given tab. |
112 PendingInfoBarRequests::iterator CancelInfoBarRequestInternal( | 110 void ClearPendingInfoBarRequestsForTab(int render_process_id, |
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 Loading... |
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 Loading... |
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 Loading... |
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 ClearPendingInfoBarRequestsForTab(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; |
| 439 PendingInfoBarRequests infobars_to_remove; |
436 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); | 440 for (PendingInfoBarRequests::iterator i = pending_infobar_requests_.begin(); |
437 i != pending_infobar_requests_.end(); ) { | 441 i != pending_infobar_requests_.end(); ) { |
438 if (i->IsForPair(requesting_frame, embedder)) { | 442 if (i->IsForPair(requesting_frame, embedder)) { |
439 // Cancel this request first, then notify listeners. TODO(pkasting): Why | 443 requests_to_notify.push_back(*i); |
440 // is this order important? | 444 if (i->Equals(render_process_id, render_view_id, bridge_id)) { |
441 // NOTE: If the pending request had an infobar, TabContents will close it | 445 // The delegate that called us is i, and it's currently in either |
442 // either synchronously or asynchronously, which will then pump the queue | 446 // Accept() or Cancel(). This means that the owning InfoBar will call |
443 // via OnInfoBarClosed(). | 447 // RemoveInfoBar() later on, and that will trigger a notification we're |
444 PendingInfoBarRequest copied_request = *i; | 448 // observing. |
445 // Don't let CancelInfoBarRequestInternal() call RemoveInfoBar() with the | 449 ++i; |
446 // delegate that's currently calling us. That delegate is in either | 450 } else if (i->infobar_delegate) { |
447 // Accept() or Cancel(), so its owning InfoBar will call RemoveInfoBar() | 451 // This InfoBar is for the same frame/embedder pair, but in a different |
448 // later on in this callstack anyway; and if we do it here, and it causes | 452 // tab. We should remove it now that we've got an answer for it. |
449 // the delegate to be deleted, our GURL& args will point to garbage and we | 453 infobars_to_remove.push_back(*i); |
450 // may also cause other problems during stack unwinding. | 454 ++i; |
451 if (i->Equals(render_process_id, render_view_id, bridge_id)) | 455 } else { |
452 i->infobar_delegate = NULL; | 456 // We haven't created an InfoBar yet, just remove the pending request. |
453 i = CancelInfoBarRequestInternal(i); | 457 i = pending_infobar_requests_.erase(i); |
454 | 458 } |
455 geolocation_permission_context_->NotifyPermissionSet( | |
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 all InfoBars for the same |requesting_frame| and |embedder|. |
| 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::ClearPendingInfoBarRequestsForTab( |
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 Loading... |
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 } |
OLD | NEW |