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/geolocation_permission_context.h"
11 #include "base/bind.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/id_map.h"
14 #include "base/memory/scoped_vector.h"
15 #include "base/synchronization/waitable_event.h"
16 #include "base/test/simple_test_clock.h"
17 #include "base/time/clock.h"
18 #include "chrome/browser/chrome_notification_types.h"
19 #include "chrome/browser/content_settings/host_content_settings_map.h"
20 #include "chrome/browser/content_settings/permission_request_id.h"
21 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
22 #include "chrome/browser/geolocation/geolocation_permission_context_factory.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/confirm_infobar_delegate.h"
27 #include "components/infobars/core/infobar.h"
28 #include "content/public/browser/browser_thread.h"
29 #include "content/public/browser/navigation_details.h"
30 #include "content/public/browser/notification_registrar.h"
31 #include "content/public/browser/notification_service.h"
32 #include "content/public/browser/web_contents.h"
33 #include "content/public/test/mock_render_process_host.h"
34 #include "content/public/test/test_renderer_host.h"
35 #include "content/public/test/test_utils.h"
36 #include "content/public/test/web_contents_tester.h"
37 #include "testing/gtest/include/gtest/gtest.h"
39 #if defined(OS_ANDROID)
40 #include "base/prefs/pref_service.h"
41 #include "chrome/browser/android/mock_google_location_settings_helper.h"
42 #include "chrome/common/pref_names.h"
45 #if defined(ENABLE_EXTENSIONS)
46 #include "extensions/browser/view_type_utils.h"
49 using content::MockRenderProcessHost
;
52 // ClosedInfoBarTracker -------------------------------------------------------
54 // We need to track which infobars were closed.
55 class ClosedInfoBarTracker
: public content::NotificationObserver
{
57 ClosedInfoBarTracker();
58 virtual ~ClosedInfoBarTracker();
60 // content::NotificationObserver:
61 virtual void Observe(int type
,
62 const content::NotificationSource
& source
,
63 const content::NotificationDetails
& details
) OVERRIDE
;
65 size_t size() const { return removed_infobars_
.size(); }
67 bool Contains(infobars::InfoBar
* infobar
) const;
71 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests
, TabDestroyed
);
72 content::NotificationRegistrar registrar_
;
73 std::set
<infobars::InfoBar
*> removed_infobars_
;
76 ClosedInfoBarTracker::ClosedInfoBarTracker() {
77 registrar_
.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
,
78 content::NotificationService::AllSources());
81 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
84 void ClosedInfoBarTracker::Observe(
86 const content::NotificationSource
& source
,
87 const content::NotificationDetails
& details
) {
88 DCHECK(type
== chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
);
89 removed_infobars_
.insert(
90 content::Details
<infobars::InfoBar::RemovedDetails
>(details
)->first
);
93 bool ClosedInfoBarTracker::Contains(infobars::InfoBar
* infobar
) const {
94 return removed_infobars_
.count(infobar
) != 0;
97 void ClosedInfoBarTracker::Clear() {
98 removed_infobars_
.clear();
102 // GeolocationPermissionContextTests ------------------------------------------
104 class GeolocationPermissionContextTests
105 : public ChromeRenderViewHostTestHarness
{
107 // ChromeRenderViewHostTestHarness:
108 virtual void SetUp() OVERRIDE
;
109 virtual void TearDown() OVERRIDE
;
111 PermissionRequestID
RequestID(int bridge_id
);
112 PermissionRequestID
RequestIDForTab(int tab
, int bridge_id
);
113 InfoBarService
* infobar_service() {
114 return InfoBarService::FromWebContents(web_contents());
116 InfoBarService
* infobar_service_for_tab(int tab
) {
117 return InfoBarService::FromWebContents(extra_tabs_
[tab
]);
120 void RequestGeolocationPermission(content::WebContents
* web_contents
,
121 const PermissionRequestID
& id
,
122 const GURL
& requesting_frame
);
123 void RequestGeolocationPermission(content::WebContents
* web_contents
,
124 const PermissionRequestID
& id
,
125 const GURL
& requesting_frame
,
126 base::Closure
* cancel_callback
);
127 void PermissionResponse(const PermissionRequestID
& id
,
129 void CheckPermissionMessageSent(int bridge_id
, bool allowed
);
130 void CheckPermissionMessageSentForTab(int tab
, int bridge_id
, bool allowed
);
131 void CheckPermissionMessageSentInternal(MockRenderProcessHost
* process
,
134 void AddNewTab(const GURL
& url
);
135 void CheckTabContentsState(const GURL
& requesting_frame
,
136 ContentSetting expected_content_setting
);
138 scoped_refptr
<GeolocationPermissionContext
> geolocation_permission_context_
;
139 ClosedInfoBarTracker closed_infobar_tracker_
;
140 ScopedVector
<content::WebContents
> extra_tabs_
;
142 // A map between renderer child id and a pair represending the bridge id and
143 // whether the requested permission was allowed.
144 base::hash_map
<int, std::pair
<int, bool> > responses_
;
147 PermissionRequestID
GeolocationPermissionContextTests::RequestID(
149 return PermissionRequestID(
150 web_contents()->GetRenderProcessHost()->GetID(),
151 web_contents()->GetRenderViewHost()->GetRoutingID(),
156 PermissionRequestID
GeolocationPermissionContextTests::RequestIDForTab(
159 return PermissionRequestID(
160 extra_tabs_
[tab
]->GetRenderProcessHost()->GetID(),
161 extra_tabs_
[tab
]->GetRenderViewHost()->GetRoutingID(),
166 void GeolocationPermissionContextTests::RequestGeolocationPermission(
167 content::WebContents
* web_contents
,
168 const PermissionRequestID
& id
,
169 const GURL
& requesting_frame
) {
170 RequestGeolocationPermission(web_contents
, id
, requesting_frame
, NULL
);
173 void GeolocationPermissionContextTests::RequestGeolocationPermission(
174 content::WebContents
* web_contents
,
175 const PermissionRequestID
& id
,
176 const GURL
& requesting_frame
,
177 base::Closure
* cancel_callback
) {
178 geolocation_permission_context_
->RequestGeolocationPermission(
179 web_contents
, id
.bridge_id(), requesting_frame
, false,
180 base::Bind(&GeolocationPermissionContextTests::PermissionResponse
,
181 base::Unretained(this), id
),
183 content::RunAllBlockingPoolTasksUntilIdle();
186 void GeolocationPermissionContextTests::PermissionResponse(
187 const PermissionRequestID
& id
,
189 responses_
[id
.render_process_id()] = std::make_pair(id
.bridge_id(), allowed
);
192 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
195 CheckPermissionMessageSentInternal(process(), bridge_id
, allowed
);
198 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
202 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost
*>(
203 extra_tabs_
[tab
]->GetRenderProcessHost()),
207 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
208 MockRenderProcessHost
* process
,
211 ASSERT_EQ(responses_
.count(process
->GetID()), 1U);
212 EXPECT_EQ(bridge_id
, responses_
[process
->GetID()].first
);
213 EXPECT_EQ(allowed
, responses_
[process
->GetID()].second
);
214 responses_
.erase(process
->GetID());
217 void GeolocationPermissionContextTests::AddNewTab(const GURL
& url
) {
218 content::WebContents
* new_tab
= content::WebContents::Create(
219 content::WebContents::CreateParams(profile()));
220 new_tab
->GetController().LoadURL(
221 url
, content::Referrer(), content::PAGE_TRANSITION_TYPED
, std::string());
222 content::RenderViewHostTester::For(new_tab
->GetRenderViewHost())->
223 SendNavigate(extra_tabs_
.size() + 1, url
);
225 // Set up required helpers, and make this be as "tabby" as the code requires.
226 #if defined(ENABLE_EXTENSIONS)
227 extensions::SetViewType(new_tab
, extensions::VIEW_TYPE_TAB_CONTENTS
);
229 InfoBarService::CreateForWebContents(new_tab
);
231 extra_tabs_
.push_back(new_tab
);
234 void GeolocationPermissionContextTests::CheckTabContentsState(
235 const GURL
& requesting_frame
,
236 ContentSetting expected_content_setting
) {
237 TabSpecificContentSettings
* content_settings
=
238 TabSpecificContentSettings::FromWebContents(web_contents());
239 const ContentSettingsUsagesState::StateMap
& state_map
=
240 content_settings
->geolocation_usages_state().state_map();
241 EXPECT_EQ(1U, state_map
.count(requesting_frame
.GetOrigin()));
242 EXPECT_EQ(0U, state_map
.count(requesting_frame
));
243 ContentSettingsUsagesState::StateMap::const_iterator settings
=
244 state_map
.find(requesting_frame
.GetOrigin());
245 ASSERT_FALSE(settings
== state_map
.end())
246 << "geolocation state not found " << requesting_frame
;
247 EXPECT_EQ(expected_content_setting
, settings
->second
);
250 void GeolocationPermissionContextTests::SetUp() {
251 ChromeRenderViewHostTestHarness::SetUp();
253 // Set up required helpers, and make this be as "tabby" as the code requires.
254 #if defined(ENABLE_EXTENSIONS)
255 extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS
);
257 InfoBarService::CreateForWebContents(web_contents());
258 TabSpecificContentSettings::CreateForWebContents(web_contents());
259 #if defined(OS_ANDROID)
260 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
262 geolocation_permission_context_
=
263 GeolocationPermissionContextFactory::GetForProfile(profile());
266 void GeolocationPermissionContextTests::TearDown() {
268 ChromeRenderViewHostTestHarness::TearDown();
271 // Tests ----------------------------------------------------------------------
273 TEST_F(GeolocationPermissionContextTests
, SinglePermission
) {
274 GURL
requesting_frame("http://www.example.com/geolocation");
275 NavigateAndCommit(requesting_frame
);
276 EXPECT_EQ(0U, infobar_service()->infobar_count());
277 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
278 ASSERT_EQ(1U, infobar_service()->infobar_count());
279 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
280 ConfirmInfoBarDelegate
* infobar_delegate
=
281 infobar
->delegate()->AsConfirmInfoBarDelegate();
282 ASSERT_TRUE(infobar_delegate
);
283 infobar_delegate
->Cancel();
284 infobar_service()->RemoveInfoBar(infobar
);
285 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
286 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
289 #if defined(OS_ANDROID)
290 TEST_F(GeolocationPermissionContextTests
, GeolocationEnabledDisabled
) {
291 GURL
requesting_frame("http://www.example.com/geolocation");
292 NavigateAndCommit(requesting_frame
);
293 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
294 EXPECT_EQ(0U, infobar_service()->infobar_count());
295 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
296 EXPECT_EQ(1U, infobar_service()->infobar_count());
297 ConfirmInfoBarDelegate
* infobar_delegate_0
=
298 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
299 ASSERT_TRUE(infobar_delegate_0
);
300 base::string16 text_0
= infobar_delegate_0
->GetButtonLabel(
301 ConfirmInfoBarDelegate::BUTTON_OK
);
304 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
305 EXPECT_EQ(0U, infobar_service()->infobar_count());
306 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
307 EXPECT_EQ(0U, infobar_service()->infobar_count());
310 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsEnabled
) {
311 GURL
requesting_frame("http://www.example.com/geolocation");
312 NavigateAndCommit(requesting_frame
);
313 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
314 EXPECT_EQ(0U, infobar_service()->infobar_count());
315 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
316 EXPECT_EQ(1U, infobar_service()->infobar_count());
317 ConfirmInfoBarDelegate
* infobar_delegate
=
318 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
319 ASSERT_TRUE(infobar_delegate
);
320 infobar_delegate
->Accept();
321 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
322 CheckPermissionMessageSent(0, true);
325 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsDisabled
) {
326 GURL
requesting_frame("http://www.example.com/geolocation");
327 NavigateAndCommit(requesting_frame
);
328 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
329 EXPECT_EQ(0U, infobar_service()->infobar_count());
330 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
331 EXPECT_EQ(0U, infobar_service()->infobar_count());
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(
351 web_contents(), RequestID(0), requesting_frame_0
);
352 RequestGeolocationPermission(
353 web_contents(), RequestID(1), requesting_frame_1
);
354 // Ensure only one infobar is created.
355 ASSERT_EQ(1U, infobar_service()->infobar_count());
356 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
357 ConfirmInfoBarDelegate
* infobar_delegate_0
=
358 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
359 ASSERT_TRUE(infobar_delegate_0
);
360 base::string16 text_0
= infobar_delegate_0
->GetMessageText();
362 // Accept the first frame.
363 infobar_delegate_0
->Accept();
364 CheckTabContentsState(requesting_frame_0
, CONTENT_SETTING_ALLOW
);
365 CheckPermissionMessageSent(0, true);
367 infobar_service()->RemoveInfoBar(infobar_0
);
368 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
369 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
370 closed_infobar_tracker_
.Clear();
371 // Now we should have a new infobar for the second frame.
372 ASSERT_EQ(1U, infobar_service()->infobar_count());
374 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
375 ConfirmInfoBarDelegate
* infobar_delegate_1
=
376 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
377 ASSERT_TRUE(infobar_delegate_1
);
378 base::string16 text_1
= infobar_delegate_1
->GetMessageText();
379 EXPECT_NE(text_0
, text_1
);
381 // Cancel (block) this frame.
382 infobar_delegate_1
->Cancel();
383 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_BLOCK
);
384 CheckPermissionMessageSent(1, false);
385 infobar_service()->RemoveInfoBar(infobar_1
);
386 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
387 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
388 EXPECT_EQ(0U, infobar_service()->infobar_count());
389 // Ensure the persisted permissions are ok.
390 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
391 profile()->GetHostContentSettingsMap()->GetContentSetting(
392 requesting_frame_0
, requesting_frame_0
,
393 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
395 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
396 profile()->GetHostContentSettingsMap()->GetContentSetting(
397 requesting_frame_1
, requesting_frame_0
,
398 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
401 TEST_F(GeolocationPermissionContextTests
, HashIsIgnored
) {
402 GURL
url_a("http://www.example.com/geolocation#a");
403 GURL
url_b("http://www.example.com/geolocation#b");
405 // Navigate to the first url and check permission is requested.
406 NavigateAndCommit(url_a
);
407 EXPECT_EQ(0U, infobar_service()->infobar_count());
408 RequestGeolocationPermission(web_contents(), RequestID(0), url_a
);
409 ASSERT_EQ(1U, infobar_service()->infobar_count());
410 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
411 ConfirmInfoBarDelegate
* infobar_delegate
=
412 infobar
->delegate()->AsConfirmInfoBarDelegate();
413 ASSERT_TRUE(infobar_delegate
);
415 // Change the hash, we'll still be on the same page.
416 NavigateAndCommit(url_b
);
419 infobar_delegate
->Accept();
420 CheckTabContentsState(url_a
, CONTENT_SETTING_ALLOW
);
421 CheckTabContentsState(url_b
, CONTENT_SETTING_ALLOW
);
422 CheckPermissionMessageSent(0, true);
425 infobar_service()->RemoveInfoBar(infobar
);
426 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
427 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
430 TEST_F(GeolocationPermissionContextTests
, PermissionForFileScheme
) {
431 GURL
requesting_frame("file://example/geolocation.html");
432 NavigateAndCommit(requesting_frame
);
433 EXPECT_EQ(0U, infobar_service()->infobar_count());
434 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
435 EXPECT_EQ(1U, infobar_service()->infobar_count());
436 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
437 ConfirmInfoBarDelegate
* infobar_delegate
=
438 infobar
->delegate()->AsConfirmInfoBarDelegate();
439 ASSERT_TRUE(infobar_delegate
);
441 infobar_delegate
->Accept();
442 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
443 CheckPermissionMessageSent(0, true);
444 infobar_service()->RemoveInfoBar(infobar
);
446 // Make sure the setting is not stored.
447 EXPECT_EQ(CONTENT_SETTING_ASK
,
448 profile()->GetHostContentSettingsMap()->GetContentSetting(
451 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
455 TEST_F(GeolocationPermissionContextTests
, CancelGeolocationPermissionRequest
) {
456 GURL
requesting_frame_0("http://www.example.com/geolocation");
457 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
458 EXPECT_EQ(CONTENT_SETTING_ASK
,
459 profile()->GetHostContentSettingsMap()->GetContentSetting(
460 requesting_frame_0
, requesting_frame_0
,
461 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
463 EXPECT_EQ(CONTENT_SETTING_ASK
,
464 profile()->GetHostContentSettingsMap()->GetContentSetting(
465 requesting_frame_1
, requesting_frame_0
,
466 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
468 NavigateAndCommit(requesting_frame_0
);
469 EXPECT_EQ(0U, infobar_service()->infobar_count());
470 // Request permission for two frames.
471 base::Closure cancel_callback
;
472 RequestGeolocationPermission(
473 web_contents(), RequestID(0), requesting_frame_0
, &cancel_callback
);
474 RequestGeolocationPermission(
475 web_contents(), RequestID(1), requesting_frame_1
);
476 ASSERT_EQ(1U, infobar_service()->infobar_count());
478 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
479 ConfirmInfoBarDelegate
* infobar_delegate_0
=
480 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
481 ASSERT_TRUE(infobar_delegate_0
);
482 base::string16 text_0
= infobar_delegate_0
->GetMessageText();
484 // Simulate the frame going away, ensure the infobar for this frame
485 // is removed and the next pending infobar is created.
486 cancel_callback
.Run();
487 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
488 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
489 closed_infobar_tracker_
.Clear();
490 ASSERT_EQ(1U, infobar_service()->infobar_count());
492 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
493 ConfirmInfoBarDelegate
* infobar_delegate_1
=
494 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
495 ASSERT_TRUE(infobar_delegate_1
);
496 base::string16 text_1
= infobar_delegate_1
->GetMessageText();
497 EXPECT_NE(text_0
, text_1
);
500 infobar_delegate_1
->Accept();
501 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_ALLOW
);
502 CheckPermissionMessageSent(1, true);
503 infobar_service()->RemoveInfoBar(infobar_1
);
504 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
505 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
506 EXPECT_EQ(0U, infobar_service()->infobar_count());
507 // Ensure the persisted permissions are ok.
508 EXPECT_EQ(CONTENT_SETTING_ASK
,
509 profile()->GetHostContentSettingsMap()->GetContentSetting(
510 requesting_frame_0
, requesting_frame_0
,
511 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
513 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
514 profile()->GetHostContentSettingsMap()->GetContentSetting(
515 requesting_frame_1
, requesting_frame_0
,
516 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
519 TEST_F(GeolocationPermissionContextTests
, InvalidURL
) {
520 GURL
invalid_embedder("about:blank");
521 GURL requesting_frame
;
522 NavigateAndCommit(invalid_embedder
);
523 EXPECT_EQ(0U, infobar_service()->infobar_count());
524 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
525 EXPECT_EQ(0U, infobar_service()->infobar_count());
526 CheckPermissionMessageSent(0, false);
529 TEST_F(GeolocationPermissionContextTests
, SameOriginMultipleTabs
) {
530 GURL
url_a("http://www.example.com/geolocation");
531 GURL
url_b("http://www.example-2.com/geolocation");
532 NavigateAndCommit(url_a
);
536 EXPECT_EQ(0U, infobar_service()->infobar_count());
537 RequestGeolocationPermission(web_contents(), RequestID(0), url_a
);
538 ASSERT_EQ(1U, infobar_service()->infobar_count());
540 RequestGeolocationPermission(extra_tabs_
[0], RequestIDForTab(0, 0), url_b
);
541 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
543 RequestGeolocationPermission(extra_tabs_
[1], RequestIDForTab(1, 0), url_a
);
544 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
546 infobars::InfoBar
* removed_infobar
=
547 infobar_service_for_tab(1)->infobar_at(0);
549 // Accept the first tab.
550 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
551 ConfirmInfoBarDelegate
* infobar_delegate_0
=
552 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
553 ASSERT_TRUE(infobar_delegate_0
);
554 infobar_delegate_0
->Accept();
555 CheckPermissionMessageSent(0, true);
556 infobar_service()->RemoveInfoBar(infobar_0
);
557 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
558 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
559 // Now the infobar for the tab with the same origin should have gone.
560 EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
561 CheckPermissionMessageSentForTab(1, 0, true);
562 EXPECT_TRUE(closed_infobar_tracker_
.Contains(removed_infobar
));
563 closed_infobar_tracker_
.Clear();
565 // But the other tab should still have the info bar...
566 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
567 infobars::InfoBar
* infobar_1
= infobar_service_for_tab(0)->infobar_at(0);
568 ConfirmInfoBarDelegate
* infobar_delegate_1
=
569 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
570 ASSERT_TRUE(infobar_delegate_1
);
571 infobar_delegate_1
->Cancel();
572 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1
);
573 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
574 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
577 TEST_F(GeolocationPermissionContextTests
, QueuedOriginMultipleTabs
) {
578 GURL
url_a("http://www.example.com/geolocation");
579 GURL
url_b("http://www.example-2.com/geolocation");
580 NavigateAndCommit(url_a
);
583 EXPECT_EQ(0U, infobar_service()->infobar_count());
584 RequestGeolocationPermission(web_contents(), RequestID(0), url_a
);
585 ASSERT_EQ(1U, infobar_service()->infobar_count());
587 RequestGeolocationPermission(extra_tabs_
[0], RequestIDForTab(0, 0), url_a
);
588 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
590 RequestGeolocationPermission(extra_tabs_
[0], RequestIDForTab(0, 1), url_b
);
591 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
593 infobars::InfoBar
* removed_infobar
= infobar_service()->infobar_at(0);
595 // Accept the second tab.
596 infobars::InfoBar
* infobar_0
= infobar_service_for_tab(0)->infobar_at(0);
597 ConfirmInfoBarDelegate
* infobar_delegate_0
=
598 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
599 ASSERT_TRUE(infobar_delegate_0
);
600 infobar_delegate_0
->Accept();
601 CheckPermissionMessageSentForTab(0, 0, true);
602 infobar_service_for_tab(0)->RemoveInfoBar(infobar_0
);
603 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
604 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
605 // Now the infobar for the tab with the same origin should have gone.
606 EXPECT_EQ(0U, infobar_service()->infobar_count());
607 CheckPermissionMessageSent(0, true);
608 EXPECT_TRUE(closed_infobar_tracker_
.Contains(removed_infobar
));
609 closed_infobar_tracker_
.Clear();
611 // And we should have the queued infobar displayed now.
612 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
614 // Accept the second infobar.
615 infobars::InfoBar
* infobar_1
= infobar_service_for_tab(0)->infobar_at(0);
616 ConfirmInfoBarDelegate
* infobar_delegate_1
=
617 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
618 ASSERT_TRUE(infobar_delegate_1
);
619 infobar_delegate_1
->Accept();
620 CheckPermissionMessageSentForTab(0, 1, true);
621 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1
);
622 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
623 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
626 TEST_F(GeolocationPermissionContextTests
, TabDestroyed
) {
627 GURL
requesting_frame_0("http://www.example.com/geolocation");
628 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
629 EXPECT_EQ(CONTENT_SETTING_ASK
,
630 profile()->GetHostContentSettingsMap()->GetContentSetting(
631 requesting_frame_0
, requesting_frame_0
,
632 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
634 EXPECT_EQ(CONTENT_SETTING_ASK
,
635 profile()->GetHostContentSettingsMap()->GetContentSetting(
636 requesting_frame_1
, requesting_frame_0
,
637 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
639 NavigateAndCommit(requesting_frame_0
);
640 EXPECT_EQ(0U, infobar_service()->infobar_count());
641 // Request permission for two frames.
642 RequestGeolocationPermission(
643 web_contents(), RequestID(0), requesting_frame_0
);
644 RequestGeolocationPermission(
645 web_contents(), 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(
670 web_contents(), RequestID(0), requesting_frame_1
);
671 // Ensure the infobar is created.
672 ASSERT_EQ(1U, infobar_service()->infobar_count());
673 infobars::InfoBarDelegate
* infobar_delegate
=
674 infobar_service()->infobar_at(0)->delegate();
675 ASSERT_TRUE(infobar_delegate
);
676 // Ensure the infobar wouldn't expire for a navigation to the committed entry.
677 content::LoadCommittedDetails details
;
678 details
.entry
= web_contents()->GetController().GetLastCommittedEntry();
679 EXPECT_FALSE(infobar_delegate
->ShouldExpire(
680 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details
)));
681 // Ensure the infobar will expire when we commit the pending navigation.
682 details
.entry
= web_contents()->GetController().GetActiveEntry();
683 EXPECT_TRUE(infobar_delegate
->ShouldExpire(
684 InfoBarService::NavigationDetailsFromLoadCommittedDetails(details
)));
686 // Delete the tab contents.
690 TEST_F(GeolocationPermissionContextTests
, LastUsageAudited
) {
691 GURL
requesting_frame("http://www.example.com/geolocation");
692 NavigateAndCommit(requesting_frame
);
694 base::SimpleTestClock
* test_clock
= new base::SimpleTestClock
;
695 test_clock
->SetNow(base::Time::UnixEpoch() +
696 base::TimeDelta::FromSeconds(10));
698 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
699 map
->SetPrefClockForTesting(scoped_ptr
<base::Clock
>(test_clock
));
701 // The permission shouldn't have been used yet.
702 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
703 requesting_frame
.GetOrigin(),
704 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
707 EXPECT_EQ(0U, infobar_service()->infobar_count());
708 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
709 ASSERT_EQ(1U, infobar_service()->infobar_count());
710 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
711 ConfirmInfoBarDelegate
* infobar_delegate
=
712 infobar
->delegate()->AsConfirmInfoBarDelegate();
713 ASSERT_TRUE(infobar_delegate
);
714 infobar_delegate
->Accept();
715 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
716 CheckPermissionMessageSent(0, true);
718 // Permission has been used at the starting time.
719 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
720 requesting_frame
.GetOrigin(),
721 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
724 test_clock
->Advance(base::TimeDelta::FromSeconds(3));
725 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
727 // Permission has been used three seconds later.
728 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
729 requesting_frame
.GetOrigin(),
730 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
734 TEST_F(GeolocationPermissionContextTests
, LastUsageAuditedMultipleFrames
) {
735 base::SimpleTestClock
* test_clock
= new base::SimpleTestClock
;
736 test_clock
->SetNow(base::Time::UnixEpoch() +
737 base::TimeDelta::FromSeconds(10));
739 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
740 map
->SetPrefClockForTesting(scoped_ptr
<base::Clock
>(test_clock
));
742 GURL
requesting_frame_0("http://www.example.com/geolocation");
743 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
745 // The permission shouldn't have been used yet.
746 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
747 requesting_frame_0
.GetOrigin(),
748 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
750 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
751 requesting_frame_0
.GetOrigin(),
752 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
755 NavigateAndCommit(requesting_frame_0
);
756 EXPECT_EQ(0U, infobar_service()->infobar_count());
758 // Request permission for two frames.
759 RequestGeolocationPermission(
760 web_contents(), RequestID(0), requesting_frame_0
);
761 RequestGeolocationPermission(
762 web_contents(), RequestID(1), requesting_frame_1
);
764 // Ensure only one infobar is created.
765 ASSERT_EQ(1U, infobar_service()->infobar_count());
766 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
767 ConfirmInfoBarDelegate
* infobar_delegate_0
=
768 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
770 // Accept the first frame.
771 infobar_delegate_0
->Accept();
772 CheckTabContentsState(requesting_frame_0
, CONTENT_SETTING_ALLOW
);
773 CheckPermissionMessageSent(0, true);
774 infobar_service()->RemoveInfoBar(infobar_0
);
776 // Verify that accepting the first didn't accept because it's embedder
778 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
779 requesting_frame_0
.GetOrigin(),
780 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
782 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
783 requesting_frame_0
.GetOrigin(),
784 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
787 ASSERT_EQ(1U, infobar_service()->infobar_count());
788 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
789 ConfirmInfoBarDelegate
* infobar_delegate_1
=
790 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
792 test_clock
->Advance(base::TimeDelta::FromSeconds(1));
794 // Allow the second frame.
795 infobar_delegate_1
->Accept();
796 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_ALLOW
);
797 CheckPermissionMessageSent(1, true);
798 infobar_service()->RemoveInfoBar(infobar_1
);
800 // Verify that the times are different.
801 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
802 requesting_frame_0
.GetOrigin(),
803 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
805 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
806 requesting_frame_0
.GetOrigin(),
807 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
810 test_clock
->Advance(base::TimeDelta::FromSeconds(2));
811 RequestGeolocationPermission(
812 web_contents(), RequestID(0), requesting_frame_0
);
814 // Verify that requesting permission in one frame doesn't update other where
815 // it is the embedder.
816 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
817 requesting_frame_0
.GetOrigin(),
818 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
820 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
821 requesting_frame_0
.GetOrigin(),
822 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),