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/tab_specific_content_settings.h"
21 #include "chrome/browser/geolocation/geolocation_permission_context_factory.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/content_settings/core/common/permission_request_id.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_observer.h"
31 #include "content/public/browser/notification_registrar.h"
32 #include "content/public/browser/notification_service.h"
33 #include "content/public/browser/web_contents.h"
34 #include "content/public/test/mock_render_process_host.h"
35 #include "content/public/test/test_renderer_host.h"
36 #include "content/public/test/test_utils.h"
37 #include "content/public/test/web_contents_tester.h"
38 #include "testing/gtest/include/gtest/gtest.h"
40 #if defined(OS_ANDROID)
41 #include "base/prefs/pref_service.h"
42 #include "chrome/browser/android/mock_google_location_settings_helper.h"
43 #include "chrome/common/pref_names.h"
46 #if defined(ENABLE_EXTENSIONS)
47 #include "extensions/browser/view_type_utils.h"
50 using content::MockRenderProcessHost
;
53 // ClosedInfoBarTracker -------------------------------------------------------
55 // We need to track which infobars were closed.
56 class ClosedInfoBarTracker
: public content::NotificationObserver
{
58 ClosedInfoBarTracker();
59 virtual ~ClosedInfoBarTracker();
61 // content::NotificationObserver:
62 virtual void Observe(int type
,
63 const content::NotificationSource
& source
,
64 const content::NotificationDetails
& details
) override
;
66 size_t size() const { return removed_infobars_
.size(); }
68 bool Contains(infobars::InfoBar
* infobar
) const;
72 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests
, TabDestroyed
);
73 content::NotificationRegistrar registrar_
;
74 std::set
<infobars::InfoBar
*> removed_infobars_
;
77 ClosedInfoBarTracker::ClosedInfoBarTracker() {
78 registrar_
.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
,
79 content::NotificationService::AllSources());
82 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
85 void ClosedInfoBarTracker::Observe(
87 const content::NotificationSource
& source
,
88 const content::NotificationDetails
& details
) {
89 DCHECK(type
== chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
);
90 removed_infobars_
.insert(
91 content::Details
<infobars::InfoBar::RemovedDetails
>(details
)->first
);
94 bool ClosedInfoBarTracker::Contains(infobars::InfoBar
* infobar
) const {
95 return removed_infobars_
.count(infobar
) != 0;
98 void ClosedInfoBarTracker::Clear() {
99 removed_infobars_
.clear();
103 // GeolocationPermissionContextTests ------------------------------------------
105 class GeolocationPermissionContextTests
106 : public ChromeRenderViewHostTestHarness
{
108 // ChromeRenderViewHostTestHarness:
109 virtual void SetUp() override
;
110 virtual void TearDown() override
;
112 PermissionRequestID
RequestID(int bridge_id
);
113 PermissionRequestID
RequestIDForTab(int tab
, int bridge_id
);
114 InfoBarService
* infobar_service() {
115 return InfoBarService::FromWebContents(web_contents());
117 InfoBarService
* infobar_service_for_tab(int tab
) {
118 return InfoBarService::FromWebContents(extra_tabs_
[tab
]);
121 void RequestGeolocationPermission(content::WebContents
* web_contents
,
122 const PermissionRequestID
& id
,
123 const GURL
& requesting_frame
);
125 void PermissionResponse(const PermissionRequestID
& id
,
127 void CheckPermissionMessageSent(int bridge_id
, bool allowed
);
128 void CheckPermissionMessageSentForTab(int tab
, int bridge_id
, bool allowed
);
129 void CheckPermissionMessageSentInternal(MockRenderProcessHost
* process
,
132 void AddNewTab(const GURL
& url
);
133 void CheckTabContentsState(const GURL
& requesting_frame
,
134 ContentSetting expected_content_setting
);
136 // owned by the browser context
137 GeolocationPermissionContext
* geolocation_permission_context_
;
138 ClosedInfoBarTracker closed_infobar_tracker_
;
139 ScopedVector
<content::WebContents
> extra_tabs_
;
141 // A map between renderer child id and a pair represending the bridge id and
142 // whether the requested permission was allowed.
143 base::hash_map
<int, std::pair
<int, bool> > responses_
;
146 PermissionRequestID
GeolocationPermissionContextTests::RequestID(
148 return PermissionRequestID(
149 web_contents()->GetRenderProcessHost()->GetID(),
150 web_contents()->GetRenderViewHost()->GetRoutingID(),
155 PermissionRequestID
GeolocationPermissionContextTests::RequestIDForTab(
158 return PermissionRequestID(
159 extra_tabs_
[tab
]->GetRenderProcessHost()->GetID(),
160 extra_tabs_
[tab
]->GetRenderViewHost()->GetRoutingID(),
165 void GeolocationPermissionContextTests::RequestGeolocationPermission(
166 content::WebContents
* web_contents
,
167 const PermissionRequestID
& id
,
168 const GURL
& requesting_frame
) {
169 geolocation_permission_context_
->RequestPermission(
170 web_contents
, id
, requesting_frame
, false,
171 base::Bind(&GeolocationPermissionContextTests::PermissionResponse
,
172 base::Unretained(this), id
));
173 content::RunAllBlockingPoolTasksUntilIdle();
176 void GeolocationPermissionContextTests::PermissionResponse(
177 const PermissionRequestID
& id
,
179 responses_
[id
.render_process_id()] = std::make_pair(id
.bridge_id(), allowed
);
182 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
185 CheckPermissionMessageSentInternal(process(), bridge_id
, allowed
);
188 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
192 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost
*>(
193 extra_tabs_
[tab
]->GetRenderProcessHost()),
197 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
198 MockRenderProcessHost
* process
,
201 ASSERT_EQ(responses_
.count(process
->GetID()), 1U);
202 EXPECT_EQ(bridge_id
, responses_
[process
->GetID()].first
);
203 EXPECT_EQ(allowed
, responses_
[process
->GetID()].second
);
204 responses_
.erase(process
->GetID());
207 void GeolocationPermissionContextTests::AddNewTab(const GURL
& url
) {
208 content::WebContents
* new_tab
= content::WebContents::Create(
209 content::WebContents::CreateParams(profile()));
210 new_tab
->GetController().LoadURL(
211 url
, content::Referrer(), ui::PAGE_TRANSITION_TYPED
, std::string());
212 content::RenderFrameHostTester::For(new_tab
->GetMainFrame())
213 ->SendNavigate(extra_tabs_
.size() + 1, url
);
215 // Set up required helpers, and make this be as "tabby" as the code requires.
216 #if defined(ENABLE_EXTENSIONS)
217 extensions::SetViewType(new_tab
, extensions::VIEW_TYPE_TAB_CONTENTS
);
219 InfoBarService::CreateForWebContents(new_tab
);
221 extra_tabs_
.push_back(new_tab
);
224 void GeolocationPermissionContextTests::CheckTabContentsState(
225 const GURL
& requesting_frame
,
226 ContentSetting expected_content_setting
) {
227 TabSpecificContentSettings
* content_settings
=
228 TabSpecificContentSettings::FromWebContents(web_contents());
229 const ContentSettingsUsagesState::StateMap
& state_map
=
230 content_settings
->geolocation_usages_state().state_map();
231 EXPECT_EQ(1U, state_map
.count(requesting_frame
.GetOrigin()));
232 EXPECT_EQ(0U, state_map
.count(requesting_frame
));
233 ContentSettingsUsagesState::StateMap::const_iterator settings
=
234 state_map
.find(requesting_frame
.GetOrigin());
235 ASSERT_FALSE(settings
== state_map
.end())
236 << "geolocation state not found " << requesting_frame
;
237 EXPECT_EQ(expected_content_setting
, settings
->second
);
240 void GeolocationPermissionContextTests::SetUp() {
241 ChromeRenderViewHostTestHarness::SetUp();
243 // Set up required helpers, and make this be as "tabby" as the code requires.
244 #if defined(ENABLE_EXTENSIONS)
245 extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS
);
247 InfoBarService::CreateForWebContents(web_contents());
248 TabSpecificContentSettings::CreateForWebContents(web_contents());
249 #if defined(OS_ANDROID)
250 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
252 geolocation_permission_context_
=
253 GeolocationPermissionContextFactory::GetForProfile(profile());
256 void GeolocationPermissionContextTests::TearDown() {
258 ChromeRenderViewHostTestHarness::TearDown();
261 // Tests ----------------------------------------------------------------------
263 TEST_F(GeolocationPermissionContextTests
, SinglePermission
) {
264 GURL
requesting_frame("http://www.example.com/geolocation");
265 NavigateAndCommit(requesting_frame
);
266 EXPECT_EQ(0U, infobar_service()->infobar_count());
267 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
268 ASSERT_EQ(1U, infobar_service()->infobar_count());
269 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
270 ConfirmInfoBarDelegate
* infobar_delegate
=
271 infobar
->delegate()->AsConfirmInfoBarDelegate();
272 ASSERT_TRUE(infobar_delegate
);
273 infobar_delegate
->Cancel();
274 infobar_service()->RemoveInfoBar(infobar
);
275 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
276 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
279 #if defined(OS_ANDROID)
280 TEST_F(GeolocationPermissionContextTests
, GeolocationEnabledDisabled
) {
281 GURL
requesting_frame("http://www.example.com/geolocation");
282 NavigateAndCommit(requesting_frame
);
283 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
284 EXPECT_EQ(0U, infobar_service()->infobar_count());
285 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
286 EXPECT_EQ(1U, infobar_service()->infobar_count());
287 ConfirmInfoBarDelegate
* infobar_delegate_0
=
288 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
289 ASSERT_TRUE(infobar_delegate_0
);
290 base::string16 text_0
= infobar_delegate_0
->GetButtonLabel(
291 ConfirmInfoBarDelegate::BUTTON_OK
);
294 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
295 EXPECT_EQ(0U, infobar_service()->infobar_count());
296 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
297 EXPECT_EQ(0U, infobar_service()->infobar_count());
300 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsEnabled
) {
301 GURL
requesting_frame("http://www.example.com/geolocation");
302 NavigateAndCommit(requesting_frame
);
303 MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
304 EXPECT_EQ(0U, infobar_service()->infobar_count());
305 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
306 EXPECT_EQ(1U, infobar_service()->infobar_count());
307 ConfirmInfoBarDelegate
* infobar_delegate
=
308 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
309 ASSERT_TRUE(infobar_delegate
);
310 infobar_delegate
->Accept();
311 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
312 CheckPermissionMessageSent(0, true);
315 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsDisabled
) {
316 GURL
requesting_frame("http://www.example.com/geolocation");
317 NavigateAndCommit(requesting_frame
);
318 MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
319 EXPECT_EQ(0U, infobar_service()->infobar_count());
320 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
321 EXPECT_EQ(0U, infobar_service()->infobar_count());
325 TEST_F(GeolocationPermissionContextTests
, QueuedPermission
) {
326 GURL
requesting_frame_0("http://www.example.com/geolocation");
327 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
328 EXPECT_EQ(CONTENT_SETTING_ASK
,
329 profile()->GetHostContentSettingsMap()->GetContentSetting(
330 requesting_frame_0
, requesting_frame_0
,
331 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
332 EXPECT_EQ(CONTENT_SETTING_ASK
,
333 profile()->GetHostContentSettingsMap()->GetContentSetting(
334 requesting_frame_1
, requesting_frame_0
,
335 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
337 NavigateAndCommit(requesting_frame_0
);
338 EXPECT_EQ(0U, infobar_service()->infobar_count());
339 // Request permission for two frames.
340 RequestGeolocationPermission(
341 web_contents(), RequestID(0), requesting_frame_0
);
342 RequestGeolocationPermission(
343 web_contents(), RequestID(1), requesting_frame_1
);
344 // Ensure only one infobar is created.
345 ASSERT_EQ(1U, infobar_service()->infobar_count());
346 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
347 ConfirmInfoBarDelegate
* infobar_delegate_0
=
348 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
349 ASSERT_TRUE(infobar_delegate_0
);
350 base::string16 text_0
= infobar_delegate_0
->GetMessageText();
352 // Accept the first frame.
353 infobar_delegate_0
->Accept();
354 CheckTabContentsState(requesting_frame_0
, CONTENT_SETTING_ALLOW
);
355 CheckPermissionMessageSent(0, true);
357 infobar_service()->RemoveInfoBar(infobar_0
);
358 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
359 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
360 closed_infobar_tracker_
.Clear();
361 // Now we should have a new infobar for the second frame.
362 ASSERT_EQ(1U, infobar_service()->infobar_count());
364 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
365 ConfirmInfoBarDelegate
* infobar_delegate_1
=
366 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
367 ASSERT_TRUE(infobar_delegate_1
);
368 base::string16 text_1
= infobar_delegate_1
->GetMessageText();
369 EXPECT_NE(text_0
, text_1
);
371 // Cancel (block) this frame.
372 infobar_delegate_1
->Cancel();
373 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_BLOCK
);
374 CheckPermissionMessageSent(1, false);
375 infobar_service()->RemoveInfoBar(infobar_1
);
376 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
377 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
378 EXPECT_EQ(0U, infobar_service()->infobar_count());
379 // Ensure the persisted permissions are ok.
380 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
381 profile()->GetHostContentSettingsMap()->GetContentSetting(
382 requesting_frame_0
, requesting_frame_0
,
383 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
385 EXPECT_EQ(CONTENT_SETTING_BLOCK
,
386 profile()->GetHostContentSettingsMap()->GetContentSetting(
387 requesting_frame_1
, requesting_frame_0
,
388 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
391 TEST_F(GeolocationPermissionContextTests
, HashIsIgnored
) {
392 GURL
url_a("http://www.example.com/geolocation#a");
393 GURL
url_b("http://www.example.com/geolocation#b");
395 // Navigate to the first url and check permission is requested.
396 NavigateAndCommit(url_a
);
397 EXPECT_EQ(0U, infobar_service()->infobar_count());
398 RequestGeolocationPermission(web_contents(), RequestID(0), url_a
);
399 ASSERT_EQ(1U, infobar_service()->infobar_count());
400 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
401 ConfirmInfoBarDelegate
* infobar_delegate
=
402 infobar
->delegate()->AsConfirmInfoBarDelegate();
403 ASSERT_TRUE(infobar_delegate
);
405 // Change the hash, we'll still be on the same page.
406 NavigateAndCommit(url_b
);
409 infobar_delegate
->Accept();
410 CheckTabContentsState(url_a
, CONTENT_SETTING_ALLOW
);
411 CheckTabContentsState(url_b
, CONTENT_SETTING_ALLOW
);
412 CheckPermissionMessageSent(0, true);
415 infobar_service()->RemoveInfoBar(infobar
);
416 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
417 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
420 TEST_F(GeolocationPermissionContextTests
, PermissionForFileScheme
) {
421 GURL
requesting_frame("file://example/geolocation.html");
422 NavigateAndCommit(requesting_frame
);
423 EXPECT_EQ(0U, infobar_service()->infobar_count());
424 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
425 EXPECT_EQ(1U, infobar_service()->infobar_count());
426 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
427 ConfirmInfoBarDelegate
* infobar_delegate
=
428 infobar
->delegate()->AsConfirmInfoBarDelegate();
429 ASSERT_TRUE(infobar_delegate
);
431 infobar_delegate
->Accept();
432 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
433 CheckPermissionMessageSent(0, true);
434 infobar_service()->RemoveInfoBar(infobar
);
436 // Make sure the setting is not stored.
437 EXPECT_EQ(CONTENT_SETTING_ASK
,
438 profile()->GetHostContentSettingsMap()->GetContentSetting(
441 CONTENT_SETTINGS_TYPE_GEOLOCATION
,
445 TEST_F(GeolocationPermissionContextTests
, CancelGeolocationPermissionRequest
) {
446 GURL
requesting_frame_0("http://www.example.com/geolocation");
447 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
448 EXPECT_EQ(CONTENT_SETTING_ASK
,
449 profile()->GetHostContentSettingsMap()->GetContentSetting(
450 requesting_frame_0
, requesting_frame_0
,
451 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
453 EXPECT_EQ(CONTENT_SETTING_ASK
,
454 profile()->GetHostContentSettingsMap()->GetContentSetting(
455 requesting_frame_1
, requesting_frame_0
,
456 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
458 NavigateAndCommit(requesting_frame_0
);
459 EXPECT_EQ(0U, infobar_service()->infobar_count());
461 // Request permission for two frames.
462 RequestGeolocationPermission(
463 web_contents(), RequestID(0), requesting_frame_0
);
464 RequestGeolocationPermission(
465 web_contents(), RequestID(1), requesting_frame_1
);
466 ASSERT_EQ(1U, infobar_service()->infobar_count());
468 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
469 ConfirmInfoBarDelegate
* infobar_delegate_0
=
470 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
471 ASSERT_TRUE(infobar_delegate_0
);
472 base::string16 text_0
= infobar_delegate_0
->GetMessageText();
474 // Simulate the frame going away, ensure the infobar for this frame
475 // is removed and the next pending infobar is created.
476 geolocation_permission_context_
->CancelPermissionRequest(web_contents(),
478 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
479 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
480 closed_infobar_tracker_
.Clear();
481 ASSERT_EQ(1U, infobar_service()->infobar_count());
483 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
484 ConfirmInfoBarDelegate
* infobar_delegate_1
=
485 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
486 ASSERT_TRUE(infobar_delegate_1
);
487 base::string16 text_1
= infobar_delegate_1
->GetMessageText();
488 EXPECT_NE(text_0
, text_1
);
491 infobar_delegate_1
->Accept();
492 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_ALLOW
);
493 CheckPermissionMessageSent(1, true);
494 infobar_service()->RemoveInfoBar(infobar_1
);
495 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
496 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
497 EXPECT_EQ(0U, infobar_service()->infobar_count());
498 // Ensure the persisted permissions are ok.
499 EXPECT_EQ(CONTENT_SETTING_ASK
,
500 profile()->GetHostContentSettingsMap()->GetContentSetting(
501 requesting_frame_0
, requesting_frame_0
,
502 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
504 EXPECT_EQ(CONTENT_SETTING_ALLOW
,
505 profile()->GetHostContentSettingsMap()->GetContentSetting(
506 requesting_frame_1
, requesting_frame_0
,
507 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
510 TEST_F(GeolocationPermissionContextTests
, InvalidURL
) {
511 GURL
invalid_embedder("about:blank");
512 GURL requesting_frame
;
513 NavigateAndCommit(invalid_embedder
);
514 EXPECT_EQ(0U, infobar_service()->infobar_count());
515 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
516 EXPECT_EQ(0U, infobar_service()->infobar_count());
517 CheckPermissionMessageSent(0, false);
520 TEST_F(GeolocationPermissionContextTests
, SameOriginMultipleTabs
) {
521 GURL
url_a("http://www.example.com/geolocation");
522 GURL
url_b("http://www.example-2.com/geolocation");
523 NavigateAndCommit(url_a
);
527 EXPECT_EQ(0U, infobar_service()->infobar_count());
528 RequestGeolocationPermission(web_contents(), RequestID(0), url_a
);
529 ASSERT_EQ(1U, infobar_service()->infobar_count());
531 RequestGeolocationPermission(extra_tabs_
[0], RequestIDForTab(0, 0), url_b
);
532 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
534 RequestGeolocationPermission(extra_tabs_
[1], RequestIDForTab(1, 0), url_a
);
535 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
537 infobars::InfoBar
* removed_infobar
=
538 infobar_service_for_tab(1)->infobar_at(0);
540 // Accept the first tab.
541 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
542 ConfirmInfoBarDelegate
* infobar_delegate_0
=
543 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
544 ASSERT_TRUE(infobar_delegate_0
);
545 infobar_delegate_0
->Accept();
546 CheckPermissionMessageSent(0, true);
547 infobar_service()->RemoveInfoBar(infobar_0
);
548 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
549 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
550 // Now the infobar for the tab with the same origin should have gone.
551 EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
552 CheckPermissionMessageSentForTab(1, 0, true);
553 EXPECT_TRUE(closed_infobar_tracker_
.Contains(removed_infobar
));
554 closed_infobar_tracker_
.Clear();
556 // But the other tab should still have the info bar...
557 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
558 infobars::InfoBar
* infobar_1
= infobar_service_for_tab(0)->infobar_at(0);
559 ConfirmInfoBarDelegate
* infobar_delegate_1
=
560 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
561 ASSERT_TRUE(infobar_delegate_1
);
562 infobar_delegate_1
->Cancel();
563 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1
);
564 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
565 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
568 TEST_F(GeolocationPermissionContextTests
, QueuedOriginMultipleTabs
) {
569 GURL
url_a("http://www.example.com/geolocation");
570 GURL
url_b("http://www.example-2.com/geolocation");
571 NavigateAndCommit(url_a
);
574 EXPECT_EQ(0U, infobar_service()->infobar_count());
575 RequestGeolocationPermission(web_contents(), RequestID(0), url_a
);
576 ASSERT_EQ(1U, infobar_service()->infobar_count());
578 RequestGeolocationPermission(extra_tabs_
[0], RequestIDForTab(0, 0), url_a
);
579 EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
581 RequestGeolocationPermission(extra_tabs_
[0], RequestIDForTab(0, 1), url_b
);
582 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
584 infobars::InfoBar
* removed_infobar
= infobar_service()->infobar_at(0);
586 // Accept the second tab.
587 infobars::InfoBar
* infobar_0
= infobar_service_for_tab(0)->infobar_at(0);
588 ConfirmInfoBarDelegate
* infobar_delegate_0
=
589 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
590 ASSERT_TRUE(infobar_delegate_0
);
591 infobar_delegate_0
->Accept();
592 CheckPermissionMessageSentForTab(0, 0, true);
593 infobar_service_for_tab(0)->RemoveInfoBar(infobar_0
);
594 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
595 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
596 // Now the infobar for the tab with the same origin should have gone.
597 EXPECT_EQ(0U, infobar_service()->infobar_count());
598 CheckPermissionMessageSent(0, true);
599 EXPECT_TRUE(closed_infobar_tracker_
.Contains(removed_infobar
));
600 closed_infobar_tracker_
.Clear();
602 // And we should have the queued infobar displayed now.
603 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
605 // Accept the second infobar.
606 infobars::InfoBar
* infobar_1
= infobar_service_for_tab(0)->infobar_at(0);
607 ConfirmInfoBarDelegate
* infobar_delegate_1
=
608 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
609 ASSERT_TRUE(infobar_delegate_1
);
610 infobar_delegate_1
->Accept();
611 CheckPermissionMessageSentForTab(0, 1, true);
612 infobar_service_for_tab(0)->RemoveInfoBar(infobar_1
);
613 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
614 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_1
));
617 TEST_F(GeolocationPermissionContextTests
, TabDestroyed
) {
618 GURL
requesting_frame_0("http://www.example.com/geolocation");
619 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
620 EXPECT_EQ(CONTENT_SETTING_ASK
,
621 profile()->GetHostContentSettingsMap()->GetContentSetting(
622 requesting_frame_0
, requesting_frame_0
,
623 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
625 EXPECT_EQ(CONTENT_SETTING_ASK
,
626 profile()->GetHostContentSettingsMap()->GetContentSetting(
627 requesting_frame_1
, requesting_frame_0
,
628 CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string()));
630 NavigateAndCommit(requesting_frame_0
);
631 EXPECT_EQ(0U, infobar_service()->infobar_count());
632 // Request permission for two frames.
633 RequestGeolocationPermission(
634 web_contents(), RequestID(0), requesting_frame_0
);
635 RequestGeolocationPermission(
636 web_contents(), RequestID(1), requesting_frame_1
);
637 // Ensure only one infobar is created.
638 ASSERT_EQ(1U, infobar_service()->infobar_count());
639 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
641 // Delete the tab contents.
644 // During contents destruction, the infobar will have been closed, and the
645 // pending request should have been cleared without an infobar being created.
646 ASSERT_EQ(1U, closed_infobar_tracker_
.size());
647 ASSERT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
650 TEST_F(GeolocationPermissionContextTests
, LastUsageAudited
) {
651 GURL
requesting_frame("http://www.example.com/geolocation");
652 NavigateAndCommit(requesting_frame
);
654 base::SimpleTestClock
* test_clock
= new base::SimpleTestClock
;
655 test_clock
->SetNow(base::Time::UnixEpoch() +
656 base::TimeDelta::FromSeconds(10));
658 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
659 map
->SetPrefClockForTesting(scoped_ptr
<base::Clock
>(test_clock
));
661 // The permission shouldn't have been used yet.
662 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
663 requesting_frame
.GetOrigin(),
664 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
667 EXPECT_EQ(0U, infobar_service()->infobar_count());
668 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
669 ASSERT_EQ(1U, infobar_service()->infobar_count());
670 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
671 ConfirmInfoBarDelegate
* infobar_delegate
=
672 infobar
->delegate()->AsConfirmInfoBarDelegate();
673 ASSERT_TRUE(infobar_delegate
);
674 infobar_delegate
->Accept();
675 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
676 CheckPermissionMessageSent(0, true);
678 // Permission has been used at the starting time.
679 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
680 requesting_frame
.GetOrigin(),
681 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
684 test_clock
->Advance(base::TimeDelta::FromSeconds(3));
685 RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame
);
687 // Permission has been used three seconds later.
688 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
689 requesting_frame
.GetOrigin(),
690 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
694 TEST_F(GeolocationPermissionContextTests
, LastUsageAuditedMultipleFrames
) {
695 base::SimpleTestClock
* test_clock
= new base::SimpleTestClock
;
696 test_clock
->SetNow(base::Time::UnixEpoch() +
697 base::TimeDelta::FromSeconds(10));
699 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
700 map
->SetPrefClockForTesting(scoped_ptr
<base::Clock
>(test_clock
));
702 GURL
requesting_frame_0("http://www.example.com/geolocation");
703 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
705 // The permission shouldn't have been used yet.
706 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
707 requesting_frame_0
.GetOrigin(),
708 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
710 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
711 requesting_frame_0
.GetOrigin(),
712 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
715 NavigateAndCommit(requesting_frame_0
);
716 EXPECT_EQ(0U, infobar_service()->infobar_count());
718 // Request permission for two frames.
719 RequestGeolocationPermission(
720 web_contents(), RequestID(0), requesting_frame_0
);
721 RequestGeolocationPermission(
722 web_contents(), RequestID(1), requesting_frame_1
);
724 // Ensure only one infobar is created.
725 ASSERT_EQ(1U, infobar_service()->infobar_count());
726 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
727 ConfirmInfoBarDelegate
* infobar_delegate_0
=
728 infobar_0
->delegate()->AsConfirmInfoBarDelegate();
730 // Accept the first frame.
731 infobar_delegate_0
->Accept();
732 CheckTabContentsState(requesting_frame_0
, CONTENT_SETTING_ALLOW
);
733 CheckPermissionMessageSent(0, true);
734 infobar_service()->RemoveInfoBar(infobar_0
);
736 // Verify that accepting the first didn't accept because it's embedder
738 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
739 requesting_frame_0
.GetOrigin(),
740 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
742 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
743 requesting_frame_0
.GetOrigin(),
744 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
747 ASSERT_EQ(1U, infobar_service()->infobar_count());
748 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
749 ConfirmInfoBarDelegate
* infobar_delegate_1
=
750 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
752 test_clock
->Advance(base::TimeDelta::FromSeconds(1));
754 // Allow the second frame.
755 infobar_delegate_1
->Accept();
756 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_ALLOW
);
757 CheckPermissionMessageSent(1, true);
758 infobar_service()->RemoveInfoBar(infobar_1
);
760 // Verify that the times are different.
761 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
762 requesting_frame_0
.GetOrigin(),
763 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
765 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
766 requesting_frame_0
.GetOrigin(),
767 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
770 test_clock
->Advance(base::TimeDelta::FromSeconds(2));
771 RequestGeolocationPermission(
772 web_contents(), RequestID(0), requesting_frame_0
);
774 // Verify that requesting permission in one frame doesn't update other where
775 // it is the embedder.
776 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
777 requesting_frame_0
.GetOrigin(),
778 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
780 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
781 requesting_frame_0
.GetOrigin(),
782 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),