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.
5 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
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"
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"
41 using content::MockRenderProcessHost;
44 // ClosedInfoBarTracker -------------------------------------------------------
46 // We need to track which infobars were closed.
47 class ClosedInfoBarTracker : public content::NotificationObserver {
49 ClosedInfoBarTracker();
50 virtual ~ClosedInfoBarTracker();
52 // content::NotificationObserver:
53 virtual void Observe(int type,
54 const content::NotificationSource& source,
55 const content::NotificationDetails& details) OVERRIDE;
57 size_t size() const { return removed_infobars_.size(); }
59 bool Contains(InfoBarDelegate* infobar) const;
63 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests, TabDestroyed);
64 content::NotificationRegistrar registrar_;
65 std::set<InfoBarDelegate*> removed_infobars_;
68 ClosedInfoBarTracker::ClosedInfoBarTracker() {
69 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
70 content::NotificationService::AllSources());
73 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
76 void ClosedInfoBarTracker::Observe(
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);
85 bool ClosedInfoBarTracker::Contains(InfoBarDelegate* infobar) const {
86 return removed_infobars_.count(infobar) != 0;
89 void ClosedInfoBarTracker::Clear() {
90 removed_infobars_.clear();
94 // GeolocationPermissionContextTests ------------------------------------------
96 class GeolocationPermissionContextTests
97 : public ChromeRenderViewHostTestHarness {
99 // ChromeRenderViewHostTestHarness:
100 virtual void SetUp() OVERRIDE;
101 virtual void TearDown() OVERRIDE;
103 PermissionRequestID RequestID(int bridge_id);
104 PermissionRequestID RequestIDForTab(int tab, int bridge_id);
105 InfoBarService* infobar_service() {
106 return InfoBarService::FromWebContents(web_contents());
108 InfoBarService* infobar_service_for_tab(int tab) {
109 return InfoBarService::FromWebContents(extra_tabs_[tab]);
112 void RequestGeolocationPermission(const PermissionRequestID& id,
113 const GURL& requesting_frame);
114 void CancelGeolocationPermissionRequest(const PermissionRequestID& id,
115 const GURL& requesting_frame);
116 void PermissionResponse(const PermissionRequestID& id,
118 void CheckPermissionMessageSent(int bridge_id, bool allowed);
119 void CheckPermissionMessageSentForTab(int tab, int bridge_id, bool allowed);
120 void CheckPermissionMessageSentInternal(MockRenderProcessHost* process,
123 void AddNewTab(const GURL& url);
124 void CheckTabContentsState(const GURL& requesting_frame,
125 ContentSetting expected_content_setting);
127 scoped_refptr<ChromeGeolocationPermissionContext>
128 geolocation_permission_context_;
129 ClosedInfoBarTracker closed_infobar_tracker_;
130 ScopedVector<content::WebContents> extra_tabs_;
132 // A map between renderer child id and a pair represending the bridge id and
133 // whether the requested permission was allowed.
134 base::hash_map<int, std::pair<int, bool> > responses_;
137 PermissionRequestID GeolocationPermissionContextTests::RequestID(
139 return PermissionRequestID(
140 web_contents()->GetRenderProcessHost()->GetID(),
141 web_contents()->GetRenderViewHost()->GetRoutingID(),
145 PermissionRequestID GeolocationPermissionContextTests::RequestIDForTab(
148 return PermissionRequestID(
149 extra_tabs_[tab]->GetRenderProcessHost()->GetID(),
150 extra_tabs_[tab]->GetRenderViewHost()->GetRoutingID(),
154 void GeolocationPermissionContextTests::RequestGeolocationPermission(
155 const PermissionRequestID& id,
156 const GURL& requesting_frame) {
157 geolocation_permission_context_->RequestGeolocationPermission(
158 id.render_process_id(), id.render_view_id(), id.bridge_id(),
160 base::Bind(&GeolocationPermissionContextTests::PermissionResponse,
161 base::Unretained(this), id));
164 void GeolocationPermissionContextTests::CancelGeolocationPermissionRequest(
165 const PermissionRequestID& id,
166 const GURL& requesting_frame) {
167 geolocation_permission_context_->CancelGeolocationPermissionRequest(
168 id.render_process_id(), id.render_view_id(), id.bridge_id(),
172 void GeolocationPermissionContextTests::PermissionResponse(
173 const PermissionRequestID& id,
175 responses_[id.render_process_id()] = std::make_pair(id.bridge_id(), allowed);
178 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
181 CheckPermissionMessageSentInternal(process(), bridge_id, allowed);
184 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
188 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost*>(
189 extra_tabs_[tab]->GetRenderProcessHost()),
193 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
194 MockRenderProcessHost* process,
197 ASSERT_EQ(responses_.count(process->GetID()), 1U);
198 EXPECT_EQ(bridge_id, responses_[process->GetID()].first);
199 EXPECT_EQ(allowed, responses_[process->GetID()].second);
200 responses_.erase(process->GetID());
203 void GeolocationPermissionContextTests::AddNewTab(const GURL& url) {
204 content::WebContents* new_tab = content::WebContents::Create(
205 content::WebContents::CreateParams(profile()));
206 new_tab->GetController().LoadURL(
207 url, content::Referrer(), content::PAGE_TRANSITION_TYPED, std::string());
208 content::RenderViewHostTester::For(new_tab->GetRenderViewHost())->
209 SendNavigate(extra_tabs_.size() + 1, url);
211 // Set up required helpers, and make this be as "tabby" as the code requires.
212 extensions::SetViewType(new_tab, extensions::VIEW_TYPE_TAB_CONTENTS);
213 InfoBarService::CreateForWebContents(new_tab);
215 extra_tabs_.push_back(new_tab);
218 void GeolocationPermissionContextTests::CheckTabContentsState(
219 const GURL& requesting_frame,
220 ContentSetting expected_content_setting) {
221 TabSpecificContentSettings* content_settings =
222 TabSpecificContentSettings::FromWebContents(web_contents());
223 const ContentSettingsUsagesState::StateMap& state_map =
224 content_settings->geolocation_usages_state().state_map();
225 EXPECT_EQ(1U, state_map.count(requesting_frame.GetOrigin()));
226 EXPECT_EQ(0U, state_map.count(requesting_frame));
227 ContentSettingsUsagesState::StateMap::const_iterator settings =
228 state_map.find(requesting_frame.GetOrigin());
229 ASSERT_FALSE(settings == state_map.end())
230 << "geolocation state not found " << requesting_frame;
231 EXPECT_EQ(expected_content_setting, settings->second);
234 void GeolocationPermissionContextTests::SetUp() {
235 ChromeRenderViewHostTestHarness::SetUp();
237 // Set up required helpers, and make this be as "tabby" as the code requires.
238 extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS);
239 InfoBarService::CreateForWebContents(web_contents());
240 TabSpecificContentSettings::CreateForWebContents(web_contents());
241 #if defined(OS_ANDROID)
242 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
244 geolocation_permission_context_ =
245 ChromeGeolocationPermissionContextFactory::GetForProfile(profile());
248 void GeolocationPermissionContextTests::TearDown() {
250 ChromeRenderViewHostTestHarness::TearDown();
253 // Tests ----------------------------------------------------------------------
255 TEST_F(GeolocationPermissionContextTests, SinglePermission) {
256 GURL requesting_frame("http://www.example.com/geolocation");
257 NavigateAndCommit(requesting_frame);
258 EXPECT_EQ(0U, infobar_service()->infobar_count());
259 RequestGeolocationPermission(RequestID(0), requesting_frame);
260 ASSERT_EQ(1U, infobar_service()->infobar_count());
261 ConfirmInfoBarDelegate* infobar_delegate =
262 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
263 ASSERT_TRUE(infobar_delegate);
264 infobar_delegate->Cancel();
265 infobar_service()->RemoveInfoBar(infobar_delegate);
266 EXPECT_EQ(1U, closed_infobar_tracker_.size());
267 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate));
268 delete infobar_delegate;
271 #if defined(OS_ANDROID)
272 TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
273 GURL requesting_frame("http://www.example.com/geolocation");
274 NavigateAndCommit(requesting_frame);
275 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
276 EXPECT_EQ(0U, infobar_service()->infobar_count());
277 RequestGeolocationPermission(RequestID(0), requesting_frame);
278 EXPECT_EQ(1U, infobar_service()->infobar_count());
279 ConfirmInfoBarDelegate* infobar_delegate_0 =
280 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
281 ASSERT_TRUE(infobar_delegate_0);
282 string16 text_0 = infobar_delegate_0->GetButtonLabel(
283 ConfirmInfoBarDelegate::BUTTON_OK);
285 NavigateAndCommit(requesting_frame);
286 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
287 EXPECT_EQ(0U, infobar_service()->infobar_count());
288 RequestGeolocationPermission(RequestID(0), requesting_frame);
289 EXPECT_EQ(1U, infobar_service()->infobar_count());
290 ConfirmInfoBarDelegate* infobar_delegate_1 =
291 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
292 ASSERT_TRUE(infobar_delegate_1);
293 string16 text_1 = infobar_delegate_1->GetButtonLabel(
294 ConfirmInfoBarDelegate::BUTTON_OK);
295 EXPECT_NE(text_0, text_1);
297 NavigateAndCommit(requesting_frame);
298 MockGoogleLocationSettingsHelper::SetLocationStatus(false, false);
299 EXPECT_EQ(0U, infobar_service()->infobar_count());
300 RequestGeolocationPermission(RequestID(0), requesting_frame);
301 EXPECT_EQ(0U, infobar_service()->infobar_count());
304 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) {
305 GURL requesting_frame("http://www.example.com/geolocation");
306 NavigateAndCommit(requesting_frame);
307 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
308 EXPECT_EQ(0U, infobar_service()->infobar_count());
309 RequestGeolocationPermission(RequestID(0), requesting_frame);
310 EXPECT_EQ(1U, infobar_service()->infobar_count());
311 ConfirmInfoBarDelegate* infobar_delegate =
312 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
313 ASSERT_TRUE(infobar_delegate);
314 infobar_delegate->Accept();
315 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
316 CheckPermissionMessageSent(0, true);
319 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) {
320 GURL requesting_frame("http://www.example.com/geolocation");
321 NavigateAndCommit(requesting_frame);
322 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
323 EXPECT_EQ(0U, infobar_service()->infobar_count());
324 RequestGeolocationPermission(RequestID(0), requesting_frame);
325 EXPECT_EQ(1U, infobar_service()->infobar_count());
326 ConfirmInfoBarDelegate* infobar_delegate =
327 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
328 ASSERT_TRUE(infobar_delegate);
329 infobar_delegate->Accept();
331 MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled());
335 TEST_F(GeolocationPermissionContextTests, QueuedPermission) {
336 GURL requesting_frame_0("http://www.example.com/geolocation");
337 GURL requesting_frame_1("http://www.example-2.com/geolocation");
338 EXPECT_EQ(CONTENT_SETTING_ASK,
339 profile()->GetHostContentSettingsMap()->GetContentSetting(
340 requesting_frame_0, requesting_frame_0,
341 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
342 EXPECT_EQ(CONTENT_SETTING_ASK,
343 profile()->GetHostContentSettingsMap()->GetContentSetting(
344 requesting_frame_1, requesting_frame_0,
345 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
347 NavigateAndCommit(requesting_frame_0);
348 EXPECT_EQ(0U, infobar_service()->infobar_count());
349 // Request permission for two frames.
350 RequestGeolocationPermission(RequestID(0), requesting_frame_0);
351 RequestGeolocationPermission(RequestID(1), requesting_frame_1);
352 // Ensure only one infobar is created.
353 ASSERT_EQ(1U, infobar_service()->infobar_count());
354 ConfirmInfoBarDelegate* infobar_delegate_0 =
355 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
356 ASSERT_TRUE(infobar_delegate_0);
357 string16 text_0 = infobar_delegate_0->GetMessageText();
359 // Accept the first frame.
360 infobar_delegate_0->Accept();
361 CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW);
362 CheckPermissionMessageSent(0, true);
364 infobar_service()->RemoveInfoBar(infobar_delegate_0);
365 EXPECT_EQ(1U, closed_infobar_tracker_.size());
366 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
367 closed_infobar_tracker_.Clear();
368 delete infobar_delegate_0;
369 // Now we should have a new infobar for the second frame.
370 ASSERT_EQ(1U, infobar_service()->infobar_count());
372 ConfirmInfoBarDelegate* infobar_delegate_1 =
373 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
374 ASSERT_TRUE(infobar_delegate_1);
375 string16 text_1 = infobar_delegate_1->GetMessageText();
376 EXPECT_NE(text_0, text_1);
378 // Cancel (block) this frame.
379 infobar_delegate_1->Cancel();
380 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK);
381 CheckPermissionMessageSent(1, false);
382 infobar_service()->RemoveInfoBar(infobar_delegate_1);
383 EXPECT_EQ(1U, closed_infobar_tracker_.size());
384 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
385 delete infobar_delegate_1;
386 EXPECT_EQ(0U, infobar_service()->infobar_count());
387 // Ensure the persisted permissions are ok.
388 EXPECT_EQ(CONTENT_SETTING_ALLOW,
389 profile()->GetHostContentSettingsMap()->GetContentSetting(
390 requesting_frame_0, requesting_frame_0,
391 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
393 EXPECT_EQ(CONTENT_SETTING_BLOCK,
394 profile()->GetHostContentSettingsMap()->GetContentSetting(
395 requesting_frame_1, requesting_frame_0,
396 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
399 TEST_F(GeolocationPermissionContextTests, HashIsIgnored) {
400 GURL url_a("http://www.example.com/geolocation#a");
401 GURL url_b("http://www.example.com/geolocation#b");
403 // Navigate to the first url and check permission is requested.
404 NavigateAndCommit(url_a);
405 EXPECT_EQ(0U, infobar_service()->infobar_count());
406 RequestGeolocationPermission(RequestID(0), url_a);
407 ASSERT_EQ(1U, infobar_service()->infobar_count());
408 ConfirmInfoBarDelegate* infobar_delegate =
409 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
410 ASSERT_TRUE(infobar_delegate);
412 // Change the hash, we'll still be on the same page.
413 NavigateAndCommit(url_b);
416 infobar_delegate->Accept();
417 CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW);
418 CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW);
419 CheckPermissionMessageSent(0, true);
422 infobar_service()->RemoveInfoBar(infobar_delegate);
423 EXPECT_EQ(1U, closed_infobar_tracker_.size());
424 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate));
425 closed_infobar_tracker_.Clear();
426 delete infobar_delegate;
429 TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) {
430 GURL requesting_frame("file://example/geolocation.html");
431 NavigateAndCommit(requesting_frame);
432 EXPECT_EQ(0U, infobar_service()->infobar_count());
433 RequestGeolocationPermission(RequestID(0), requesting_frame);
434 EXPECT_EQ(1U, infobar_service()->infobar_count());
435 ConfirmInfoBarDelegate* infobar_delegate =
436 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
437 ASSERT_TRUE(infobar_delegate);
439 infobar_delegate->Accept();
440 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
441 CheckPermissionMessageSent(0, true);
442 infobar_service()->RemoveInfoBar(infobar_delegate);
443 delete infobar_delegate;
445 // Make sure the setting is not stored.
446 EXPECT_EQ(CONTENT_SETTING_ASK,
447 profile()->GetHostContentSettingsMap()->GetContentSetting(
450 CONTENT_SETTINGS_TYPE_GEOLOCATION,
454 TEST_F(GeolocationPermissionContextTests, CancelGeolocationPermissionRequest) {
455 GURL requesting_frame_0("http://www.example.com/geolocation");
456 GURL requesting_frame_1("http://www.example-2.com/geolocation");
457 EXPECT_EQ(CONTENT_SETTING_ASK,
458 profile()->GetHostContentSettingsMap()->GetContentSetting(
459 requesting_frame_0, requesting_frame_0,
460 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
462 EXPECT_EQ(CONTENT_SETTING_ASK,
463 profile()->GetHostContentSettingsMap()->GetContentSetting(
464 requesting_frame_1, requesting_frame_0,
465 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
467 NavigateAndCommit(requesting_frame_0);
468 EXPECT_EQ(0U, infobar_service()->infobar_count());
469 // Request permission for two frames.
470 RequestGeolocationPermission(RequestID(0), requesting_frame_0);
471 RequestGeolocationPermission(RequestID(1), requesting_frame_1);
472 ASSERT_EQ(1U, infobar_service()->infobar_count());
474 ConfirmInfoBarDelegate* infobar_delegate_0 =
475 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
476 ASSERT_TRUE(infobar_delegate_0);
477 string16 text_0 = infobar_delegate_0->GetMessageText();
479 // Simulate the frame going away, ensure the infobar for this frame
480 // is removed and the next pending infobar is created.
481 CancelGeolocationPermissionRequest(RequestID(0), requesting_frame_0);
482 EXPECT_EQ(1U, closed_infobar_tracker_.size());
483 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
484 closed_infobar_tracker_.Clear();
485 delete infobar_delegate_0;
486 ASSERT_EQ(1U, infobar_service()->infobar_count());
488 ConfirmInfoBarDelegate* infobar_delegate_1 =
489 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
490 ASSERT_TRUE(infobar_delegate_1);
491 string16 text_1 = infobar_delegate_1->GetMessageText();
492 EXPECT_NE(text_0, text_1);
495 infobar_delegate_1->Accept();
496 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW);
497 CheckPermissionMessageSent(1, true);
498 infobar_service()->RemoveInfoBar(infobar_delegate_1);
499 EXPECT_EQ(1U, closed_infobar_tracker_.size());
500 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
501 delete infobar_delegate_1;
502 EXPECT_EQ(0U, infobar_service()->infobar_count());
503 // Ensure the persisted permissions are ok.
504 EXPECT_EQ(CONTENT_SETTING_ASK,
505 profile()->GetHostContentSettingsMap()->GetContentSetting(
506 requesting_frame_0, requesting_frame_0,
507 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
509 EXPECT_EQ(CONTENT_SETTING_ALLOW,
510 profile()->GetHostContentSettingsMap()->GetContentSetting(
511 requesting_frame_1, requesting_frame_0,
512 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
515 TEST_F(GeolocationPermissionContextTests, InvalidURL) {
516 GURL invalid_embedder("about:blank");
517 GURL requesting_frame;
518 NavigateAndCommit(invalid_embedder);
519 EXPECT_EQ(0U, infobar_service()->infobar_count());
520 RequestGeolocationPermission(RequestID(0), requesting_frame);
521 EXPECT_EQ(0U, infobar_service()->infobar_count());
522 CheckPermissionMessageSent(0, false);
525 TEST_F(GeolocationPermissionContextTests, SameOriginMultipleTabs) {
526 GURL url_a("http://www.example.com/geolocation");
527 GURL url_b("http://www.example-2.com/geolocation");
528 NavigateAndCommit(url_a);
532 EXPECT_EQ(0U, infobar_service()->infobar_count());
533 RequestGeolocationPermission(RequestID(0), url_a);
534 ASSERT_EQ(1U, infobar_service()->infobar_count());
536 RequestGeolocationPermission(RequestIDForTab(0, 0), url_b);
537 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
539 RequestGeolocationPermission(RequestIDForTab(1, 0), url_a);
540 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
542 ConfirmInfoBarDelegate* removed_infobar =
543 infobar_service_for_tab(1)->infobar_at(0)->AsConfirmInfoBarDelegate();
545 // Accept the first tab.
546 ConfirmInfoBarDelegate* infobar_delegate_0 =
547 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
548 ASSERT_TRUE(infobar_delegate_0);
549 infobar_delegate_0->Accept();
550 CheckPermissionMessageSent(0, true);
551 infobar_service()->RemoveInfoBar(infobar_delegate_0);
552 EXPECT_EQ(2U, closed_infobar_tracker_.size());
553 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
554 delete infobar_delegate_0;
555 // Now the infobar for the tab with the same origin should have gone.
556 EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
557 CheckPermissionMessageSentForTab(1, 0, true);
558 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
559 closed_infobar_tracker_.Clear();
560 // Destroy the infobar that has just been removed.
561 delete removed_infobar;
563 // But the other tab should still have the info bar...
564 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
565 ConfirmInfoBarDelegate* infobar_delegate_1 =
566 infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
567 infobar_delegate_1->Cancel();
568 infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1);
569 EXPECT_EQ(1U, closed_infobar_tracker_.size());
570 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
571 delete infobar_delegate_1;
574 TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) {
575 GURL url_a("http://www.example.com/geolocation");
576 GURL url_b("http://www.example-2.com/geolocation");
577 NavigateAndCommit(url_a);
580 EXPECT_EQ(0U, infobar_service()->infobar_count());
581 RequestGeolocationPermission(RequestID(0), url_a);
582 ASSERT_EQ(1U, infobar_service()->infobar_count());
584 RequestGeolocationPermission(RequestIDForTab(0, 0), url_a);
585 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
587 RequestGeolocationPermission(RequestIDForTab(0, 1), url_b);
588 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
590 ConfirmInfoBarDelegate* removed_infobar =
591 infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
593 // Accept the second tab.
594 ConfirmInfoBarDelegate* infobar_delegate_0 =
595 infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
596 ASSERT_TRUE(infobar_delegate_0);
597 infobar_delegate_0->Accept();
598 CheckPermissionMessageSentForTab(0, 0, true);
599 infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_0);
600 EXPECT_EQ(2U, closed_infobar_tracker_.size());
601 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
602 delete infobar_delegate_0;
603 // Now the infobar for the tab with the same origin should have gone.
604 EXPECT_EQ(0U, infobar_service()->infobar_count());
605 CheckPermissionMessageSent(0, true);
606 EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
607 closed_infobar_tracker_.Clear();
608 delete removed_infobar;
610 // And we should have the queued infobar displayed now.
611 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
613 // Accept the second infobar.
614 ConfirmInfoBarDelegate* infobar_delegate_1 =
615 infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
616 ASSERT_TRUE(infobar_delegate_1);
617 infobar_delegate_1->Accept();
618 CheckPermissionMessageSentForTab(0, 1, true);
619 infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1);
620 EXPECT_EQ(1U, closed_infobar_tracker_.size());
621 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
622 delete infobar_delegate_1;
625 TEST_F(GeolocationPermissionContextTests, TabDestroyed) {
626 GURL requesting_frame_0("http://www.example.com/geolocation");
627 GURL requesting_frame_1("http://www.example-2.com/geolocation");
628 EXPECT_EQ(CONTENT_SETTING_ASK,
629 profile()->GetHostContentSettingsMap()->GetContentSetting(
630 requesting_frame_0, requesting_frame_0,
631 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
633 EXPECT_EQ(CONTENT_SETTING_ASK,
634 profile()->GetHostContentSettingsMap()->GetContentSetting(
635 requesting_frame_1, requesting_frame_0,
636 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
638 NavigateAndCommit(requesting_frame_0);
639 EXPECT_EQ(0U, infobar_service()->infobar_count());
640 // Request permission for two frames.
641 RequestGeolocationPermission(RequestID(0), requesting_frame_0);
642 RequestGeolocationPermission(RequestID(1), requesting_frame_1);
643 // Ensure only one infobar is created.
644 ASSERT_EQ(1U, infobar_service()->infobar_count());
645 InfoBarDelegate* infobar = infobar_service()->infobar_at(0);
647 // Delete the tab contents.
651 // During contents destruction, the infobar will have been closed, and the
652 // pending request should have been cleared without an infobar being created.
653 ASSERT_EQ(1U, closed_infobar_tracker_.size());
654 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar));
657 TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) {
658 GURL requesting_frame_0("http://www.example.com/geolocation");
659 GURL requesting_frame_1("http://www.example-2.com/geolocation");
660 NavigateAndCommit(requesting_frame_0);
661 NavigateAndCommit(requesting_frame_1);
662 EXPECT_EQ(0U, infobar_service()->infobar_count());
663 // Go back: navigate to a pending entry before requesting geolocation
665 web_contents()->GetController().GoBack();
666 // Request permission for the committed frame (not the pending one).
667 RequestGeolocationPermission(RequestID(0), requesting_frame_1);
668 // Ensure the infobar is created.
669 ASSERT_EQ(1U, infobar_service()->infobar_count());
670 InfoBarDelegate* infobar_delegate = infobar_service()->infobar_at(0);
671 ASSERT_TRUE(infobar_delegate);
672 // Ensure the infobar wouldn't expire for a navigation to the committed entry.
673 content::LoadCommittedDetails details;
674 details.entry = web_contents()->GetController().GetLastCommittedEntry();
675 EXPECT_FALSE(infobar_delegate->ShouldExpire(details));
676 // Ensure the infobar will expire when we commit the pending navigation.
677 details.entry = web_contents()->GetController().GetActiveEntry();
678 EXPECT_TRUE(infobar_delegate->ShouldExpire(details));
680 // Delete the tab contents.
682 delete infobar_delegate;