| 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 |