| OLD | NEW |
| (Empty) |
| 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/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/chrome_geolocation_permission_context_facto
ry.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 CancelGeolocationPermissionRequest(content::WebContents* web_contents, | |
| 119 const PermissionRequestID& id, | |
| 120 const GURL& requesting_frame); | |
| 121 void PermissionResponse(const PermissionRequestID& id, | |
| 122 bool allowed); | |
| 123 void CheckPermissionMessageSent(int bridge_id, bool allowed); | |
| 124 void CheckPermissionMessageSentForTab(int tab, int bridge_id, bool allowed); | |
| 125 void CheckPermissionMessageSentInternal(MockRenderProcessHost* process, | |
| 126 int bridge_id, | |
| 127 bool allowed); | |
| 128 void AddNewTab(const GURL& url); | |
| 129 void CheckTabContentsState(const GURL& requesting_frame, | |
| 130 ContentSetting expected_content_setting); | |
| 131 | |
| 132 scoped_refptr<ChromeGeolocationPermissionContext> | |
| 133 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 geolocation_permission_context_->RequestGeolocationPermission( | |
| 166 web_contents, id.bridge_id(), requesting_frame, false, | |
| 167 base::Bind(&GeolocationPermissionContextTests::PermissionResponse, | |
| 168 base::Unretained(this), id)); | |
| 169 content::BrowserThread::GetBlockingPool()->FlushForTesting(); | |
| 170 base::RunLoop().RunUntilIdle(); | |
| 171 } | |
| 172 | |
| 173 void GeolocationPermissionContextTests::CancelGeolocationPermissionRequest( | |
| 174 content::WebContents* web_contents, | |
| 175 const PermissionRequestID& id, | |
| 176 const GURL& requesting_frame) { | |
| 177 geolocation_permission_context_->CancelGeolocationPermissionRequest( | |
| 178 web_contents, id.bridge_id(), requesting_frame); | |
| 179 } | |
| 180 | |
| 181 void GeolocationPermissionContextTests::PermissionResponse( | |
| 182 const PermissionRequestID& id, | |
| 183 bool allowed) { | |
| 184 responses_[id.render_process_id()] = std::make_pair(id.bridge_id(), allowed); | |
| 185 } | |
| 186 | |
| 187 void GeolocationPermissionContextTests::CheckPermissionMessageSent( | |
| 188 int bridge_id, | |
| 189 bool allowed) { | |
| 190 CheckPermissionMessageSentInternal(process(), bridge_id, allowed); | |
| 191 } | |
| 192 | |
| 193 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab( | |
| 194 int tab, | |
| 195 int bridge_id, | |
| 196 bool allowed) { | |
| 197 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost*>( | |
| 198 extra_tabs_[tab]->GetRenderProcessHost()), | |
| 199 bridge_id, allowed); | |
| 200 } | |
| 201 | |
| 202 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal( | |
| 203 MockRenderProcessHost* process, | |
| 204 int bridge_id, | |
| 205 bool allowed) { | |
| 206 ASSERT_EQ(responses_.count(process->GetID()), 1U); | |
| 207 EXPECT_EQ(bridge_id, responses_[process->GetID()].first); | |
| 208 EXPECT_EQ(allowed, responses_[process->GetID()].second); | |
| 209 responses_.erase(process->GetID()); | |
| 210 } | |
| 211 | |
| 212 void GeolocationPermissionContextTests::AddNewTab(const GURL& url) { | |
| 213 content::WebContents* new_tab = content::WebContents::Create( | |
| 214 content::WebContents::CreateParams(profile())); | |
| 215 new_tab->GetController().LoadURL( | |
| 216 url, content::Referrer(), content::PAGE_TRANSITION_TYPED, std::string()); | |
| 217 content::RenderViewHostTester::For(new_tab->GetRenderViewHost())-> | |
| 218 SendNavigate(extra_tabs_.size() + 1, url); | |
| 219 | |
| 220 // Set up required helpers, and make this be as "tabby" as the code requires. | |
| 221 extensions::SetViewType(new_tab, extensions::VIEW_TYPE_TAB_CONTENTS); | |
| 222 InfoBarService::CreateForWebContents(new_tab); | |
| 223 | |
| 224 extra_tabs_.push_back(new_tab); | |
| 225 } | |
| 226 | |
| 227 void GeolocationPermissionContextTests::CheckTabContentsState( | |
| 228 const GURL& requesting_frame, | |
| 229 ContentSetting expected_content_setting) { | |
| 230 TabSpecificContentSettings* content_settings = | |
| 231 TabSpecificContentSettings::FromWebContents(web_contents()); | |
| 232 const ContentSettingsUsagesState::StateMap& state_map = | |
| 233 content_settings->geolocation_usages_state().state_map(); | |
| 234 EXPECT_EQ(1U, state_map.count(requesting_frame.GetOrigin())); | |
| 235 EXPECT_EQ(0U, state_map.count(requesting_frame)); | |
| 236 ContentSettingsUsagesState::StateMap::const_iterator settings = | |
| 237 state_map.find(requesting_frame.GetOrigin()); | |
| 238 ASSERT_FALSE(settings == state_map.end()) | |
| 239 << "geolocation state not found " << requesting_frame; | |
| 240 EXPECT_EQ(expected_content_setting, settings->second); | |
| 241 } | |
| 242 | |
| 243 void GeolocationPermissionContextTests::SetUp() { | |
| 244 ChromeRenderViewHostTestHarness::SetUp(); | |
| 245 | |
| 246 // Set up required helpers, and make this be as "tabby" as the code requires. | |
| 247 extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS); | |
| 248 InfoBarService::CreateForWebContents(web_contents()); | |
| 249 TabSpecificContentSettings::CreateForWebContents(web_contents()); | |
| 250 #if defined(OS_ANDROID) | |
| 251 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true); | |
| 252 #endif | |
| 253 geolocation_permission_context_ = | |
| 254 ChromeGeolocationPermissionContextFactory::GetForProfile(profile()); | |
| 255 } | |
| 256 | |
| 257 void GeolocationPermissionContextTests::TearDown() { | |
| 258 extra_tabs_.clear(); | |
| 259 ChromeRenderViewHostTestHarness::TearDown(); | |
| 260 } | |
| 261 | |
| 262 // Tests ---------------------------------------------------------------------- | |
| 263 | |
| 264 TEST_F(GeolocationPermissionContextTests, SinglePermission) { | |
| 265 GURL requesting_frame("http://www.example.com/geolocation"); | |
| 266 NavigateAndCommit(requesting_frame); | |
| 267 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 268 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 269 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 270 infobars::InfoBar* infobar = infobar_service()->infobar_at(0); | |
| 271 ConfirmInfoBarDelegate* infobar_delegate = | |
| 272 infobar->delegate()->AsConfirmInfoBarDelegate(); | |
| 273 ASSERT_TRUE(infobar_delegate); | |
| 274 infobar_delegate->Cancel(); | |
| 275 infobar_service()->RemoveInfoBar(infobar); | |
| 276 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 277 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar)); | |
| 278 } | |
| 279 | |
| 280 #if defined(OS_ANDROID) | |
| 281 TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) { | |
| 282 GURL requesting_frame("http://www.example.com/geolocation"); | |
| 283 NavigateAndCommit(requesting_frame); | |
| 284 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true); | |
| 285 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 286 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 287 EXPECT_EQ(1U, infobar_service()->infobar_count()); | |
| 288 ConfirmInfoBarDelegate* infobar_delegate_0 = | |
| 289 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate(); | |
| 290 ASSERT_TRUE(infobar_delegate_0); | |
| 291 base::string16 text_0 = infobar_delegate_0->GetButtonLabel( | |
| 292 ConfirmInfoBarDelegate::BUTTON_OK); | |
| 293 | |
| 294 Reload(); | |
| 295 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false); | |
| 296 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 297 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 298 EXPECT_EQ(1U, infobar_service()->infobar_count()); | |
| 299 ConfirmInfoBarDelegate* infobar_delegate_1 = | |
| 300 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate(); | |
| 301 ASSERT_TRUE(infobar_delegate_1); | |
| 302 base::string16 text_1 = infobar_delegate_1->GetButtonLabel( | |
| 303 ConfirmInfoBarDelegate::BUTTON_OK); | |
| 304 EXPECT_NE(text_0, text_1); | |
| 305 | |
| 306 Reload(); | |
| 307 MockGoogleLocationSettingsHelper::SetLocationStatus(false, false); | |
| 308 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 309 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 310 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 311 } | |
| 312 | |
| 313 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) { | |
| 314 GURL requesting_frame("http://www.example.com/geolocation"); | |
| 315 NavigateAndCommit(requesting_frame); | |
| 316 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true); | |
| 317 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 318 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 319 EXPECT_EQ(1U, infobar_service()->infobar_count()); | |
| 320 ConfirmInfoBarDelegate* infobar_delegate = | |
| 321 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate(); | |
| 322 ASSERT_TRUE(infobar_delegate); | |
| 323 infobar_delegate->Accept(); | |
| 324 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW); | |
| 325 CheckPermissionMessageSent(0, true); | |
| 326 } | |
| 327 | |
| 328 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) { | |
| 329 GURL requesting_frame("http://www.example.com/geolocation"); | |
| 330 NavigateAndCommit(requesting_frame); | |
| 331 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false); | |
| 332 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 333 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 334 EXPECT_EQ(1U, infobar_service()->infobar_count()); | |
| 335 ConfirmInfoBarDelegate* infobar_delegate = | |
| 336 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate(); | |
| 337 ASSERT_TRUE(infobar_delegate); | |
| 338 infobar_delegate->Accept(); | |
| 339 EXPECT_TRUE( | |
| 340 MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled()); | |
| 341 } | |
| 342 #endif | |
| 343 | |
| 344 TEST_F(GeolocationPermissionContextTests, QueuedPermission) { | |
| 345 GURL requesting_frame_0("http://www.example.com/geolocation"); | |
| 346 GURL requesting_frame_1("http://www.example-2.com/geolocation"); | |
| 347 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 348 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 349 requesting_frame_0, requesting_frame_0, | |
| 350 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 351 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 352 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 353 requesting_frame_1, requesting_frame_0, | |
| 354 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 355 | |
| 356 NavigateAndCommit(requesting_frame_0); | |
| 357 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 358 // Request permission for two frames. | |
| 359 RequestGeolocationPermission( | |
| 360 web_contents(), RequestID(0), requesting_frame_0); | |
| 361 RequestGeolocationPermission( | |
| 362 web_contents(), RequestID(1), requesting_frame_1); | |
| 363 // Ensure only one infobar is created. | |
| 364 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 365 infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0); | |
| 366 ConfirmInfoBarDelegate* infobar_delegate_0 = | |
| 367 infobar_0->delegate()->AsConfirmInfoBarDelegate(); | |
| 368 ASSERT_TRUE(infobar_delegate_0); | |
| 369 base::string16 text_0 = infobar_delegate_0->GetMessageText(); | |
| 370 | |
| 371 // Accept the first frame. | |
| 372 infobar_delegate_0->Accept(); | |
| 373 CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW); | |
| 374 CheckPermissionMessageSent(0, true); | |
| 375 | |
| 376 infobar_service()->RemoveInfoBar(infobar_0); | |
| 377 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 378 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0)); | |
| 379 closed_infobar_tracker_.Clear(); | |
| 380 // Now we should have a new infobar for the second frame. | |
| 381 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 382 | |
| 383 infobars::InfoBar* infobar_1 = infobar_service()->infobar_at(0); | |
| 384 ConfirmInfoBarDelegate* infobar_delegate_1 = | |
| 385 infobar_1->delegate()->AsConfirmInfoBarDelegate(); | |
| 386 ASSERT_TRUE(infobar_delegate_1); | |
| 387 base::string16 text_1 = infobar_delegate_1->GetMessageText(); | |
| 388 EXPECT_NE(text_0, text_1); | |
| 389 | |
| 390 // Cancel (block) this frame. | |
| 391 infobar_delegate_1->Cancel(); | |
| 392 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK); | |
| 393 CheckPermissionMessageSent(1, false); | |
| 394 infobar_service()->RemoveInfoBar(infobar_1); | |
| 395 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 396 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1)); | |
| 397 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 398 // Ensure the persisted permissions are ok. | |
| 399 EXPECT_EQ(CONTENT_SETTING_ALLOW, | |
| 400 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 401 requesting_frame_0, requesting_frame_0, | |
| 402 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 403 | |
| 404 EXPECT_EQ(CONTENT_SETTING_BLOCK, | |
| 405 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 406 requesting_frame_1, requesting_frame_0, | |
| 407 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 408 } | |
| 409 | |
| 410 TEST_F(GeolocationPermissionContextTests, HashIsIgnored) { | |
| 411 GURL url_a("http://www.example.com/geolocation#a"); | |
| 412 GURL url_b("http://www.example.com/geolocation#b"); | |
| 413 | |
| 414 // Navigate to the first url and check permission is requested. | |
| 415 NavigateAndCommit(url_a); | |
| 416 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 417 RequestGeolocationPermission(web_contents(), RequestID(0), url_a); | |
| 418 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 419 infobars::InfoBar* infobar = infobar_service()->infobar_at(0); | |
| 420 ConfirmInfoBarDelegate* infobar_delegate = | |
| 421 infobar->delegate()->AsConfirmInfoBarDelegate(); | |
| 422 ASSERT_TRUE(infobar_delegate); | |
| 423 | |
| 424 // Change the hash, we'll still be on the same page. | |
| 425 NavigateAndCommit(url_b); | |
| 426 | |
| 427 // Accept. | |
| 428 infobar_delegate->Accept(); | |
| 429 CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW); | |
| 430 CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW); | |
| 431 CheckPermissionMessageSent(0, true); | |
| 432 | |
| 433 // Cleanup. | |
| 434 infobar_service()->RemoveInfoBar(infobar); | |
| 435 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 436 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar)); | |
| 437 } | |
| 438 | |
| 439 TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) { | |
| 440 GURL requesting_frame("file://example/geolocation.html"); | |
| 441 NavigateAndCommit(requesting_frame); | |
| 442 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 443 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 444 EXPECT_EQ(1U, infobar_service()->infobar_count()); | |
| 445 infobars::InfoBar* infobar = infobar_service()->infobar_at(0); | |
| 446 ConfirmInfoBarDelegate* infobar_delegate = | |
| 447 infobar->delegate()->AsConfirmInfoBarDelegate(); | |
| 448 ASSERT_TRUE(infobar_delegate); | |
| 449 // Accept the frame. | |
| 450 infobar_delegate->Accept(); | |
| 451 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW); | |
| 452 CheckPermissionMessageSent(0, true); | |
| 453 infobar_service()->RemoveInfoBar(infobar); | |
| 454 | |
| 455 // Make sure the setting is not stored. | |
| 456 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 457 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 458 requesting_frame, | |
| 459 requesting_frame, | |
| 460 CONTENT_SETTINGS_TYPE_GEOLOCATION, | |
| 461 std::string())); | |
| 462 } | |
| 463 | |
| 464 TEST_F(GeolocationPermissionContextTests, CancelGeolocationPermissionRequest) { | |
| 465 GURL requesting_frame_0("http://www.example.com/geolocation"); | |
| 466 GURL requesting_frame_1("http://www.example-2.com/geolocation"); | |
| 467 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 468 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 469 requesting_frame_0, requesting_frame_0, | |
| 470 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 471 | |
| 472 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 473 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 474 requesting_frame_1, requesting_frame_0, | |
| 475 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 476 | |
| 477 NavigateAndCommit(requesting_frame_0); | |
| 478 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 479 // Request permission for two frames. | |
| 480 RequestGeolocationPermission( | |
| 481 web_contents(), RequestID(0), requesting_frame_0); | |
| 482 RequestGeolocationPermission( | |
| 483 web_contents(), RequestID(1), requesting_frame_1); | |
| 484 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 485 | |
| 486 infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0); | |
| 487 ConfirmInfoBarDelegate* infobar_delegate_0 = | |
| 488 infobar_0->delegate()->AsConfirmInfoBarDelegate(); | |
| 489 ASSERT_TRUE(infobar_delegate_0); | |
| 490 base::string16 text_0 = infobar_delegate_0->GetMessageText(); | |
| 491 | |
| 492 // Simulate the frame going away, ensure the infobar for this frame | |
| 493 // is removed and the next pending infobar is created. | |
| 494 CancelGeolocationPermissionRequest( | |
| 495 web_contents(), RequestID(0), requesting_frame_0); | |
| 496 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 497 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0)); | |
| 498 closed_infobar_tracker_.Clear(); | |
| 499 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 500 | |
| 501 infobars::InfoBar* infobar_1 = infobar_service()->infobar_at(0); | |
| 502 ConfirmInfoBarDelegate* infobar_delegate_1 = | |
| 503 infobar_1->delegate()->AsConfirmInfoBarDelegate(); | |
| 504 ASSERT_TRUE(infobar_delegate_1); | |
| 505 base::string16 text_1 = infobar_delegate_1->GetMessageText(); | |
| 506 EXPECT_NE(text_0, text_1); | |
| 507 | |
| 508 // Allow this frame. | |
| 509 infobar_delegate_1->Accept(); | |
| 510 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW); | |
| 511 CheckPermissionMessageSent(1, true); | |
| 512 infobar_service()->RemoveInfoBar(infobar_1); | |
| 513 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 514 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1)); | |
| 515 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 516 // Ensure the persisted permissions are ok. | |
| 517 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 518 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 519 requesting_frame_0, requesting_frame_0, | |
| 520 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 521 | |
| 522 EXPECT_EQ(CONTENT_SETTING_ALLOW, | |
| 523 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 524 requesting_frame_1, requesting_frame_0, | |
| 525 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 526 } | |
| 527 | |
| 528 TEST_F(GeolocationPermissionContextTests, InvalidURL) { | |
| 529 GURL invalid_embedder("about:blank"); | |
| 530 GURL requesting_frame; | |
| 531 NavigateAndCommit(invalid_embedder); | |
| 532 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 533 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame); | |
| 534 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 535 CheckPermissionMessageSent(0, false); | |
| 536 } | |
| 537 | |
| 538 TEST_F(GeolocationPermissionContextTests, SameOriginMultipleTabs) { | |
| 539 GURL url_a("http://www.example.com/geolocation"); | |
| 540 GURL url_b("http://www.example-2.com/geolocation"); | |
| 541 NavigateAndCommit(url_a); | |
| 542 AddNewTab(url_b); | |
| 543 AddNewTab(url_a); | |
| 544 | |
| 545 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 546 RequestGeolocationPermission(web_contents(), RequestID(0), url_a); | |
| 547 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 548 | |
| 549 RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 0), url_b); | |
| 550 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); | |
| 551 | |
| 552 RequestGeolocationPermission(extra_tabs_[1], RequestIDForTab(1, 0), url_a); | |
| 553 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count()); | |
| 554 | |
| 555 infobars::InfoBar* removed_infobar = | |
| 556 infobar_service_for_tab(1)->infobar_at(0); | |
| 557 | |
| 558 // Accept the first tab. | |
| 559 infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0); | |
| 560 ConfirmInfoBarDelegate* infobar_delegate_0 = | |
| 561 infobar_0->delegate()->AsConfirmInfoBarDelegate(); | |
| 562 ASSERT_TRUE(infobar_delegate_0); | |
| 563 infobar_delegate_0->Accept(); | |
| 564 CheckPermissionMessageSent(0, true); | |
| 565 infobar_service()->RemoveInfoBar(infobar_0); | |
| 566 EXPECT_EQ(2U, closed_infobar_tracker_.size()); | |
| 567 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0)); | |
| 568 // Now the infobar for the tab with the same origin should have gone. | |
| 569 EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count()); | |
| 570 CheckPermissionMessageSentForTab(1, 0, true); | |
| 571 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar)); | |
| 572 closed_infobar_tracker_.Clear(); | |
| 573 | |
| 574 // But the other tab should still have the info bar... | |
| 575 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); | |
| 576 infobars::InfoBar* infobar_1 = infobar_service_for_tab(0)->infobar_at(0); | |
| 577 ConfirmInfoBarDelegate* infobar_delegate_1 = | |
| 578 infobar_1->delegate()->AsConfirmInfoBarDelegate(); | |
| 579 ASSERT_TRUE(infobar_delegate_1); | |
| 580 infobar_delegate_1->Cancel(); | |
| 581 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1); | |
| 582 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 583 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1)); | |
| 584 } | |
| 585 | |
| 586 TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) { | |
| 587 GURL url_a("http://www.example.com/geolocation"); | |
| 588 GURL url_b("http://www.example-2.com/geolocation"); | |
| 589 NavigateAndCommit(url_a); | |
| 590 AddNewTab(url_a); | |
| 591 | |
| 592 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 593 RequestGeolocationPermission(web_contents(), RequestID(0), url_a); | |
| 594 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 595 | |
| 596 RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 0), url_a); | |
| 597 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); | |
| 598 | |
| 599 RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 1), url_b); | |
| 600 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); | |
| 601 | |
| 602 infobars::InfoBar* removed_infobar = infobar_service()->infobar_at(0); | |
| 603 | |
| 604 // Accept the second tab. | |
| 605 infobars::InfoBar* infobar_0 = infobar_service_for_tab(0)->infobar_at(0); | |
| 606 ConfirmInfoBarDelegate* infobar_delegate_0 = | |
| 607 infobar_0->delegate()->AsConfirmInfoBarDelegate(); | |
| 608 ASSERT_TRUE(infobar_delegate_0); | |
| 609 infobar_delegate_0->Accept(); | |
| 610 CheckPermissionMessageSentForTab(0, 0, true); | |
| 611 infobar_service_for_tab(0)->RemoveInfoBar(infobar_0); | |
| 612 EXPECT_EQ(2U, closed_infobar_tracker_.size()); | |
| 613 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0)); | |
| 614 // Now the infobar for the tab with the same origin should have gone. | |
| 615 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 616 CheckPermissionMessageSent(0, true); | |
| 617 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar)); | |
| 618 closed_infobar_tracker_.Clear(); | |
| 619 | |
| 620 // And we should have the queued infobar displayed now. | |
| 621 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count()); | |
| 622 | |
| 623 // Accept the second infobar. | |
| 624 infobars::InfoBar* infobar_1 = infobar_service_for_tab(0)->infobar_at(0); | |
| 625 ConfirmInfoBarDelegate* infobar_delegate_1 = | |
| 626 infobar_1->delegate()->AsConfirmInfoBarDelegate(); | |
| 627 ASSERT_TRUE(infobar_delegate_1); | |
| 628 infobar_delegate_1->Accept(); | |
| 629 CheckPermissionMessageSentForTab(0, 1, true); | |
| 630 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1); | |
| 631 EXPECT_EQ(1U, closed_infobar_tracker_.size()); | |
| 632 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_1)); | |
| 633 } | |
| 634 | |
| 635 TEST_F(GeolocationPermissionContextTests, TabDestroyed) { | |
| 636 GURL requesting_frame_0("http://www.example.com/geolocation"); | |
| 637 GURL requesting_frame_1("http://www.example-2.com/geolocation"); | |
| 638 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 639 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 640 requesting_frame_0, requesting_frame_0, | |
| 641 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 642 | |
| 643 EXPECT_EQ(CONTENT_SETTING_ASK, | |
| 644 profile()->GetHostContentSettingsMap()->GetContentSetting( | |
| 645 requesting_frame_1, requesting_frame_0, | |
| 646 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string())); | |
| 647 | |
| 648 NavigateAndCommit(requesting_frame_0); | |
| 649 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 650 // Request permission for two frames. | |
| 651 RequestGeolocationPermission( | |
| 652 web_contents(), RequestID(0), requesting_frame_0); | |
| 653 RequestGeolocationPermission( | |
| 654 web_contents(), RequestID(1), requesting_frame_1); | |
| 655 // Ensure only one infobar is created. | |
| 656 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 657 infobars::InfoBar* infobar = infobar_service()->infobar_at(0); | |
| 658 | |
| 659 // Delete the tab contents. | |
| 660 DeleteContents(); | |
| 661 | |
| 662 // During contents destruction, the infobar will have been closed, and the | |
| 663 // pending request should have been cleared without an infobar being created. | |
| 664 ASSERT_EQ(1U, closed_infobar_tracker_.size()); | |
| 665 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar)); | |
| 666 } | |
| 667 | |
| 668 TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) { | |
| 669 GURL requesting_frame_0("http://www.example.com/geolocation"); | |
| 670 GURL requesting_frame_1("http://www.example-2.com/geolocation"); | |
| 671 NavigateAndCommit(requesting_frame_0); | |
| 672 NavigateAndCommit(requesting_frame_1); | |
| 673 EXPECT_EQ(0U, infobar_service()->infobar_count()); | |
| 674 // Go back: navigate to a pending entry before requesting geolocation | |
| 675 // permission. | |
| 676 web_contents()->GetController().GoBack(); | |
| 677 // Request permission for the committed frame (not the pending one). | |
| 678 RequestGeolocationPermission( | |
| 679 web_contents(), RequestID(0), requesting_frame_1); | |
| 680 // Ensure the infobar is created. | |
| 681 ASSERT_EQ(1U, infobar_service()->infobar_count()); | |
| 682 infobars::InfoBarDelegate* infobar_delegate = | |
| 683 infobar_service()->infobar_at(0)->delegate(); | |
| 684 ASSERT_TRUE(infobar_delegate); | |
| 685 // Ensure the infobar wouldn't expire for a navigation to the committed entry. | |
| 686 content::LoadCommittedDetails details; | |
| 687 details.entry = web_contents()->GetController().GetLastCommittedEntry(); | |
| 688 EXPECT_FALSE(infobar_delegate->ShouldExpire( | |
| 689 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details))); | |
| 690 // Ensure the infobar will expire when we commit the pending navigation. | |
| 691 details.entry = web_contents()->GetController().GetActiveEntry(); | |
| 692 EXPECT_TRUE(infobar_delegate->ShouldExpire( | |
| 693 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details))); | |
| 694 | |
| 695 // Delete the tab contents. | |
| 696 DeleteContents(); | |
| 697 } | |
| OLD | NEW |