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