Home | History | Annotate | Download | only in geolocation
      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
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/geolocation/geolocation_permission_context.h"
      6 
      7 #include <set>
      8 #include <string>
      9 #include <utility>
     10 
     11 #include "base/bind.h"
     12 #include "base/containers/hash_tables.h"
     13 #include "base/memory/scoped_vector.h"
     14 #include "base/run_loop.h"
     15 #include "base/synchronization/waitable_event.h"
     16 #include "chrome/browser/chrome_notification_types.h"
     17 #include "chrome/browser/content_settings/host_content_settings_map.h"
     18 #include "chrome/browser/content_settings/permission_request_id.h"
     19 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
     20 #include "chrome/browser/geolocation/geolocation_permission_context_factory.h"
     21 #include "chrome/browser/infobars/infobar_service.h"
     22 #include "chrome/browser/infobars/infobar_service.h"
     23 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
     24 #include "chrome/test/base/testing_profile.h"
     25 #include "components/infobars/core/confirm_infobar_delegate.h"
     26 #include "components/infobars/core/infobar.h"
     27 #include "content/public/browser/browser_thread.h"
     28 #include "content/public/browser/navigation_details.h"
     29 #include "content/public/browser/notification_registrar.h"
     30 #include "content/public/browser/notification_service.h"
     31 #include "content/public/browser/web_contents.h"
     32 #include "content/public/test/mock_render_process_host.h"
     33 #include "content/public/test/test_renderer_host.h"
     34 #include "content/public/test/web_contents_tester.h"
     35 #include "extensions/browser/view_type_utils.h"
     36 #include "testing/gtest/include/gtest/gtest.h"
     37 
     38 #if defined(OS_ANDROID)
     39 #include "base/prefs/pref_service.h"
     40 #include "chrome/browser/android/mock_google_location_settings_helper.h"
     41 #include "chrome/common/pref_names.h"
     42 #endif
     43 
     44 using content::MockRenderProcessHost;
     45 
     46 
     47 // ClosedInfoBarTracker -------------------------------------------------------
     48 
     49 // We need to track which infobars were closed.
     50 class ClosedInfoBarTracker : public content::NotificationObserver {
     51  public:
     52   ClosedInfoBarTracker();
     53   virtual ~ClosedInfoBarTracker();
     54 
     55   // content::NotificationObserver:
     56   virtual void Observe(int type,
     57                        const content::NotificationSource& source,
     58                        const content::NotificationDetails& details) OVERRIDE;
     59 
     60   size_t size() const { return removed_infobars_.size(); }
     61 
     62   bool Contains(infobars::InfoBar* infobar) const;
     63   void Clear();
     64 
     65  private:
     66   FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests, TabDestroyed);
     67   content::NotificationRegistrar registrar_;
     68   std::set<infobars::InfoBar*> removed_infobars_;
     69 };
     70 
     71 ClosedInfoBarTracker::ClosedInfoBarTracker() {
     72   registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
     73                  content::NotificationService::AllSources());
     74 }
     75 
     76 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
     77 }
     78 
     79 void ClosedInfoBarTracker::Observe(
     80     int type,
     81     const content::NotificationSource& source,
     82     const content::NotificationDetails& details) {
     83   DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED);
     84   removed_infobars_.insert(
     85       content::Details<infobars::InfoBar::RemovedDetails>(details)->first);
     86 }
     87 
     88 bool ClosedInfoBarTracker::Contains(infobars::InfoBar* infobar) const {
     89   return removed_infobars_.count(infobar) != 0;
     90 }
     91 
     92 void ClosedInfoBarTracker::Clear() {
     93   removed_infobars_.clear();
     94 }
     95 
     96 
     97 // GeolocationPermissionContextTests ------------------------------------------
     98 
     99 class GeolocationPermissionContextTests
    100     : public ChromeRenderViewHostTestHarness {
    101  protected:
    102   // ChromeRenderViewHostTestHarness:
    103   virtual void SetUp() OVERRIDE;
    104   virtual void TearDown() OVERRIDE;
    105 
    106   PermissionRequestID RequestID(int bridge_id);
    107   PermissionRequestID RequestIDForTab(int tab, int bridge_id);
    108   InfoBarService* infobar_service() {
    109     return InfoBarService::FromWebContents(web_contents());
    110   }
    111   InfoBarService* infobar_service_for_tab(int tab) {
    112     return InfoBarService::FromWebContents(extra_tabs_[tab]);
    113   }
    114 
    115   void RequestGeolocationPermission(content::WebContents* web_contents,
    116                                     const PermissionRequestID& id,
    117                                     const GURL& requesting_frame);
    118   void RequestGeolocationPermission(content::WebContents* web_contents,
    119                                     const PermissionRequestID& id,
    120                                     const GURL& requesting_frame,
    121                                     base::Closure* cancel_callback);
    122   void PermissionResponse(const PermissionRequestID& id,
    123                           bool allowed);
    124   void CheckPermissionMessageSent(int bridge_id, bool allowed);
    125   void CheckPermissionMessageSentForTab(int tab, int bridge_id, bool allowed);
    126   void CheckPermissionMessageSentInternal(MockRenderProcessHost* process,
    127                                           int bridge_id,
    128                                           bool allowed);
    129   void AddNewTab(const GURL& url);
    130   void CheckTabContentsState(const GURL& requesting_frame,
    131                              ContentSetting expected_content_setting);
    132 
    133   scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_;
    134   ClosedInfoBarTracker closed_infobar_tracker_;
    135   ScopedVector<content::WebContents> extra_tabs_;
    136 
    137   // A map between renderer child id and a pair represending the bridge id and
    138   // whether the requested permission was allowed.
    139   base::hash_map<int, std::pair<int, bool> > responses_;
    140 };
    141 
    142 PermissionRequestID GeolocationPermissionContextTests::RequestID(
    143     int bridge_id) {
    144   return PermissionRequestID(
    145       web_contents()->GetRenderProcessHost()->GetID(),
    146       web_contents()->GetRenderViewHost()->GetRoutingID(),
    147       bridge_id,
    148       GURL());
    149 }
    150 
    151 PermissionRequestID GeolocationPermissionContextTests::RequestIDForTab(
    152     int tab,
    153     int bridge_id) {
    154   return PermissionRequestID(
    155       extra_tabs_[tab]->GetRenderProcessHost()->GetID(),
    156       extra_tabs_[tab]->GetRenderViewHost()->GetRoutingID(),
    157       bridge_id,
    158       GURL());
    159 }
    160 
    161 void GeolocationPermissionContextTests::RequestGeolocationPermission(
    162     content::WebContents* web_contents,
    163     const PermissionRequestID& id,
    164     const GURL& requesting_frame) {
    165   RequestGeolocationPermission(web_contents, id, requesting_frame, NULL);
    166 }
    167 
    168 void GeolocationPermissionContextTests::RequestGeolocationPermission(
    169     content::WebContents* web_contents,
    170     const PermissionRequestID& id,
    171     const GURL& requesting_frame,
    172     base::Closure* cancel_callback) {
    173   geolocation_permission_context_->RequestGeolocationPermission(
    174       web_contents, id.bridge_id(), requesting_frame, false,
    175       base::Bind(&GeolocationPermissionContextTests::PermissionResponse,
    176                  base::Unretained(this), id),
    177       cancel_callback);
    178   content::BrowserThread::GetBlockingPool()->FlushForTesting();
    179   base::RunLoop().RunUntilIdle();
    180 }
    181 
    182 void GeolocationPermissionContextTests::PermissionResponse(
    183     const PermissionRequestID& id,
    184     bool allowed) {
    185   responses_[id.render_process_id()] = std::make_pair(id.bridge_id(), allowed);
    186 }
    187 
    188 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
    189     int bridge_id,
    190     bool allowed) {
    191   CheckPermissionMessageSentInternal(process(), bridge_id, allowed);
    192 }
    193 
    194 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
    195     int tab,
    196     int bridge_id,
    197     bool allowed) {
    198   CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost*>(
    199       extra_tabs_[tab]->GetRenderProcessHost()),
    200       bridge_id, allowed);
    201 }
    202 
    203 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
    204     MockRenderProcessHost* process,
    205     int bridge_id,
    206     bool allowed) {
    207   ASSERT_EQ(responses_.count(process->GetID()), 1U);
    208   EXPECT_EQ(bridge_id, responses_[process->GetID()].first);
    209   EXPECT_EQ(allowed, responses_[process->GetID()].second);
    210   responses_.erase(process->GetID());
    211 }
    212 
    213 void GeolocationPermissionContextTests::AddNewTab(const GURL& url) {
    214   content::WebContents* new_tab = content::WebContents::Create(
    215       content::WebContents::CreateParams(profile()));
    216   new_tab->GetController().LoadURL(
    217       url, content::Referrer(), content::PAGE_TRANSITION_TYPED, std::string());
    218   content::RenderViewHostTester::For(new_tab->GetRenderViewHost())->
    219       SendNavigate(extra_tabs_.size() + 1, url);
    220 
    221   // Set up required helpers, and make this be as "tabby" as the code requires.
    222   extensions::SetViewType(new_tab, extensions::VIEW_TYPE_TAB_CONTENTS);
    223   InfoBarService::CreateForWebContents(new_tab);
    224 
    225   extra_tabs_.push_back(new_tab);
    226 }
    227 
    228 void GeolocationPermissionContextTests::CheckTabContentsState(
    229     const GURL& requesting_frame,
    230     ContentSetting expected_content_setting) {
    231   TabSpecificContentSettings* content_settings =
    232       TabSpecificContentSettings::FromWebContents(web_contents());
    233   const ContentSettingsUsagesState::StateMap& state_map =
    234       content_settings->geolocation_usages_state().state_map();
    235   EXPECT_EQ(1U, state_map.count(requesting_frame.GetOrigin()));
    236   EXPECT_EQ(0U, state_map.count(requesting_frame));
    237   ContentSettingsUsagesState::StateMap::const_iterator settings =
    238       state_map.find(requesting_frame.GetOrigin());
    239   ASSERT_FALSE(settings == state_map.end())
    240       << "geolocation state not found " << requesting_frame;
    241   EXPECT_EQ(expected_content_setting, settings->second);
    242 }
    243 
    244 void GeolocationPermissionContextTests::SetUp() {
    245   ChromeRenderViewHostTestHarness::SetUp();
    246 
    247   // Set up required helpers, and make this be as "tabby" as the code requires.
    248   extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS);
    249   InfoBarService::CreateForWebContents(web_contents());
    250   TabSpecificContentSettings::CreateForWebContents(web_contents());
    251 #if defined(OS_ANDROID)
    252   MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
    253 #endif
    254   geolocation_permission_context_ =
    255       GeolocationPermissionContextFactory::GetForProfile(profile());
    256 }
    257 
    258 void GeolocationPermissionContextTests::TearDown() {
    259   extra_tabs_.clear();
    260   ChromeRenderViewHostTestHarness::TearDown();
    261 }
    262 
    263 // Tests ----------------------------------------------------------------------
    264 
    265 TEST_F(GeolocationPermissionContextTests, SinglePermission) {
    266   GURL requesting_frame("http://www.example.com/geolocation");
    267   NavigateAndCommit(requesting_frame);
    268   EXPECT_EQ(0U, infobar_service()->infobar_count());
    269   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    270   ASSERT_EQ(1U, infobar_service()->infobar_count());
    271   infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
    272   ConfirmInfoBarDelegate* infobar_delegate =
    273       infobar->delegate()->AsConfirmInfoBarDelegate();
    274   ASSERT_TRUE(infobar_delegate);
    275   infobar_delegate->Cancel();
    276   infobar_service()->RemoveInfoBar(infobar);
    277   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    278   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar));
    279 }
    280 
    281 #if defined(OS_ANDROID)
    282 TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
    283   GURL requesting_frame("http://www.example.com/geolocation");
    284   NavigateAndCommit(requesting_frame);
    285   MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
    286   EXPECT_EQ(0U, infobar_service()->infobar_count());
    287   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    288   EXPECT_EQ(1U, infobar_service()->infobar_count());
    289   ConfirmInfoBarDelegate* infobar_delegate_0 =
    290       infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
    291   ASSERT_TRUE(infobar_delegate_0);
    292   base::string16 text_0 = infobar_delegate_0->GetButtonLabel(
    293       ConfirmInfoBarDelegate::BUTTON_OK);
    294 
    295   Reload();
    296   MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
    297   EXPECT_EQ(0U, infobar_service()->infobar_count());
    298   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    299   EXPECT_EQ(1U, infobar_service()->infobar_count());
    300   ConfirmInfoBarDelegate* infobar_delegate_1 =
    301       infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
    302   ASSERT_TRUE(infobar_delegate_1);
    303   base::string16 text_1 = infobar_delegate_1->GetButtonLabel(
    304       ConfirmInfoBarDelegate::BUTTON_OK);
    305   EXPECT_NE(text_0, text_1);
    306 
    307   Reload();
    308   MockGoogleLocationSettingsHelper::SetLocationStatus(false, false);
    309   EXPECT_EQ(0U, infobar_service()->infobar_count());
    310   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    311   EXPECT_EQ(0U, infobar_service()->infobar_count());
    312 }
    313 
    314 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) {
    315   GURL requesting_frame("http://www.example.com/geolocation");
    316   NavigateAndCommit(requesting_frame);
    317   MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
    318   EXPECT_EQ(0U, infobar_service()->infobar_count());
    319   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    320   EXPECT_EQ(1U, infobar_service()->infobar_count());
    321   ConfirmInfoBarDelegate* infobar_delegate =
    322       infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
    323   ASSERT_TRUE(infobar_delegate);
    324   infobar_delegate->Accept();
    325   CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
    326   CheckPermissionMessageSent(0, true);
    327 }
    328 
    329 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) {
    330   GURL requesting_frame("http://www.example.com/geolocation");
    331   NavigateAndCommit(requesting_frame);
    332   MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
    333   EXPECT_EQ(0U, infobar_service()->infobar_count());
    334   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    335   EXPECT_EQ(1U, infobar_service()->infobar_count());
    336   ConfirmInfoBarDelegate* infobar_delegate =
    337       infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
    338   ASSERT_TRUE(infobar_delegate);
    339   infobar_delegate->Accept();
    340   EXPECT_TRUE(
    341       MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled());
    342 }
    343 #endif
    344 
    345 TEST_F(GeolocationPermissionContextTests, QueuedPermission) {
    346   GURL requesting_frame_0("http://www.example.com/geolocation");
    347   GURL requesting_frame_1("http://www.example-2.com/geolocation");
    348   EXPECT_EQ(CONTENT_SETTING_ASK,
    349             profile()->GetHostContentSettingsMap()->GetContentSetting(
    350                 requesting_frame_0, requesting_frame_0,
    351                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    352   EXPECT_EQ(CONTENT_SETTING_ASK,
    353             profile()->GetHostContentSettingsMap()->GetContentSetting(
    354                 requesting_frame_1, requesting_frame_0,
    355                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    356 
    357   NavigateAndCommit(requesting_frame_0);
    358   EXPECT_EQ(0U, infobar_service()->infobar_count());
    359   // Request permission for two frames.
    360   RequestGeolocationPermission(
    361       web_contents(), RequestID(0), requesting_frame_0);
    362   RequestGeolocationPermission(
    363       web_contents(), RequestID(1), requesting_frame_1);
    364   // Ensure only one infobar is created.
    365   ASSERT_EQ(1U, infobar_service()->infobar_count());
    366   infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0);
    367   ConfirmInfoBarDelegate* infobar_delegate_0 =
    368       infobar_0->delegate()->AsConfirmInfoBarDelegate();
    369   ASSERT_TRUE(infobar_delegate_0);
    370   base::string16 text_0 = infobar_delegate_0->GetMessageText();
    371 
    372   // Accept the first frame.
    373   infobar_delegate_0->Accept();
    374   CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW);
    375   CheckPermissionMessageSent(0, true);
    376 
    377   infobar_service()->RemoveInfoBar(infobar_0);
    378   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    379   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
    380   closed_infobar_tracker_.Clear();
    381   // Now we should have a new infobar for the second frame.
    382   ASSERT_EQ(1U, infobar_service()->infobar_count());
    383 
    384   infobars::InfoBar* infobar_1 = infobar_service()->infobar_at(0);
    385   ConfirmInfoBarDelegate* infobar_delegate_1 =
    386       infobar_1->delegate()->AsConfirmInfoBarDelegate();
    387   ASSERT_TRUE(infobar_delegate_1);
    388   base::string16 text_1 = infobar_delegate_1->GetMessageText();
    389   EXPECT_NE(text_0, text_1);
    390 
    391   // Cancel (block) this frame.
    392   infobar_delegate_1->Cancel();
    393   CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK);
    394   CheckPermissionMessageSent(1, false);
    395   infobar_service()->RemoveInfoBar(infobar_1);
    396   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    397   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
    398   EXPECT_EQ(0U, infobar_service()->infobar_count());
    399   // Ensure the persisted permissions are ok.
    400   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    401             profile()->GetHostContentSettingsMap()->GetContentSetting(
    402                 requesting_frame_0, requesting_frame_0,
    403                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    404 
    405   EXPECT_EQ(CONTENT_SETTING_BLOCK,
    406             profile()->GetHostContentSettingsMap()->GetContentSetting(
    407                 requesting_frame_1, requesting_frame_0,
    408                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    409 }
    410 
    411 TEST_F(GeolocationPermissionContextTests, HashIsIgnored) {
    412   GURL url_a("http://www.example.com/geolocation#a");
    413   GURL url_b("http://www.example.com/geolocation#b");
    414 
    415   // Navigate to the first url and check permission is requested.
    416   NavigateAndCommit(url_a);
    417   EXPECT_EQ(0U, infobar_service()->infobar_count());
    418   RequestGeolocationPermission(web_contents(), RequestID(0), url_a);
    419   ASSERT_EQ(1U, infobar_service()->infobar_count());
    420   infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
    421   ConfirmInfoBarDelegate* infobar_delegate =
    422       infobar->delegate()->AsConfirmInfoBarDelegate();
    423   ASSERT_TRUE(infobar_delegate);
    424 
    425   // Change the hash, we'll still be on the same page.
    426   NavigateAndCommit(url_b);
    427 
    428   // Accept.
    429   infobar_delegate->Accept();
    430   CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW);
    431   CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW);
    432   CheckPermissionMessageSent(0, true);
    433 
    434   // Cleanup.
    435   infobar_service()->RemoveInfoBar(infobar);
    436   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    437   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar));
    438 }
    439 
    440 TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) {
    441   GURL requesting_frame("file://example/geolocation.html");
    442   NavigateAndCommit(requesting_frame);
    443   EXPECT_EQ(0U, infobar_service()->infobar_count());
    444   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    445   EXPECT_EQ(1U, infobar_service()->infobar_count());
    446   infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
    447   ConfirmInfoBarDelegate* infobar_delegate =
    448       infobar->delegate()->AsConfirmInfoBarDelegate();
    449   ASSERT_TRUE(infobar_delegate);
    450   // Accept the frame.
    451   infobar_delegate->Accept();
    452   CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
    453   CheckPermissionMessageSent(0, true);
    454   infobar_service()->RemoveInfoBar(infobar);
    455 
    456   // Make sure the setting is not stored.
    457   EXPECT_EQ(CONTENT_SETTING_ASK,
    458       profile()->GetHostContentSettingsMap()->GetContentSetting(
    459           requesting_frame,
    460           requesting_frame,
    461           CONTENT_SETTINGS_TYPE_GEOLOCATION,
    462           std::string()));
    463 }
    464 
    465 TEST_F(GeolocationPermissionContextTests, CancelGeolocationPermissionRequest) {
    466   GURL requesting_frame_0("http://www.example.com/geolocation");
    467   GURL requesting_frame_1("http://www.example-2.com/geolocation");
    468   EXPECT_EQ(CONTENT_SETTING_ASK,
    469             profile()->GetHostContentSettingsMap()->GetContentSetting(
    470                 requesting_frame_0, requesting_frame_0,
    471                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    472 
    473   EXPECT_EQ(CONTENT_SETTING_ASK,
    474             profile()->GetHostContentSettingsMap()->GetContentSetting(
    475                 requesting_frame_1, requesting_frame_0,
    476                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    477 
    478   NavigateAndCommit(requesting_frame_0);
    479   EXPECT_EQ(0U, infobar_service()->infobar_count());
    480   // Request permission for two frames.
    481   base::Closure cancel_callback;
    482   RequestGeolocationPermission(
    483       web_contents(), RequestID(0), requesting_frame_0, &cancel_callback);
    484   RequestGeolocationPermission(
    485       web_contents(), RequestID(1), requesting_frame_1);
    486   ASSERT_EQ(1U, infobar_service()->infobar_count());
    487 
    488   infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0);
    489   ConfirmInfoBarDelegate* infobar_delegate_0 =
    490       infobar_0->delegate()->AsConfirmInfoBarDelegate();
    491   ASSERT_TRUE(infobar_delegate_0);
    492   base::string16 text_0 = infobar_delegate_0->GetMessageText();
    493 
    494   // Simulate the frame going away, ensure the infobar for this frame
    495   // is removed and the next pending infobar is created.
    496   cancel_callback.Run();
    497   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    498   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
    499   closed_infobar_tracker_.Clear();
    500   ASSERT_EQ(1U, infobar_service()->infobar_count());
    501 
    502   infobars::InfoBar* infobar_1 = infobar_service()->infobar_at(0);
    503   ConfirmInfoBarDelegate* infobar_delegate_1 =
    504       infobar_1->delegate()->AsConfirmInfoBarDelegate();
    505   ASSERT_TRUE(infobar_delegate_1);
    506   base::string16 text_1 = infobar_delegate_1->GetMessageText();
    507   EXPECT_NE(text_0, text_1);
    508 
    509   // Allow this frame.
    510   infobar_delegate_1->Accept();
    511   CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW);
    512   CheckPermissionMessageSent(1, true);
    513   infobar_service()->RemoveInfoBar(infobar_1);
    514   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    515   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
    516   EXPECT_EQ(0U, infobar_service()->infobar_count());
    517   // Ensure the persisted permissions are ok.
    518   EXPECT_EQ(CONTENT_SETTING_ASK,
    519             profile()->GetHostContentSettingsMap()->GetContentSetting(
    520                 requesting_frame_0, requesting_frame_0,
    521                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    522 
    523   EXPECT_EQ(CONTENT_SETTING_ALLOW,
    524             profile()->GetHostContentSettingsMap()->GetContentSetting(
    525                 requesting_frame_1, requesting_frame_0,
    526                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    527 }
    528 
    529 TEST_F(GeolocationPermissionContextTests, InvalidURL) {
    530   GURL invalid_embedder("about:blank");
    531   GURL requesting_frame;
    532   NavigateAndCommit(invalid_embedder);
    533   EXPECT_EQ(0U, infobar_service()->infobar_count());
    534   RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
    535   EXPECT_EQ(0U, infobar_service()->infobar_count());
    536   CheckPermissionMessageSent(0, false);
    537 }
    538 
    539 TEST_F(GeolocationPermissionContextTests, SameOriginMultipleTabs) {
    540   GURL url_a("http://www.example.com/geolocation");
    541   GURL url_b("http://www.example-2.com/geolocation");
    542   NavigateAndCommit(url_a);
    543   AddNewTab(url_b);
    544   AddNewTab(url_a);
    545 
    546   EXPECT_EQ(0U, infobar_service()->infobar_count());
    547   RequestGeolocationPermission(web_contents(), RequestID(0), url_a);
    548   ASSERT_EQ(1U, infobar_service()->infobar_count());
    549 
    550   RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 0), url_b);
    551   EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
    552 
    553   RequestGeolocationPermission(extra_tabs_[1], RequestIDForTab(1, 0), url_a);
    554   ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
    555 
    556   infobars::InfoBar* removed_infobar =
    557       infobar_service_for_tab(1)->infobar_at(0);
    558 
    559   // Accept the first tab.
    560   infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0);
    561   ConfirmInfoBarDelegate* infobar_delegate_0 =
    562       infobar_0->delegate()->AsConfirmInfoBarDelegate();
    563   ASSERT_TRUE(infobar_delegate_0);
    564   infobar_delegate_0->Accept();
    565   CheckPermissionMessageSent(0, true);
    566   infobar_service()->RemoveInfoBar(infobar_0);
    567   EXPECT_EQ(2U, closed_infobar_tracker_.size());
    568   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
    569   // Now the infobar for the tab with the same origin should have gone.
    570   EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
    571   CheckPermissionMessageSentForTab(1, 0, true);
    572   EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
    573   closed_infobar_tracker_.Clear();
    574 
    575   // But the other tab should still have the info bar...
    576   ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
    577   infobars::InfoBar* infobar_1 = infobar_service_for_tab(0)->infobar_at(0);
    578   ConfirmInfoBarDelegate* infobar_delegate_1 =
    579       infobar_1->delegate()->AsConfirmInfoBarDelegate();
    580   ASSERT_TRUE(infobar_delegate_1);
    581   infobar_delegate_1->Cancel();
    582   infobar_service_for_tab(0)->RemoveInfoBar(infobar_1);
    583   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    584   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
    585 }
    586 
    587 TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) {
    588   GURL url_a("http://www.example.com/geolocation");
    589   GURL url_b("http://www.example-2.com/geolocation");
    590   NavigateAndCommit(url_a);
    591   AddNewTab(url_a);
    592 
    593   EXPECT_EQ(0U, infobar_service()->infobar_count());
    594   RequestGeolocationPermission(web_contents(), RequestID(0), url_a);
    595   ASSERT_EQ(1U, infobar_service()->infobar_count());
    596 
    597   RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 0), url_a);
    598   EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
    599 
    600   RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 1), url_b);
    601   ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
    602 
    603   infobars::InfoBar* removed_infobar = infobar_service()->infobar_at(0);
    604 
    605   // Accept the second tab.
    606   infobars::InfoBar* infobar_0 = infobar_service_for_tab(0)->infobar_at(0);
    607   ConfirmInfoBarDelegate* infobar_delegate_0 =
    608       infobar_0->delegate()->AsConfirmInfoBarDelegate();
    609   ASSERT_TRUE(infobar_delegate_0);
    610   infobar_delegate_0->Accept();
    611   CheckPermissionMessageSentForTab(0, 0, true);
    612   infobar_service_for_tab(0)->RemoveInfoBar(infobar_0);
    613   EXPECT_EQ(2U, closed_infobar_tracker_.size());
    614   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
    615   // Now the infobar for the tab with the same origin should have gone.
    616   EXPECT_EQ(0U, infobar_service()->infobar_count());
    617   CheckPermissionMessageSent(0, true);
    618   EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
    619   closed_infobar_tracker_.Clear();
    620 
    621   // And we should have the queued infobar displayed now.
    622   ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
    623 
    624   // Accept the second infobar.
    625   infobars::InfoBar* infobar_1 = infobar_service_for_tab(0)->infobar_at(0);
    626   ConfirmInfoBarDelegate* infobar_delegate_1 =
    627       infobar_1->delegate()->AsConfirmInfoBarDelegate();
    628   ASSERT_TRUE(infobar_delegate_1);
    629   infobar_delegate_1->Accept();
    630   CheckPermissionMessageSentForTab(0, 1, true);
    631   infobar_service_for_tab(0)->RemoveInfoBar(infobar_1);
    632   EXPECT_EQ(1U, closed_infobar_tracker_.size());
    633   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1));
    634 }
    635 
    636 TEST_F(GeolocationPermissionContextTests, TabDestroyed) {
    637   GURL requesting_frame_0("http://www.example.com/geolocation");
    638   GURL requesting_frame_1("http://www.example-2.com/geolocation");
    639   EXPECT_EQ(CONTENT_SETTING_ASK,
    640             profile()->GetHostContentSettingsMap()->GetContentSetting(
    641                 requesting_frame_0, requesting_frame_0,
    642                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    643 
    644   EXPECT_EQ(CONTENT_SETTING_ASK,
    645             profile()->GetHostContentSettingsMap()->GetContentSetting(
    646                 requesting_frame_1, requesting_frame_0,
    647                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
    648 
    649   NavigateAndCommit(requesting_frame_0);
    650   EXPECT_EQ(0U, infobar_service()->infobar_count());
    651   // Request permission for two frames.
    652   RequestGeolocationPermission(
    653       web_contents(), RequestID(0), requesting_frame_0);
    654   RequestGeolocationPermission(
    655       web_contents(), RequestID(1), requesting_frame_1);
    656   // Ensure only one infobar is created.
    657   ASSERT_EQ(1U, infobar_service()->infobar_count());
    658   infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
    659 
    660   // Delete the tab contents.
    661   DeleteContents();
    662 
    663   // During contents destruction, the infobar will have been closed, and the
    664   // pending request should have been cleared without an infobar being created.
    665   ASSERT_EQ(1U, closed_infobar_tracker_.size());
    666   ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar));
    667 }
    668 
    669 TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) {
    670   GURL requesting_frame_0("http://www.example.com/geolocation");
    671   GURL requesting_frame_1("http://www.example-2.com/geolocation");
    672   NavigateAndCommit(requesting_frame_0);
    673   NavigateAndCommit(requesting_frame_1);
    674   EXPECT_EQ(0U, infobar_service()->infobar_count());
    675   // Go back: navigate to a pending entry before requesting geolocation
    676   // permission.
    677   web_contents()->GetController().GoBack();
    678   // Request permission for the committed frame (not the pending one).
    679   RequestGeolocationPermission(
    680       web_contents(), RequestID(0), requesting_frame_1);
    681   // Ensure the infobar is created.
    682   ASSERT_EQ(1U, infobar_service()->infobar_count());
    683   infobars::InfoBarDelegate* infobar_delegate =
    684       infobar_service()->infobar_at(0)->delegate();
    685   ASSERT_TRUE(infobar_delegate);
    686   // Ensure the infobar wouldn't expire for a navigation to the committed entry.
    687   content::LoadCommittedDetails details;
    688   details.entry = web_contents()->GetController().GetLastCommittedEntry();
    689   EXPECT_FALSE(infobar_delegate->ShouldExpire(
    690       InfoBarService::NavigationDetailsFromLoadCommittedDetails(details)));
    691   // Ensure the infobar will expire when we commit the pending navigation.
    692   details.entry = web_contents()->GetController().GetActiveEntry();
    693   EXPECT_TRUE(infobar_delegate->ShouldExpire(
    694       InfoBarService::NavigationDetailsFromLoadCommittedDetails(details)));
    695 
    696   // Delete the tab contents.
    697   DeleteContents();
    698 }
    699