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/command_line.h"
13 #include "base/containers/hash_tables.h"
14 #include "base/id_map.h"
15 #include "base/memory/scoped_vector.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "base/test/simple_test_clock.h"
18 #include "base/time/clock.h"
19 #include "chrome/browser/chrome_notification_types.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/browser/permissions/permission_request_id.h"
24 #include "chrome/browser/ui/website_settings/mock_permission_bubble_view.h"
25 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
26 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
29 #include "chrome/test/base/testing_profile.h"
30 #include "components/content_settings/core/browser/host_content_settings_map.h"
31 #include "components/infobars/core/confirm_infobar_delegate.h"
32 #include "components/infobars/core/infobar.h"
33 #include "content/public/browser/browser_thread.h"
34 #include "content/public/browser/navigation_details.h"
35 #include "content/public/browser/navigation_entry.h"
36 #include "content/public/browser/notification_observer.h"
37 #include "content/public/browser/notification_registrar.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/render_frame_host.h"
40 #include "content/public/browser/web_contents.h"
41 #include "content/public/test/mock_render_process_host.h"
42 #include "content/public/test/test_renderer_host.h"
43 #include "content/public/test/test_utils.h"
44 #include "content/public/test/web_contents_tester.h"
45 #include "testing/gtest/include/gtest/gtest.h"
47 #if defined(OS_ANDROID)
48 #include "base/prefs/pref_service.h"
49 #include "chrome/browser/android/mock_location_settings.h"
50 #include "chrome/browser/geolocation/geolocation_permission_context_android.h"
53 #if defined(ENABLE_EXTENSIONS)
54 #include "extensions/browser/view_type_utils.h"
57 using content::MockRenderProcessHost
;
60 // ClosedInfoBarTracker -------------------------------------------------------
62 // We need to track which infobars were closed.
63 class ClosedInfoBarTracker
: public content::NotificationObserver
{
65 ClosedInfoBarTracker();
66 ~ClosedInfoBarTracker() override
;
68 // content::NotificationObserver:
69 void Observe(int type
,
70 const content::NotificationSource
& source
,
71 const content::NotificationDetails
& details
) override
;
73 size_t size() const { return removed_infobars_
.size(); }
75 bool Contains(infobars::InfoBar
* infobar
) const;
79 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests
, TabDestroyed
);
80 content::NotificationRegistrar registrar_
;
81 std::set
<infobars::InfoBar
*> removed_infobars_
;
84 ClosedInfoBarTracker::ClosedInfoBarTracker() {
85 registrar_
.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
,
86 content::NotificationService::AllSources());
89 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
92 void ClosedInfoBarTracker::Observe(
94 const content::NotificationSource
& source
,
95 const content::NotificationDetails
& details
) {
96 DCHECK(type
== chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED
);
97 removed_infobars_
.insert(
98 content::Details
<infobars::InfoBar::RemovedDetails
>(details
)->first
);
101 bool ClosedInfoBarTracker::Contains(infobars::InfoBar
* infobar
) const {
102 return removed_infobars_
.count(infobar
) != 0;
105 void ClosedInfoBarTracker::Clear() {
106 removed_infobars_
.clear();
110 // GeolocationPermissionContextTests ------------------------------------------
112 class GeolocationPermissionContextTests
113 : public ChromeRenderViewHostTestHarness
{
115 // ChromeRenderViewHostTestHarness:
116 void SetUp() override
;
117 void TearDown() override
;
119 PermissionRequestID
RequestID(int request_id
);
120 PermissionRequestID
RequestIDForTab(int tab
, int request_id
);
121 InfoBarService
* infobar_service() {
122 return InfoBarService::FromWebContents(web_contents());
124 InfoBarService
* infobar_service_for_tab(int tab
) {
125 return InfoBarService::FromWebContents(extra_tabs_
[tab
]);
128 void RequestGeolocationPermission(content::WebContents
* web_contents
,
129 const PermissionRequestID
& id
,
130 const GURL
& requesting_frame
,
133 void PermissionResponse(const PermissionRequestID
& id
,
134 ContentSetting content_setting
);
135 void CheckPermissionMessageSent(int request_id
, bool allowed
);
136 void CheckPermissionMessageSentForTab(int tab
, int request_id
, bool allowed
);
137 void CheckPermissionMessageSentInternal(MockRenderProcessHost
* process
,
140 void AddNewTab(const GURL
& url
);
141 void CheckTabContentsState(const GURL
& requesting_frame
,
142 ContentSetting expected_content_setting
);
143 size_t GetBubblesQueueSize(PermissionBubbleManager
* manager
);
144 void AcceptBubble(PermissionBubbleManager
* manager
);
145 void DenyBubble(PermissionBubbleManager
* manager
);
146 void CloseBubble(PermissionBubbleManager
* manager
);
147 void BubbleManagerDocumentLoadCompleted();
148 void BubbleManagerDocumentLoadCompleted(content::WebContents
* web_contents
);
149 ContentSetting
GetGeolocationContentSetting(GURL frame_0
, GURL frame_1
);
150 bool BubbleEnabled() const;
151 size_t GetNumberOfPrompts();
153 base::string16
GetPromptText();
155 // owned by the browser context
156 GeolocationPermissionContext
* geolocation_permission_context_
;
157 ClosedInfoBarTracker closed_infobar_tracker_
;
158 ScopedVector
<content::WebContents
> extra_tabs_
;
160 // A map between renderer child id and a pair represending the bridge id and
161 // whether the requested permission was allowed.
162 base::hash_map
<int, std::pair
<int, bool> > responses_
;
165 PermissionRequestID
GeolocationPermissionContextTests::RequestID(
167 return PermissionRequestID(
168 web_contents()->GetRenderProcessHost()->GetID(),
169 web_contents()->GetMainFrame()->GetRoutingID(),
173 PermissionRequestID
GeolocationPermissionContextTests::RequestIDForTab(
176 return PermissionRequestID(
177 extra_tabs_
[tab
]->GetRenderProcessHost()->GetID(),
178 extra_tabs_
[tab
]->GetMainFrame()->GetRoutingID(),
182 void GeolocationPermissionContextTests::RequestGeolocationPermission(
183 content::WebContents
* web_contents
,
184 const PermissionRequestID
& id
,
185 const GURL
& requesting_frame
,
187 geolocation_permission_context_
->RequestPermission(
188 web_contents
, id
, requesting_frame
, user_gesture
,
189 base::Bind(&GeolocationPermissionContextTests::PermissionResponse
,
190 base::Unretained(this), id
));
191 content::RunAllBlockingPoolTasksUntilIdle();
194 void GeolocationPermissionContextTests::PermissionResponse(
195 const PermissionRequestID
& id
,
196 ContentSetting content_setting
) {
197 responses_
[id
.render_process_id()] =
198 std::make_pair(id
.request_id(), content_setting
== CONTENT_SETTING_ALLOW
);
201 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
204 CheckPermissionMessageSentInternal(process(), request_id
, allowed
);
207 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
211 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost
*>(
212 extra_tabs_
[tab
]->GetRenderProcessHost()),
213 request_id
, allowed
);
216 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
217 MockRenderProcessHost
* process
,
220 ASSERT_EQ(responses_
.count(process
->GetID()), 1U);
221 EXPECT_EQ(request_id
, responses_
[process
->GetID()].first
);
222 EXPECT_EQ(allowed
, responses_
[process
->GetID()].second
);
223 responses_
.erase(process
->GetID());
226 void GeolocationPermissionContextTests::AddNewTab(const GURL
& url
) {
227 content::WebContents
* new_tab
= CreateTestWebContents();
228 new_tab
->GetController().LoadURL(
229 url
, content::Referrer(), ui::PAGE_TRANSITION_TYPED
, std::string());
230 content::NavigationEntry
* entry
= new_tab
->GetController().GetPendingEntry();
231 content::RenderFrameHostTester::For(new_tab
->GetMainFrame())
232 ->SendNavigate(extra_tabs_
.size() + 1, entry
->GetUniqueID(), true, url
);
234 // Set up required helpers, and make this be as "tabby" as the code requires.
235 #if defined(ENABLE_EXTENSIONS)
236 extensions::SetViewType(new_tab
, extensions::VIEW_TYPE_TAB_CONTENTS
);
238 InfoBarService::CreateForWebContents(new_tab
);
239 if (BubbleEnabled()) {
240 PermissionBubbleManager::CreateForWebContents(new_tab
);
241 PermissionBubbleManager
* permission_bubble_manager
=
242 PermissionBubbleManager::FromWebContents(new_tab
);
243 MockPermissionBubbleView::SetFactory(permission_bubble_manager
, false);
244 permission_bubble_manager
->DisplayPendingRequests();
247 extra_tabs_
.push_back(new_tab
);
250 void GeolocationPermissionContextTests::CheckTabContentsState(
251 const GURL
& requesting_frame
,
252 ContentSetting expected_content_setting
) {
253 TabSpecificContentSettings
* content_settings
=
254 TabSpecificContentSettings::FromWebContents(web_contents());
255 const ContentSettingsUsagesState::StateMap
& state_map
=
256 content_settings
->geolocation_usages_state().state_map();
257 EXPECT_EQ(1U, state_map
.count(requesting_frame
.GetOrigin()));
258 EXPECT_EQ(0U, state_map
.count(requesting_frame
));
259 ContentSettingsUsagesState::StateMap::const_iterator settings
=
260 state_map
.find(requesting_frame
.GetOrigin());
261 ASSERT_FALSE(settings
== state_map
.end())
262 << "geolocation state not found " << requesting_frame
;
263 EXPECT_EQ(expected_content_setting
, settings
->second
);
266 void GeolocationPermissionContextTests::SetUp() {
267 ChromeRenderViewHostTestHarness::SetUp();
269 // Set up required helpers, and make this be as "tabby" as the code requires.
270 #if defined(ENABLE_EXTENSIONS)
271 extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS
);
273 InfoBarService::CreateForWebContents(web_contents());
274 TabSpecificContentSettings::CreateForWebContents(web_contents());
275 geolocation_permission_context_
=
276 GeolocationPermissionContextFactory::GetForProfile(profile());
277 #if defined(OS_ANDROID)
278 static_cast<GeolocationPermissionContextAndroid
*>(
279 geolocation_permission_context_
)
280 ->SetLocationSettingsForTesting(
281 scoped_ptr
<LocationSettings
>(new MockLocationSettings()));
282 MockLocationSettings::SetLocationStatus(true, true);
284 if (BubbleEnabled()) {
285 PermissionBubbleManager::CreateForWebContents(web_contents());
286 PermissionBubbleManager
* permission_bubble_manager
=
287 PermissionBubbleManager::FromWebContents(web_contents());
288 MockPermissionBubbleView::SetFactory(permission_bubble_manager
, false);
289 permission_bubble_manager
->DisplayPendingRequests();
293 void GeolocationPermissionContextTests::TearDown() {
295 ChromeRenderViewHostTestHarness::TearDown();
298 size_t GeolocationPermissionContextTests::GetBubblesQueueSize(
299 PermissionBubbleManager
* manager
) {
300 return manager
->requests_
.size();
303 void GeolocationPermissionContextTests::AcceptBubble(
304 PermissionBubbleManager
* manager
) {
308 void GeolocationPermissionContextTests::DenyBubble(
309 PermissionBubbleManager
* manager
) {
313 void GeolocationPermissionContextTests::CloseBubble(
314 PermissionBubbleManager
* manager
) {
318 void GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted() {
319 GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted(
323 void GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted(
324 content::WebContents
* web_contents
) {
325 PermissionBubbleManager::FromWebContents(web_contents
)->
326 DocumentOnLoadCompletedInMainFrame();
329 ContentSetting
GeolocationPermissionContextTests::GetGeolocationContentSetting(
330 GURL frame_0
, GURL frame_1
) {
331 return profile()->GetHostContentSettingsMap()->GetContentSetting(
332 frame_0
, frame_1
, CONTENT_SETTINGS_TYPE_GEOLOCATION
, std::string());
335 bool GeolocationPermissionContextTests::BubbleEnabled() const {
336 return PermissionBubbleManager::Enabled();
339 size_t GeolocationPermissionContextTests::GetNumberOfPrompts() {
340 if (BubbleEnabled()) {
341 PermissionBubbleManager
* manager
=
342 PermissionBubbleManager::FromWebContents(web_contents());
343 return GetBubblesQueueSize(manager
);
345 return infobar_service()->infobar_count();
349 void GeolocationPermissionContextTests::AcceptPrompt() {
350 if (BubbleEnabled()) {
351 PermissionBubbleManager
* manager
=
352 PermissionBubbleManager::FromWebContents(web_contents());
353 AcceptBubble(manager
);
355 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
356 ConfirmInfoBarDelegate
* infobar_delegate
=
357 infobar
->delegate()->AsConfirmInfoBarDelegate();
358 infobar_delegate
->Accept();
362 base::string16
GeolocationPermissionContextTests::GetPromptText() {
363 if (BubbleEnabled()) {
364 PermissionBubbleManager
* manager
=
365 PermissionBubbleManager::FromWebContents(web_contents());
366 return manager
->requests_
.front()->GetMessageText();
368 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
369 ConfirmInfoBarDelegate
* infobar_delegate
=
370 infobar
->delegate()->AsConfirmInfoBarDelegate();
371 return infobar_delegate
->GetMessageText();
374 // Tests ----------------------------------------------------------------------
376 TEST_F(GeolocationPermissionContextTests
, SinglePermissionInfobar
) {
377 if (BubbleEnabled()) return;
379 GURL
requesting_frame("http://www.example.com/geolocation");
380 NavigateAndCommit(requesting_frame
);
381 EXPECT_EQ(0U, infobar_service()->infobar_count());
382 RequestGeolocationPermission(
383 web_contents(), RequestID(0), requesting_frame
, true);
384 ASSERT_EQ(1U, infobar_service()->infobar_count());
385 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
386 ConfirmInfoBarDelegate
* infobar_delegate
=
387 infobar
->delegate()->AsConfirmInfoBarDelegate();
388 ASSERT_TRUE(infobar_delegate
);
389 infobar_delegate
->Cancel();
390 infobar_service()->RemoveInfoBar(infobar
);
391 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
392 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
395 TEST_F(GeolocationPermissionContextTests
, SinglePermissionBubble
) {
396 if (!BubbleEnabled()) return;
398 GURL
requesting_frame("http://www.example.com/geolocation");
399 NavigateAndCommit(requesting_frame
);
400 BubbleManagerDocumentLoadCompleted();
402 EXPECT_EQ(0U, GetNumberOfPrompts());
403 RequestGeolocationPermission(
404 web_contents(), RequestID(0), requesting_frame
, true);
405 ASSERT_EQ(1U, GetNumberOfPrompts());
408 #if defined(OS_ANDROID)
409 // Infobar-only tests; Android doesn't support permission bubbles.
410 TEST_F(GeolocationPermissionContextTests
, GeolocationEnabledDisabled
) {
411 GURL
requesting_frame("http://www.example.com/geolocation");
412 NavigateAndCommit(requesting_frame
);
413 MockLocationSettings::SetLocationStatus(true, true);
414 EXPECT_EQ(0U, infobar_service()->infobar_count());
415 RequestGeolocationPermission(
416 web_contents(), RequestID(0), requesting_frame
, true);
417 EXPECT_EQ(1U, infobar_service()->infobar_count());
418 ConfirmInfoBarDelegate
* infobar_delegate_0
=
419 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
420 ASSERT_TRUE(infobar_delegate_0
);
421 base::string16 text_0
= infobar_delegate_0
->GetButtonLabel(
422 ConfirmInfoBarDelegate::BUTTON_OK
);
425 MockLocationSettings::SetLocationStatus(true, false);
426 EXPECT_EQ(0U, infobar_service()->infobar_count());
427 RequestGeolocationPermission(
428 web_contents(), RequestID(0), requesting_frame
, true);
429 EXPECT_EQ(0U, infobar_service()->infobar_count());
432 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsEnabled
) {
433 GURL
requesting_frame("http://www.example.com/geolocation");
434 NavigateAndCommit(requesting_frame
);
435 MockLocationSettings::SetLocationStatus(true, true);
436 EXPECT_EQ(0U, infobar_service()->infobar_count());
437 RequestGeolocationPermission(
438 web_contents(), RequestID(0), requesting_frame
, true);
439 EXPECT_EQ(1U, infobar_service()->infobar_count());
440 ConfirmInfoBarDelegate
* infobar_delegate
=
441 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
442 ASSERT_TRUE(infobar_delegate
);
443 infobar_delegate
->Accept();
444 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
445 CheckPermissionMessageSent(0, true);
448 TEST_F(GeolocationPermissionContextTests
, MasterEnabledGoogleAppsDisabled
) {
449 GURL
requesting_frame("http://www.example.com/geolocation");
450 NavigateAndCommit(requesting_frame
);
451 MockLocationSettings::SetLocationStatus(true, false);
452 EXPECT_EQ(0U, infobar_service()->infobar_count());
453 RequestGeolocationPermission(
454 web_contents(), RequestID(0), requesting_frame
, true);
455 EXPECT_EQ(0U, infobar_service()->infobar_count());
459 TEST_F(GeolocationPermissionContextTests
, QueuedPermission
) {
460 GURL
requesting_frame_0("http://www.example.com/geolocation");
461 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
464 GetGeolocationContentSetting(requesting_frame_0
, requesting_frame_1
));
467 GetGeolocationContentSetting(requesting_frame_1
, requesting_frame_1
));
469 NavigateAndCommit(requesting_frame_0
);
470 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
472 // Check that no permission requests have happened yet.
473 EXPECT_EQ(0U, GetNumberOfPrompts());
475 // Request permission for two frames.
476 RequestGeolocationPermission(
477 web_contents(), RequestID(0), requesting_frame_0
, true);
478 RequestGeolocationPermission(
479 web_contents(), RequestID(1), requesting_frame_1
, true);
480 // Ensure only one infobar is created.
481 ASSERT_EQ(1U, GetNumberOfPrompts());
482 base::string16 text_0
= GetPromptText();
484 // Accept the first frame.
486 CheckTabContentsState(requesting_frame_0
, CONTENT_SETTING_ALLOW
);
487 CheckPermissionMessageSent(0, true);
489 if (!BubbleEnabled()) {
490 infobars::InfoBar
* infobar_0
= infobar_service()->infobar_at(0);
491 infobar_service()->RemoveInfoBar(infobar_0
);
492 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
493 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_0
));
494 closed_infobar_tracker_
.Clear();
497 // Now we should have a new infobar for the second frame.
498 ASSERT_EQ(1U, GetNumberOfPrompts());
499 base::string16 text_1
= GetPromptText();
501 // Check that the messages differ.
502 EXPECT_NE(text_0
, text_1
);
504 // Cancel (block) this frame.
505 if (BubbleEnabled()) {
506 PermissionBubbleManager
* manager
=
507 PermissionBubbleManager::FromWebContents(web_contents());
510 infobars::InfoBar
* infobar_1
= infobar_service()->infobar_at(0);
511 infobar_1
->delegate()->AsConfirmInfoBarDelegate()->Cancel();
513 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_BLOCK
);
514 CheckPermissionMessageSent(1, false);
516 // Ensure the persisted permissions are ok.
518 CONTENT_SETTING_ALLOW
,
519 GetGeolocationContentSetting(requesting_frame_0
, requesting_frame_0
));
521 CONTENT_SETTING_BLOCK
,
522 GetGeolocationContentSetting(requesting_frame_1
, requesting_frame_0
));
525 TEST_F(GeolocationPermissionContextTests
, HashIsIgnored
) {
526 GURL
url_a("http://www.example.com/geolocation#a");
527 GURL
url_b("http://www.example.com/geolocation#b");
529 // Navigate to the first url.
530 NavigateAndCommit(url_a
);
531 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
533 // Check permission is requested.
534 ASSERT_EQ(0U, GetNumberOfPrompts());
535 RequestGeolocationPermission(
536 web_contents(), RequestID(0), url_a
, BubbleEnabled());
537 ASSERT_EQ(1U, GetNumberOfPrompts());
539 // Change the hash, we'll still be on the same page.
540 NavigateAndCommit(url_b
);
541 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
545 CheckTabContentsState(url_a
, CONTENT_SETTING_ALLOW
);
546 CheckTabContentsState(url_b
, CONTENT_SETTING_ALLOW
);
547 CheckPermissionMessageSent(0, true);
550 if (!BubbleEnabled()) {
551 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
552 infobar_service()->RemoveInfoBar(infobar
);
553 EXPECT_EQ(1U, closed_infobar_tracker_
.size());
554 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
558 TEST_F(GeolocationPermissionContextTests
, PermissionForFileScheme
) {
559 // TODO(felt): The bubble is rejecting file:// permission requests.
560 // Fix and enable this test. crbug.com/444047
561 if (BubbleEnabled()) return;
563 GURL
requesting_frame("file://example/geolocation.html");
564 NavigateAndCommit(requesting_frame
);
565 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
567 // Check permission is requested.
568 ASSERT_EQ(0U, GetNumberOfPrompts());
569 RequestGeolocationPermission(
570 web_contents(), RequestID(0), requesting_frame
, true);
571 EXPECT_EQ(1U, GetNumberOfPrompts());
575 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
576 CheckPermissionMessageSent(0, true);
578 // Make sure the setting is not stored.
581 GetGeolocationContentSetting(requesting_frame
, requesting_frame
));
584 TEST_F(GeolocationPermissionContextTests
, CancelGeolocationPermissionRequest
) {
585 GURL
frame_0("http://www.example.com/geolocation");
586 GURL
frame_1("http://www.example-2.com/geolocation");
588 CONTENT_SETTING_ASK
, GetGeolocationContentSetting(frame_0
, frame_0
));
590 CONTENT_SETTING_ASK
, GetGeolocationContentSetting(frame_1
, frame_0
));
592 NavigateAndCommit(frame_0
);
593 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
595 ASSERT_EQ(0U, GetNumberOfPrompts());
597 // Request permission for two frames.
598 RequestGeolocationPermission(
599 web_contents(), RequestID(0), frame_0
, true);
600 RequestGeolocationPermission(
601 web_contents(), RequestID(1), frame_1
, true);
603 // Get the first permission request text.
604 ASSERT_EQ(1U, GetNumberOfPrompts());
605 base::string16 text_0
= GetPromptText();
606 ASSERT_FALSE(text_0
.empty());
608 // Simulate the frame going away; the request should be removed.
609 if (BubbleEnabled()) {
610 PermissionBubbleManager
* manager
=
611 PermissionBubbleManager::FromWebContents(web_contents());
612 CloseBubble(manager
);
614 geolocation_permission_context_
->CancelPermissionRequest(web_contents(),
618 // Check that the next pending request is created correctly.
619 base::string16 text_1
= GetPromptText();
620 EXPECT_NE(text_0
, text_1
);
622 // Allow this frame and check that it worked.
624 CheckTabContentsState(frame_1
, CONTENT_SETTING_ALLOW
);
625 CheckPermissionMessageSent(1, true);
627 // Ensure the persisted permissions are ok.
629 CONTENT_SETTING_ASK
, GetGeolocationContentSetting(frame_0
, frame_0
));
631 CONTENT_SETTING_ALLOW
, GetGeolocationContentSetting(frame_1
, frame_0
));
634 TEST_F(GeolocationPermissionContextTests
, InvalidURL
) {
635 // Navigate to the first url.
636 GURL
invalid_embedder("about:blank");
637 GURL requesting_frame
;
638 NavigateAndCommit(invalid_embedder
);
639 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
641 // Nothing should be displayed.
642 EXPECT_EQ(0U, GetNumberOfPrompts());
643 RequestGeolocationPermission(
644 web_contents(), RequestID(0), requesting_frame
, true);
645 EXPECT_EQ(0U, GetNumberOfPrompts());
646 CheckPermissionMessageSent(0, false);
649 TEST_F(GeolocationPermissionContextTests
, SameOriginMultipleTabs
) {
650 GURL
url_a("http://www.example.com/geolocation");
651 GURL
url_b("http://www.example-2.com/geolocation");
652 NavigateAndCommit(url_a
); // Tab A0
653 AddNewTab(url_b
); // Tab B (extra_tabs_[0])
654 AddNewTab(url_a
); // Tab A1 (extra_tabs_[1])
655 if (BubbleEnabled()) {
656 BubbleManagerDocumentLoadCompleted();
657 BubbleManagerDocumentLoadCompleted(extra_tabs_
[0]);
658 BubbleManagerDocumentLoadCompleted(extra_tabs_
[1]);
660 PermissionBubbleManager
* manager_a0
=
661 PermissionBubbleManager::FromWebContents(web_contents());
662 PermissionBubbleManager
* manager_b
=
663 PermissionBubbleManager::FromWebContents(extra_tabs_
[0]);
664 PermissionBubbleManager
* manager_a1
=
665 PermissionBubbleManager::FromWebContents(extra_tabs_
[1]);
667 // Request permission in all three tabs.
668 RequestGeolocationPermission(
669 web_contents(), RequestID(0), url_a
, true);
670 RequestGeolocationPermission(
671 extra_tabs_
[0], RequestIDForTab(0, 0), url_b
, true);
672 RequestGeolocationPermission(
673 extra_tabs_
[1], RequestIDForTab(1, 0), url_a
, true);
674 ASSERT_EQ(1U, GetNumberOfPrompts()); // For A0.
675 if (BubbleEnabled()) {
676 ASSERT_EQ(1U, GetBubblesQueueSize(manager_b
));
677 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1
));
679 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
680 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
683 // Accept the permission in tab A0.
684 if (BubbleEnabled()) {
685 AcceptBubble(manager_a0
);
687 infobars::InfoBar
* infobar_a0
= infobar_service()->infobar_at(0);
688 ConfirmInfoBarDelegate
* infobar_delegate_a0
=
689 infobar_a0
->delegate()->AsConfirmInfoBarDelegate();
690 ASSERT_TRUE(infobar_delegate_a0
);
691 infobar_delegate_a0
->Accept();
692 infobar_service()->RemoveInfoBar(infobar_a0
);
693 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
694 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_a0
));
696 CheckPermissionMessageSent(0, true);
697 // Because they're the same origin, this will cause tab A1's infobar to
698 // disappear. It does not cause the bubble to disappear: crbug.com/443013.
699 // TODO(felt): Update this test when the bubble's behavior is changed.
701 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1
));
703 CheckPermissionMessageSentForTab(1, 0, true);
705 // Either way, tab B should still have a pending permission request.
707 ASSERT_EQ(1U, GetBubblesQueueSize(manager_b
));
709 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
712 TEST_F(GeolocationPermissionContextTests
, QueuedOriginMultipleTabs
) {
713 GURL
url_a("http://www.example.com/geolocation");
714 GURL
url_b("http://www.example-2.com/geolocation");
715 NavigateAndCommit(url_a
); // Tab A0.
716 AddNewTab(url_a
); // Tab A1.
717 if (BubbleEnabled()) {
718 BubbleManagerDocumentLoadCompleted();
719 BubbleManagerDocumentLoadCompleted(extra_tabs_
[0]);
721 PermissionBubbleManager
* manager_a0
=
722 PermissionBubbleManager::FromWebContents(web_contents());
723 PermissionBubbleManager
* manager_a1
=
724 PermissionBubbleManager::FromWebContents(extra_tabs_
[0]);
726 // Request permission in both tabs; the extra tab will have two permission
727 // requests from two origins.
728 RequestGeolocationPermission(
729 web_contents(), RequestID(0), url_a
, true);
730 RequestGeolocationPermission(
731 extra_tabs_
[0], RequestIDForTab(0, 0), url_a
, true);
732 RequestGeolocationPermission(
733 extra_tabs_
[0], RequestIDForTab(0, 1), url_b
, true);
734 if (BubbleEnabled()) {
735 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a0
));
736 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1
));
738 ASSERT_EQ(1U, infobar_service()->infobar_count());
739 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
742 // Accept the first request in tab A1.
743 if (BubbleEnabled()) {
744 AcceptBubble(manager_a1
);
746 infobars::InfoBar
* infobar_a1
= infobar_service_for_tab(0)->infobar_at(0);
747 ConfirmInfoBarDelegate
* infobar_delegate_a1
=
748 infobar_a1
->delegate()->AsConfirmInfoBarDelegate();
749 ASSERT_TRUE(infobar_delegate_a1
);
750 infobar_delegate_a1
->Accept();
751 infobar_service_for_tab(0)->RemoveInfoBar(infobar_a1
);
752 EXPECT_EQ(2U, closed_infobar_tracker_
.size());
753 EXPECT_TRUE(closed_infobar_tracker_
.Contains(infobar_a1
));
755 CheckPermissionMessageSentForTab(0, 0, true);
757 // Because they're the same origin, this will cause tab A0's infobar to
758 // disappear. It does not cause the bubble to disappear: crbug.com/443013.
759 // TODO(felt): Update this test when the bubble's behavior is changed.
760 if (BubbleEnabled()) {
761 EXPECT_EQ(1U, GetBubblesQueueSize(manager_a0
));
763 EXPECT_EQ(0U, infobar_service()->infobar_count());
764 CheckPermissionMessageSent(0, true);
767 // The second request should now be visible in tab A1.
769 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1
));
771 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
773 // Accept the second request and check that it's gone.
774 if (BubbleEnabled()) {
775 AcceptBubble(manager_a1
);
776 EXPECT_EQ(0U, GetBubblesQueueSize(manager_a1
));
778 infobars::InfoBar
* infobar_1
= infobar_service_for_tab(0)->infobar_at(0);
779 ConfirmInfoBarDelegate
* infobar_delegate_1
=
780 infobar_1
->delegate()->AsConfirmInfoBarDelegate();
781 ASSERT_TRUE(infobar_delegate_1
);
782 infobar_delegate_1
->Accept();
786 TEST_F(GeolocationPermissionContextTests
, TabDestroyed
) {
787 GURL
requesting_frame_0("http://www.example.com/geolocation");
788 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
791 GetGeolocationContentSetting(requesting_frame_0
, requesting_frame_0
));
794 GetGeolocationContentSetting(requesting_frame_1
, requesting_frame_0
));
796 NavigateAndCommit(requesting_frame_0
);
797 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
799 // Request permission for two frames.
800 RequestGeolocationPermission(
801 web_contents(), RequestID(0), requesting_frame_0
, false);
802 RequestGeolocationPermission(
803 web_contents(), RequestID(1), requesting_frame_1
, false);
805 // Ensure only one prompt is created.
806 ASSERT_EQ(1U, GetNumberOfPrompts());
808 // Delete the tab contents.
809 if (!BubbleEnabled()) {
810 infobars::InfoBar
* infobar
= infobar_service()->infobar_at(0);
812 ASSERT_EQ(1U, closed_infobar_tracker_
.size());
813 ASSERT_TRUE(closed_infobar_tracker_
.Contains(infobar
));
816 // The content settings should not have changed.
819 GetGeolocationContentSetting(requesting_frame_0
, requesting_frame_0
));
822 GetGeolocationContentSetting(requesting_frame_1
, requesting_frame_0
));
825 TEST_F(GeolocationPermissionContextTests
, LastUsageAudited
) {
826 GURL
requesting_frame("http://www.example.com/geolocation");
827 NavigateAndCommit(requesting_frame
);
828 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
830 base::SimpleTestClock
* test_clock
= new base::SimpleTestClock
;
831 test_clock
->SetNow(base::Time::UnixEpoch() +
832 base::TimeDelta::FromSeconds(10));
834 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
835 map
->SetPrefClockForTesting(scoped_ptr
<base::Clock
>(test_clock
));
837 // The permission shouldn't have been used yet.
838 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
839 requesting_frame
.GetOrigin(),
840 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
842 ASSERT_EQ(0U, GetNumberOfPrompts());
843 RequestGeolocationPermission(
844 web_contents(), RequestID(0), requesting_frame
, false);
845 ASSERT_EQ(1U, GetNumberOfPrompts());
848 CheckTabContentsState(requesting_frame
, CONTENT_SETTING_ALLOW
);
849 CheckPermissionMessageSent(0, true);
851 // Permission has been used at the starting time.
852 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
853 requesting_frame
.GetOrigin(),
854 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
857 test_clock
->Advance(base::TimeDelta::FromSeconds(3));
858 RequestGeolocationPermission(
859 web_contents(), RequestID(0), requesting_frame
, false);
861 // Permission has been used three seconds later.
862 EXPECT_EQ(map
->GetLastUsage(requesting_frame
.GetOrigin(),
863 requesting_frame
.GetOrigin(),
864 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
868 TEST_F(GeolocationPermissionContextTests
, LastUsageAuditedMultipleFrames
) {
869 base::SimpleTestClock
* test_clock
= new base::SimpleTestClock
;
870 test_clock
->SetNow(base::Time::UnixEpoch() +
871 base::TimeDelta::FromSeconds(10));
873 HostContentSettingsMap
* map
= profile()->GetHostContentSettingsMap();
874 map
->SetPrefClockForTesting(scoped_ptr
<base::Clock
>(test_clock
));
876 GURL
requesting_frame_0("http://www.example.com/geolocation");
877 GURL
requesting_frame_1("http://www.example-2.com/geolocation");
879 // The permission shouldn't have been used yet.
880 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
881 requesting_frame_0
.GetOrigin(),
882 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
884 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
885 requesting_frame_0
.GetOrigin(),
886 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
889 NavigateAndCommit(requesting_frame_0
);
890 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
892 EXPECT_EQ(0U, GetNumberOfPrompts());
894 // Request permission for two frames.
895 RequestGeolocationPermission(
896 web_contents(), RequestID(0), requesting_frame_0
, false);
897 RequestGeolocationPermission(
898 web_contents(), RequestID(1), requesting_frame_1
, false);
900 // Ensure only one infobar is created.
901 ASSERT_EQ(1U, GetNumberOfPrompts());
903 // Accept the first frame.
905 if (!BubbleEnabled())
906 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0));
907 CheckTabContentsState(requesting_frame_0
, CONTENT_SETTING_ALLOW
);
908 CheckPermissionMessageSent(0, true);
910 // Verify that accepting the first didn't accept because it's embedded
912 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
913 requesting_frame_0
.GetOrigin(),
914 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
916 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
917 requesting_frame_0
.GetOrigin(),
918 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
921 ASSERT_EQ(1U, GetNumberOfPrompts());
923 test_clock
->Advance(base::TimeDelta::FromSeconds(1));
925 // Allow the second frame.
927 CheckTabContentsState(requesting_frame_1
, CONTENT_SETTING_ALLOW
);
928 CheckPermissionMessageSent(1, true);
929 if (!BubbleEnabled())
930 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0));
932 // Verify that the times are different.
933 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
934 requesting_frame_0
.GetOrigin(),
935 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
937 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
938 requesting_frame_0
.GetOrigin(),
939 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
942 test_clock
->Advance(base::TimeDelta::FromSeconds(2));
943 RequestGeolocationPermission(
944 web_contents(), RequestID(0), requesting_frame_0
, false);
946 // Verify that requesting permission in one frame doesn't update other where
947 // it is the embedder.
948 EXPECT_EQ(map
->GetLastUsage(requesting_frame_0
.GetOrigin(),
949 requesting_frame_0
.GetOrigin(),
950 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),
952 EXPECT_EQ(map
->GetLastUsage(requesting_frame_1
.GetOrigin(),
953 requesting_frame_0
.GetOrigin(),
954 CONTENT_SETTINGS_TYPE_GEOLOCATION
).ToDoubleT(),