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/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_factory.h"
21 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
22 #include "chrome/browser/infobars/infobar_service.h"
23 #include "chrome/browser/infobars/infobar_service.h"
24 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
25 #include "chrome/test/base/testing_profile.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"
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"
44 using content::MockRenderProcessHost
;
47 // ClosedInfoBarTracker -------------------------------------------------------
49 // We need to track which infobars were closed.
50 class ClosedInfoBarTracker
: public content::NotificationObserver
{
52 ClosedInfoBarTracker();
53 virtual ~ClosedInfoBarTracker();
55 // content::NotificationObserver:
56 virtual void Observe(int type
,
57 const content::NotificationSource
& source
,
58 const content::NotificationDetails
& details
) OVERRIDE
;
60 size_t size() const { return removed_infobars_
.size(); }
62 bool Contains(infobars::InfoBar
* infobar
) const;
66 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests
, TabDestroyed
);
67 content::NotificationRegistrar registrar_
;
68 std::set
<infobars::InfoBar
*> removed_infobars_
;
71 ClosedInfoBarTracker::ClosedInfoBarTracker() {
72 registrar_
.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
,
73 content::NotificationService::AllSources());
76 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
79 void ClosedInfoBarTracker::Observe(
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
);
88 bool ClosedInfoBarTracker::Contains(infobars::InfoBar
* infobar
) const {
89 return removed_infobars_
.count(infobar
) != 0;
92 void ClosedInfoBarTracker::Clear() {
93 removed_infobars_
.clear();
97 // GeolocationPermissionContextTests ------------------------------------------
99 class GeolocationPermissionContextTests
100 : public ChromeRenderViewHostTestHarness
{
102 // ChromeRenderViewHostTestHarness:
103 virtual void SetUp() OVERRIDE
;
104 virtual void TearDown() OVERRIDE
;
106 PermissionRequestID
RequestID(int bridge_id
);
107 PermissionRequestID
RequestIDForTab(int tab
, int bridge_id
);
108 InfoBarService
* infobar_service() {
109 return InfoBarService::FromWebContents(web_contents());
111 InfoBarService
* infobar_service_for_tab(int tab
) {
112 return InfoBarService::FromWebContents(extra_tabs_
[tab
]);
115 void RequestGeolocationPermission(const PermissionRequestID
& id
,
116 const GURL
& requesting_frame
);
117 void CancelGeolocationPermissionRequest(const PermissionRequestID
& id
,
118 const GURL
& requesting_frame
);
119 void PermissionResponse(const PermissionRequestID
& id
,
121 void CheckPermissionMessageSent(int bridge_id
, bool allowed
);
122 void CheckPermissionMessageSentForTab(int tab
, int bridge_id
, bool allowed
);
123 void CheckPermissionMessageSentInternal(MockRenderProcessHost
* process
,
126 void AddNewTab(const GURL
& url
);
127 void CheckTabContentsState(const GURL
& requesting_frame
,
128 ContentSetting expected_content_setting
);
130 scoped_refptr
<ChromeGeolocationPermissionContext
>
131 geolocation_permission_context_
;
132 ClosedInfoBarTracker closed_infobar_tracker_
;
133 ScopedVector
<content::WebContents
> extra_tabs_
;
135 // A map between renderer child id and a pair represending the bridge id and
136 // whether the requested permission was allowed.
137 base::hash_map
<int, std::pair
<int, bool> > responses_
;
140 PermissionRequestID
GeolocationPermissionContextTests::RequestID(
142 return PermissionRequestID(
143 web_contents()->GetRenderProcessHost()->GetID(),
144 web_contents()->GetRenderViewHost()->GetRoutingID(),
149 PermissionRequestID
GeolocationPermissionContextTests::RequestIDForTab(
152 return PermissionRequestID(
153 extra_tabs_
[tab
]->GetRenderProcessHost()->GetID(),
154 extra_tabs_
[tab
]->GetRenderViewHost()->GetRoutingID(),
159 void GeolocationPermissionContextTests::RequestGeolocationPermission(
160 const PermissionRequestID
& id
,
161 const GURL
& requesting_frame
) {
162 geolocation_permission_context_
->RequestGeolocationPermission(
163 id
.render_process_id(), id
.render_view_id(), id
.bridge_id(),
164 requesting_frame
, false,
165 base::Bind(&GeolocationPermissionContextTests::PermissionResponse
,
166 base::Unretained(this), id
));
167 content::BrowserThread::GetBlockingPool()->FlushForTesting();
168 base::RunLoop().RunUntilIdle();
171 void GeolocationPermissionContextTests::CancelGeolocationPermissionRequest(
172 const PermissionRequestID
& id
,
173 const GURL
& requesting_frame
) {
174 geolocation_permission_context_
->CancelGeolocationPermissionRequest(
175 id
.render_process_id(), id
.render_view_id(), id
.bridge_id(),
179 void GeolocationPermissionContextTests::PermissionResponse(
180 const PermissionRequestID
& id
,
182 responses_
[id
.render_process_id()] = std::make_pair(id
.bridge_id(), allowed
);
185 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
188 CheckPermissionMessageSentInternal(process(), bridge_id
, allowed
);
191 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
195 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost
*>(
196 extra_tabs_
[tab
]->GetRenderProcessHost()),
200 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
201 MockRenderProcessHost
* process
,
204 ASSERT_EQ(responses_
.count(process
->GetID()), 1U);
205 EXPECT_EQ(bridge_id
, responses_
[process
->GetID()].first
);
206 EXPECT_EQ(allowed
, responses_
[process
->GetID()].second
);
207 responses_
.erase(process
->GetID());
210 void GeolocationPermissionContextTests::AddNewTab(const GURL
& url
) {
211 content::WebContents
* new_tab
= content::WebContents::Create(
212 content::WebContents::CreateParams(profile()));
213 new_tab
->GetController().LoadURL(
214 url
, content::Referrer(), content::PAGE_TRANSITION_TYPED
, std::string());
215 content::RenderViewHostTester::For(new_tab
->GetRenderViewHost())->
216 SendNavigate(extra_tabs_
.size() + 1, url
);
218 // Set up required helpers, and make this be as "tabby" as the code requires.
219 extensions::SetViewType(new_tab
, extensions::VIEW_TYPE_TAB_CONTENTS
);
220 InfoBarService::CreateForWebContents(new_tab
);
222 extra_tabs_
.push_back(new_tab
);
225 void GeolocationPermissionContextTests::CheckTabContentsState(
226 const GURL
& requesting_frame
,
227 ContentSetting expected_content_setting
) {
228 TabSpecificContentSettings
* content_settings
=
229 TabSpecificContentSettings::FromWebContents(web_contents());
230 const ContentSettingsUsagesState::StateMap
& state_map
=
231 content_settings
->geolocation_usages_state().state_map();
232 EXPECT_EQ(1U, state_map
.count(requesting_frame
.GetOrigin()));
233 EXPECT_EQ(0U, state_map
.count(requesting_frame
));
234 ContentSettingsUsagesState::StateMap::const_iterator settings
=
235 state_map
.find(requesting_frame
.GetOrigin());
236 ASSERT_FALSE(settings
== state_map
.end())
237 << "geolocation state not found " << requesting_frame
;
238 EXPECT_EQ(expected_content_setting
, settings
->second
);
241 void GeolocationPermissionContextTests::SetUp() {
242 ChromeRenderViewHostTestHarness::SetUp();
244 // Set up required helpers, and make this be as "tabby" as the code requires.
245 extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS
);
246 InfoBarService::CreateForWebContents(web_contents());
247 TabSpecificContentSettings::CreateForWebContents(web_contents());
248 #if defined(OS_ANDROID)
249 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
251 geolocation_permission_context_
=
252 ChromeGeolocationPermissionContextFactory::GetForProfile(profile());
255 void GeolocationPermissionContextTests::TearDown() {
257 ChromeRenderViewHostTestHarness::TearDown();
260 // Tests ----------------------------------------------------------------------
262 TEST_F(GeolocationPermissionContextTests
, SinglePermission
) {
263 GURL
requesting_frame("http://www.example.com/geolocation");
264 NavigateAndCommit(requesting_frame
);
265 EXPECT_EQ(0U, infobar_service()->infobar_count());
266 RequestGeolocationPermission(RequestID(0), requesting_frame
);
267 ASSERT_EQ(1U, infobar_service()->infobar_count());
268 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
269 ConfirmInfoBarDelegate
* infobar_delegate
=
270 infobar
->delegate()->AsConfirmInfoBarDelegate();
271 ASSERT_TRUE(infobar_delegate
);
272 infobar_delegate
->Cancel();
273 infobar_service()->RemoveInfoBar(infobar
);
274 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
275 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
278 #if defined(OS_ANDROID)
279 TEST_F(GeolocationPermissionContextTests
, GeolocationEnabledDisabled
) {
280 GURL
requesting_frame("http://www.example.com/geolocation");
281 NavigateAndCommit(requesting_frame
);
282 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
283 EXPECT_EQ(0U, infobar_service()->infobar_count());
284 RequestGeolocationPermission(RequestID(0), requesting_frame
);
285 EXPECT_EQ(1U, infobar_service()->infobar_count());
286 ConfirmInfoBarDelegate
* infobar_delegate_0
=
287 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
288 ASSERT_TRUE(infobar_delegate_0
);
289 base::string16 text_0
= infobar_delegate_0
->GetButtonLabel(
290 ConfirmInfoBarDelegate::BUTTON_OK
);
292 NavigateAndCommit(requesting_frame
);
293 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
294 EXPECT_EQ(0U, infobar_service()->infobar_count());
295 RequestGeolocationPermission(RequestID(0), requesting_frame
);
296 EXPECT_EQ(1U, infobar_service()->infobar_count());
297 ConfirmInfoBarDelegate
* infobar_delegate_1
=
298 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
299 ASSERT_TRUE(infobar_delegate_1
);
300 base::string16 text_1
= infobar_delegate_1
->GetButtonLabel(
301 ConfirmInfoBarDelegate::BUTTON_OK
);
302 EXPECT_NE(text_0
, text_1
);
304 NavigateAndCommit(requesting_frame
);
305 MockGoogleLocationSettingsHelper::SetLocationStatus(false, false);
306 EXPECT_EQ(0U, infobar_service()->infobar_count());
307 RequestGeolocationPermission(RequestID(0), requesting_frame
);
308 EXPECT_EQ(0U, infobar_service()->infobar_count());
311 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsEnabled
) {
312 GURL
requesting_frame("http://www.example.com/geolocation");
313 NavigateAndCommit(requesting_frame
);
314 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
315 EXPECT_EQ(0U, infobar_service()->infobar_count());
316 RequestGeolocationPermission(RequestID(0), requesting_frame
);
317 EXPECT_EQ(1U, infobar_service()->infobar_count());
318 ConfirmInfoBarDelegate
* infobar_delegate
=
319 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
320 ASSERT_TRUE(infobar_delegate
);
321 infobar_delegate
->Accept();
322 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
323 CheckPermissionMessageSent(0, true);
326 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsDisabled
) {
327 GURL
requesting_frame("http://www.example.com/geolocation");
328 NavigateAndCommit(requesting_frame
);
329 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
330 EXPECT_EQ(0U, infobar_service()->infobar_count());
331 RequestGeolocationPermission(RequestID(0), requesting_frame
);
332 EXPECT_EQ(1U, infobar_service()->infobar_count());
333 ConfirmInfoBarDelegate
* infobar_delegate
=
334 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
335 ASSERT_TRUE(infobar_delegate
);
336 infobar_delegate
->Accept();
338 MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled());
342 TEST_F(GeolocationPermissionContextTests
, QueuedPermission
) {
343 GURL
requesting_frame_0("http://www.example.com/geolocation");
344 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
345 EXPECT_EQ(CONTENT_SETTING_ASK
,
346 profile()->GetHostContentSettingsMap()->GetContentSetting(
347 requesting_frame_0
, requesting_frame_0
,
348 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
349 EXPECT_EQ(CONTENT_SETTING_ASK
,
350 profile()->GetHostContentSettingsMap()->GetContentSetting(
351 requesting_frame_1
, requesting_frame_0
,
352 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
354 NavigateAndCommit(requesting_frame_0
);
355 EXPECT_EQ(0U, infobar_service()->infobar_count());
356 // Request permission for two frames.
357 RequestGeolocationPermission(RequestID(0), requesting_frame_0
);
358 RequestGeolocationPermission(RequestID(1), requesting_frame_1
);
359 // Ensure only one infobar is created.
360 ASSERT_EQ(1U, infobar_service()->infobar_count());
361 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
362 ConfirmInfoBarDelegate
* infobar_delegate_0
=
363 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
364 ASSERT_TRUE(infobar_delegate_0
);
365 base::string16 text_0
= infobar_delegate_0
->GetMessageText();
367 // Accept the first frame.
368 infobar_delegate_0
->Accept();
369 CheckTabContentsState(requesting_frame_0
, CONTENT_SETTING_ALLOW
);
370 CheckPermissionMessageSent(0, true);
372 infobar_service()->RemoveInfoBar(infobar_0
);
373 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
374 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
375 closed_infobar_tracker_
.Clear();
376 // Now we should have a new infobar for the second frame.
377 ASSERT_EQ(1U, infobar_service()->infobar_count());
379 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
380 ConfirmInfoBarDelegate
* infobar_delegate_1
=
381 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
382 ASSERT_TRUE(infobar_delegate_1
);
383 base::string16 text_1
= infobar_delegate_1
->GetMessageText();
384 EXPECT_NE(text_0
, text_1
);
386 // Cancel (block) this frame.
387 infobar_delegate_1
->Cancel();
388 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_BLOCK
);
389 CheckPermissionMessageSent(1, false);
390 infobar_service()->RemoveInfoBar(infobar_1
);
391 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
392 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
393 EXPECT_EQ(0U, infobar_service()->infobar_count());
394 // Ensure the persisted permissions are ok.
395 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
396 profile()->GetHostContentSettingsMap()->GetContentSetting(
397 requesting_frame_0
, requesting_frame_0
,
398 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
400 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
401 profile()->GetHostContentSettingsMap()->GetContentSetting(
402 requesting_frame_1
, requesting_frame_0
,
403 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
406 TEST_F(GeolocationPermissionContextTests
, HashIsIgnored
) {
407 GURL
url_a("http://www.example.com/geolocation#a");
408 GURL
url_b("http://www.example.com/geolocation#b");
410 // Navigate to the first url and check permission is requested.
411 NavigateAndCommit(url_a
);
412 EXPECT_EQ(0U, infobar_service()->infobar_count());
413 RequestGeolocationPermission(RequestID(0), url_a
);
414 ASSERT_EQ(1U, infobar_service()->infobar_count());
415 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
416 ConfirmInfoBarDelegate
* infobar_delegate
=
417 infobar
->delegate()->AsConfirmInfoBarDelegate();
418 ASSERT_TRUE(infobar_delegate
);
420 // Change the hash, we'll still be on the same page.
421 NavigateAndCommit(url_b
);
424 infobar_delegate
->Accept();
425 CheckTabContentsState(url_a
, CONTENT_SETTING_ALLOW
);
426 CheckTabContentsState(url_b
, CONTENT_SETTING_ALLOW
);
427 CheckPermissionMessageSent(0, true);
430 infobar_service()->RemoveInfoBar(infobar
);
431 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
432 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
435 TEST_F(GeolocationPermissionContextTests
, PermissionForFileScheme
) {
436 GURL
requesting_frame("file://example/geolocation.html");
437 NavigateAndCommit(requesting_frame
);
438 EXPECT_EQ(0U, infobar_service()->infobar_count());
439 RequestGeolocationPermission(RequestID(0), requesting_frame
);
440 EXPECT_EQ(1U, infobar_service()->infobar_count());
441 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
442 ConfirmInfoBarDelegate
* infobar_delegate
=
443 infobar
->delegate()->AsConfirmInfoBarDelegate();
444 ASSERT_TRUE(infobar_delegate
);
446 infobar_delegate
->Accept();
447 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
448 CheckPermissionMessageSent(0, true);
449 infobar_service()->RemoveInfoBar(infobar
);
451 // Make sure the setting is not stored.
452 EXPECT_EQ(CONTENT_SETTING_ASK
,
453 profile()->GetHostContentSettingsMap()->GetContentSetting(
456 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
460 TEST_F(GeolocationPermissionContextTests
, CancelGeolocationPermissionRequest
) {
461 GURL
requesting_frame_0("http://www.example.com/geolocation");
462 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
463 EXPECT_EQ(CONTENT_SETTING_ASK
,
464 profile()->GetHostContentSettingsMap()->GetContentSetting(
465 requesting_frame_0
, requesting_frame_0
,
466 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
468 EXPECT_EQ(CONTENT_SETTING_ASK
,
469 profile()->GetHostContentSettingsMap()->GetContentSetting(
470 requesting_frame_1
, requesting_frame_0
,
471 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
473 NavigateAndCommit(requesting_frame_0
);
474 EXPECT_EQ(0U, infobar_service()->infobar_count());
475 // Request permission for two frames.
476 RequestGeolocationPermission(RequestID(0), requesting_frame_0
);
477 RequestGeolocationPermission(RequestID(1), requesting_frame_1
);
478 ASSERT_EQ(1U, infobar_service()->infobar_count());
480 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
481 ConfirmInfoBarDelegate
* infobar_delegate_0
=
482 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
483 ASSERT_TRUE(infobar_delegate_0
);
484 base::string16 text_0
= infobar_delegate_0
->GetMessageText();
486 // Simulate the frame going away, ensure the infobar for this frame
487 // is removed and the next pending infobar is created.
488 CancelGeolocationPermissionRequest(RequestID(0), requesting_frame_0
);
489 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
490 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
491 closed_infobar_tracker_
.Clear();
492 ASSERT_EQ(1U, infobar_service()->infobar_count());
494 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
495 ConfirmInfoBarDelegate
* infobar_delegate_1
=
496 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
497 ASSERT_TRUE(infobar_delegate_1
);
498 base::string16 text_1
= infobar_delegate_1
->GetMessageText();
499 EXPECT_NE(text_0
, text_1
);
502 infobar_delegate_1
->Accept();
503 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_ALLOW
);
504 CheckPermissionMessageSent(1, true);
505 infobar_service()->RemoveInfoBar(infobar_1
);
506 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
507 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
508 EXPECT_EQ(0U, infobar_service()->infobar_count());
509 // Ensure the persisted permissions are ok.
510 EXPECT_EQ(CONTENT_SETTING_ASK
,
511 profile()->GetHostContentSettingsMap()->GetContentSetting(
512 requesting_frame_0
, requesting_frame_0
,
513 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
515 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
516 profile()->GetHostContentSettingsMap()->GetContentSetting(
517 requesting_frame_1
, requesting_frame_0
,
518 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
521 TEST_F(GeolocationPermissionContextTests
, InvalidURL
) {
522 GURL
invalid_embedder("about:blank");
523 GURL requesting_frame
;
524 NavigateAndCommit(invalid_embedder
);
525 EXPECT_EQ(0U, infobar_service()->infobar_count());
526 RequestGeolocationPermission(RequestID(0), requesting_frame
);
527 EXPECT_EQ(0U, infobar_service()->infobar_count());
528 CheckPermissionMessageSent(0, false);
531 TEST_F(GeolocationPermissionContextTests
, SameOriginMultipleTabs
) {
532 GURL
url_a("http://www.example.com/geolocation");
533 GURL
url_b("http://www.example-2.com/geolocation");
534 NavigateAndCommit(url_a
);
538 EXPECT_EQ(0U, infobar_service()->infobar_count());
539 RequestGeolocationPermission(RequestID(0), url_a
);
540 ASSERT_EQ(1U, infobar_service()->infobar_count());
542 RequestGeolocationPermission(RequestIDForTab(0, 0), url_b
);
543 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
545 RequestGeolocationPermission(RequestIDForTab(1, 0), url_a
);
546 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
548 infobars::InfoBar
* removed_infobar
=
549 infobar_service_for_tab(1)->infobar_at(0);
551 // Accept the first tab.
552 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
553 ConfirmInfoBarDelegate
* infobar_delegate_0
=
554 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
555 ASSERT_TRUE(infobar_delegate_0
);
556 infobar_delegate_0
->Accept();
557 CheckPermissionMessageSent(0, true);
558 infobar_service()->RemoveInfoBar(infobar_0
);
559 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
560 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
561 // Now the infobar for the tab with the same origin should have gone.
562 EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
563 CheckPermissionMessageSentForTab(1, 0, true);
564 EXPECT_TRUE(closed_infobar_tracker_
.Contains(removed_infobar
));
565 closed_infobar_tracker_
.Clear();
567 // But the other tab should still have the info bar...
568 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
569 infobars::InfoBar
* infobar_1
= infobar_service_for_tab(0)->infobar_at(0);
570 ConfirmInfoBarDelegate
* infobar_delegate_1
=
571 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
572 ASSERT_TRUE(infobar_delegate_1
);
573 infobar_delegate_1
->Cancel();
574 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1
);
575 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
576 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
579 TEST_F(GeolocationPermissionContextTests
, QueuedOriginMultipleTabs
) {
580 GURL
url_a("http://www.example.com/geolocation");
581 GURL
url_b("http://www.example-2.com/geolocation");
582 NavigateAndCommit(url_a
);
585 EXPECT_EQ(0U, infobar_service()->infobar_count());
586 RequestGeolocationPermission(RequestID(0), url_a
);
587 ASSERT_EQ(1U, infobar_service()->infobar_count());
589 RequestGeolocationPermission(RequestIDForTab(0, 0), url_a
);
590 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
592 RequestGeolocationPermission(RequestIDForTab(0, 1), url_b
);
593 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
595 infobars::InfoBar
* removed_infobar
= infobar_service()->infobar_at(0);
597 // Accept the second tab.
598 infobars::InfoBar
* infobar_0
= infobar_service_for_tab(0)->infobar_at(0);
599 ConfirmInfoBarDelegate
* infobar_delegate_0
=
600 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
601 ASSERT_TRUE(infobar_delegate_0
);
602 infobar_delegate_0
->Accept();
603 CheckPermissionMessageSentForTab(0, 0, true);
604 infobar_service_for_tab(0)->RemoveInfoBar(infobar_0
);
605 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
606 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
607 // Now the infobar for the tab with the same origin should have gone.
608 EXPECT_EQ(0U, infobar_service()->infobar_count());
609 CheckPermissionMessageSent(0, true);
610 EXPECT_TRUE(closed_infobar_tracker_
.Contains(removed_infobar
));
611 closed_infobar_tracker_
.Clear();
613 // And we should have the queued infobar displayed now.
614 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
616 // Accept the second infobar.
617 infobars::InfoBar
* infobar_1
= infobar_service_for_tab(0)->infobar_at(0);
618 ConfirmInfoBarDelegate
* infobar_delegate_1
=
619 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
620 ASSERT_TRUE(infobar_delegate_1
);
621 infobar_delegate_1
->Accept();
622 CheckPermissionMessageSentForTab(0, 1, true);
623 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1
);
624 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
625 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
628 TEST_F(GeolocationPermissionContextTests
, TabDestroyed
) {
629 GURL
requesting_frame_0("http://www.example.com/geolocation");
630 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
631 EXPECT_EQ(CONTENT_SETTING_ASK
,
632 profile()->GetHostContentSettingsMap()->GetContentSetting(
633 requesting_frame_0
, requesting_frame_0
,
634 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
636 EXPECT_EQ(CONTENT_SETTING_ASK
,
637 profile()->GetHostContentSettingsMap()->GetContentSetting(
638 requesting_frame_1
, requesting_frame_0
,
639 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
641 NavigateAndCommit(requesting_frame_0
);
642 EXPECT_EQ(0U, infobar_service()->infobar_count());
643 // Request permission for two frames.
644 RequestGeolocationPermission(RequestID(0), requesting_frame_0
);
645 RequestGeolocationPermission(RequestID(1), requesting_frame_1
);
646 // Ensure only one infobar is created.
647 ASSERT_EQ(1U, infobar_service()->infobar_count());
648 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
650 // Delete the tab contents.
653 // During contents destruction, the infobar will have been closed, and the
654 // pending request should have been cleared without an infobar being created.
655 ASSERT_EQ(1U, closed_infobar_tracker_
.size());
656 ASSERT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
659 TEST_F(GeolocationPermissionContextTests
, InfoBarUsesCommittedEntry
) {
660 GURL
requesting_frame_0("http://www.example.com/geolocation");
661 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
662 NavigateAndCommit(requesting_frame_0
);
663 NavigateAndCommit(requesting_frame_1
);
664 EXPECT_EQ(0U, infobar_service()->infobar_count());
665 // Go back: navigate to a pending entry before requesting geolocation
667 web_contents()->GetController().GoBack();
668 // Request permission for the committed frame (not the pending one).
669 RequestGeolocationPermission(RequestID(0), requesting_frame_1
);
670 // Ensure the infobar is created.
671 ASSERT_EQ(1U, infobar_service()->infobar_count());
672 infobars::InfoBarDelegate
* infobar_delegate
=
673 infobar_service()->infobar_at(0)->delegate();
674 ASSERT_TRUE(infobar_delegate
);
675 // Ensure the infobar wouldn't expire for a navigation to the committed entry.
676 content::LoadCommittedDetails details
;
677 details
.entry
= web_contents()->GetController().GetLastCommittedEntry();
678 EXPECT_FALSE(infobar_delegate
->ShouldExpire(
679 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details
)));
680 // Ensure the infobar will expire when we commit the pending navigation.
681 details
.entry
= web_contents()->GetController().GetActiveEntry();
682 EXPECT_TRUE(infobar_delegate
->ShouldExpire(
683 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details
)));
685 // Delete the tab contents.