Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / geolocation / geolocation_permission_context_unittest.cc
blob37e840620f4f0be3d2a75a35fe0d92156f3f3009
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"
7 #include <set>
8 #include <string>
9 #include <utility>
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/ui/website_settings/mock_permission_bubble_view.h"
24 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
25 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
28 #include "chrome/test/base/testing_profile.h"
29 #include "components/content_settings/core/browser/host_content_settings_map.h"
30 #include "components/content_settings/core/common/permission_request_id.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/notification_observer.h"
36 #include "content/public/browser/notification_registrar.h"
37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/web_contents.h"
39 #include "content/public/test/mock_render_process_host.h"
40 #include "content/public/test/test_renderer_host.h"
41 #include "content/public/test/test_utils.h"
42 #include "content/public/test/web_contents_tester.h"
43 #include "testing/gtest/include/gtest/gtest.h"
45 #if defined(OS_ANDROID)
46 #include "base/prefs/pref_service.h"
47 #include "chrome/browser/android/mock_location_settings.h"
48 #include "chrome/browser/geolocation/geolocation_permission_context_android.h"
49 #endif
51 #if defined(ENABLE_EXTENSIONS)
52 #include "extensions/browser/view_type_utils.h"
53 #endif
55 using content::MockRenderProcessHost;
58 // ClosedInfoBarTracker -------------------------------------------------------
60 // We need to track which infobars were closed.
61 class ClosedInfoBarTracker : public content::NotificationObserver {
62 public:
63 ClosedInfoBarTracker();
64 ~ClosedInfoBarTracker() override;
66 // content::NotificationObserver:
67 void Observe(int type,
68 const content::NotificationSource& source,
69 const content::NotificationDetails& details) override;
71 size_t size() const { return removed_infobars_.size(); }
73 bool Contains(infobars::InfoBar* infobar) const;
74 void Clear();
76 private:
77 FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests, TabDestroyed);
78 content::NotificationRegistrar registrar_;
79 std::set<infobars::InfoBar*> removed_infobars_;
82 ClosedInfoBarTracker::ClosedInfoBarTracker() {
83 registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
84 content::NotificationService::AllSources());
87 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
90 void ClosedInfoBarTracker::Observe(
91 int type,
92 const content::NotificationSource& source,
93 const content::NotificationDetails& details) {
94 DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED);
95 removed_infobars_.insert(
96 content::Details<infobars::InfoBar::RemovedDetails>(details)->first);
99 bool ClosedInfoBarTracker::Contains(infobars::InfoBar* infobar) const {
100 return removed_infobars_.count(infobar) != 0;
103 void ClosedInfoBarTracker::Clear() {
104 removed_infobars_.clear();
108 // GeolocationPermissionContextTests ------------------------------------------
110 class GeolocationPermissionContextTests
111 : public ChromeRenderViewHostTestHarness {
112 protected:
113 // ChromeRenderViewHostTestHarness:
114 void SetUp() override;
115 void TearDown() override;
117 PermissionRequestID RequestID(int bridge_id);
118 PermissionRequestID RequestIDForTab(int tab, int bridge_id);
119 InfoBarService* infobar_service() {
120 return InfoBarService::FromWebContents(web_contents());
122 InfoBarService* infobar_service_for_tab(int tab) {
123 return InfoBarService::FromWebContents(extra_tabs_[tab]);
126 void RequestGeolocationPermission(content::WebContents* web_contents,
127 const PermissionRequestID& id,
128 const GURL& requesting_frame,
129 bool user_gesture);
131 void PermissionResponse(const PermissionRequestID& id,
132 ContentSetting content_setting);
133 void CheckPermissionMessageSent(int bridge_id, bool allowed);
134 void CheckPermissionMessageSentForTab(int tab, int bridge_id, bool allowed);
135 void CheckPermissionMessageSentInternal(MockRenderProcessHost* process,
136 int bridge_id,
137 bool allowed);
138 void AddNewTab(const GURL& url);
139 void CheckTabContentsState(const GURL& requesting_frame,
140 ContentSetting expected_content_setting);
141 size_t GetBubblesQueueSize(PermissionBubbleManager* manager);
142 void AcceptBubble(PermissionBubbleManager* manager);
143 void DenyBubble(PermissionBubbleManager* manager);
144 void CloseBubble(PermissionBubbleManager* manager);
145 void BubbleManagerDocumentLoadCompleted();
146 void BubbleManagerDocumentLoadCompleted(content::WebContents* web_contents);
147 ContentSetting GetGeolocationContentSetting(GURL frame_0, GURL frame_1);
149 // owned by the browser context
150 GeolocationPermissionContext* geolocation_permission_context_;
151 ClosedInfoBarTracker closed_infobar_tracker_;
152 MockPermissionBubbleView bubble_view_;
153 ScopedVector<content::WebContents> extra_tabs_;
155 // A map between renderer child id and a pair represending the bridge id and
156 // whether the requested permission was allowed.
157 base::hash_map<int, std::pair<int, bool> > responses_;
160 PermissionRequestID GeolocationPermissionContextTests::RequestID(
161 int bridge_id) {
162 return PermissionRequestID(
163 web_contents()->GetRenderProcessHost()->GetID(),
164 web_contents()->GetRenderViewHost()->GetRoutingID(),
165 bridge_id,
166 GURL());
169 PermissionRequestID GeolocationPermissionContextTests::RequestIDForTab(
170 int tab,
171 int bridge_id) {
172 return PermissionRequestID(
173 extra_tabs_[tab]->GetRenderProcessHost()->GetID(),
174 extra_tabs_[tab]->GetRenderViewHost()->GetRoutingID(),
175 bridge_id,
176 GURL());
179 void GeolocationPermissionContextTests::RequestGeolocationPermission(
180 content::WebContents* web_contents,
181 const PermissionRequestID& id,
182 const GURL& requesting_frame,
183 bool user_gesture) {
184 geolocation_permission_context_->RequestPermission(
185 web_contents, id, requesting_frame, user_gesture,
186 base::Bind(&GeolocationPermissionContextTests::PermissionResponse,
187 base::Unretained(this), id));
188 content::RunAllBlockingPoolTasksUntilIdle();
191 void GeolocationPermissionContextTests::PermissionResponse(
192 const PermissionRequestID& id,
193 ContentSetting content_setting) {
194 responses_[id.render_process_id()] =
195 std::make_pair(id.bridge_id(), content_setting == CONTENT_SETTING_ALLOW);
198 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
199 int bridge_id,
200 bool allowed) {
201 CheckPermissionMessageSentInternal(process(), bridge_id, allowed);
204 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
205 int tab,
206 int bridge_id,
207 bool allowed) {
208 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost*>(
209 extra_tabs_[tab]->GetRenderProcessHost()),
210 bridge_id, allowed);
213 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
214 MockRenderProcessHost* process,
215 int bridge_id,
216 bool allowed) {
217 ASSERT_EQ(responses_.count(process->GetID()), 1U);
218 EXPECT_EQ(bridge_id, responses_[process->GetID()].first);
219 EXPECT_EQ(allowed, responses_[process->GetID()].second);
220 responses_.erase(process->GetID());
223 void GeolocationPermissionContextTests::AddNewTab(const GURL& url) {
224 content::WebContents* new_tab = CreateTestWebContents();
225 new_tab->GetController().LoadURL(
226 url, content::Referrer(), ui::PAGE_TRANSITION_TYPED, std::string());
227 content::RenderFrameHostTester::For(new_tab->GetMainFrame())
228 ->SendNavigate(extra_tabs_.size() + 1, url);
230 // Set up required helpers, and make this be as "tabby" as the code requires.
231 #if defined(ENABLE_EXTENSIONS)
232 extensions::SetViewType(new_tab, extensions::VIEW_TYPE_TAB_CONTENTS);
233 #endif
234 InfoBarService::CreateForWebContents(new_tab);
235 PermissionBubbleManager::CreateForWebContents(new_tab);
236 PermissionBubbleManager::FromWebContents(new_tab)->SetView(&bubble_view_);
238 extra_tabs_.push_back(new_tab);
241 void GeolocationPermissionContextTests::CheckTabContentsState(
242 const GURL& requesting_frame,
243 ContentSetting expected_content_setting) {
244 TabSpecificContentSettings* content_settings =
245 TabSpecificContentSettings::FromWebContents(web_contents());
246 const ContentSettingsUsagesState::StateMap& state_map =
247 content_settings->geolocation_usages_state().state_map();
248 EXPECT_EQ(1U, state_map.count(requesting_frame.GetOrigin()));
249 EXPECT_EQ(0U, state_map.count(requesting_frame));
250 ContentSettingsUsagesState::StateMap::const_iterator settings =
251 state_map.find(requesting_frame.GetOrigin());
252 ASSERT_FALSE(settings == state_map.end())
253 << "geolocation state not found " << requesting_frame;
254 EXPECT_EQ(expected_content_setting, settings->second);
257 void GeolocationPermissionContextTests::SetUp() {
258 ChromeRenderViewHostTestHarness::SetUp();
260 // Set up required helpers, and make this be as "tabby" as the code requires.
261 #if defined(ENABLE_EXTENSIONS)
262 extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS);
263 #endif
264 InfoBarService::CreateForWebContents(web_contents());
265 TabSpecificContentSettings::CreateForWebContents(web_contents());
266 geolocation_permission_context_ =
267 GeolocationPermissionContextFactory::GetForProfile(profile());
268 #if defined(OS_ANDROID)
269 static_cast<GeolocationPermissionContextAndroid*>(
270 geolocation_permission_context_)
271 ->SetLocationSettingsForTesting(
272 scoped_ptr<LocationSettings>(new MockLocationSettings()));
273 MockLocationSettings::SetLocationStatus(true, true);
274 #endif
275 PermissionBubbleManager::CreateForWebContents(web_contents());
276 PermissionBubbleManager::FromWebContents(web_contents())->SetView(
277 &bubble_view_);
280 void GeolocationPermissionContextTests::TearDown() {
281 extra_tabs_.clear();
282 ChromeRenderViewHostTestHarness::TearDown();
285 size_t GeolocationPermissionContextTests::GetBubblesQueueSize(
286 PermissionBubbleManager* manager) {
287 return manager->requests_.size();
290 void GeolocationPermissionContextTests::AcceptBubble(
291 PermissionBubbleManager* manager) {
292 manager->Accept();
295 void GeolocationPermissionContextTests::DenyBubble(
296 PermissionBubbleManager* manager) {
297 manager->Deny();
300 void GeolocationPermissionContextTests::CloseBubble(
301 PermissionBubbleManager* manager) {
302 manager->Closing();
305 void GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted() {
306 GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted(
307 web_contents());
310 void GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted(
311 content::WebContents* web_contents) {
312 PermissionBubbleManager::FromWebContents(web_contents)->
313 DocumentOnLoadCompletedInMainFrame();
316 ContentSetting GeolocationPermissionContextTests::GetGeolocationContentSetting(
317 GURL frame_0, GURL frame_1) {
318 return profile()->GetHostContentSettingsMap()->GetContentSetting(
319 frame_0, frame_1, CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string());
322 // Needed to parameterize the tests for both infobars & permission bubbles.
323 class GeolocationPermissionContextParamTests :
324 public GeolocationPermissionContextTests,
325 public ::testing::WithParamInterface<bool> {
326 protected:
327 GeolocationPermissionContextParamTests() {}
328 ~GeolocationPermissionContextParamTests() override {}
330 bool BubbleEnabled() const {
331 #if defined (OS_ANDROID)
332 return false;
333 #else
334 return GetParam();
335 #endif
338 void SetUp() override {
339 GeolocationPermissionContextTests::SetUp();
340 #if !defined(OS_ANDROID)
341 if (BubbleEnabled()) {
342 base::CommandLine::ForCurrentProcess()->AppendSwitch(
343 switches::kEnablePermissionsBubbles);
344 EXPECT_TRUE(PermissionBubbleManager::Enabled());
345 } else {
346 base::CommandLine::ForCurrentProcess()->AppendSwitch(
347 switches::kDisablePermissionsBubbles);
348 EXPECT_FALSE(PermissionBubbleManager::Enabled());
350 #endif
353 size_t GetNumberOfPrompts() {
354 if (BubbleEnabled()) {
355 PermissionBubbleManager* manager =
356 PermissionBubbleManager::FromWebContents(web_contents());
357 return GetBubblesQueueSize(manager);
358 } else {
359 return infobar_service()->infobar_count();
363 void AcceptPrompt() {
364 if (BubbleEnabled()) {
365 PermissionBubbleManager* manager =
366 PermissionBubbleManager::FromWebContents(web_contents());
367 AcceptBubble(manager);
368 } else {
369 infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
370 ConfirmInfoBarDelegate* infobar_delegate =
371 infobar->delegate()->AsConfirmInfoBarDelegate();
372 infobar_delegate->Accept();
376 base::string16 GetPromptText() {
377 if (BubbleEnabled()) {
378 PermissionBubbleManager* manager =
379 PermissionBubbleManager::FromWebContents(web_contents());
380 return manager->requests_.front()->GetMessageText();
382 infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
383 ConfirmInfoBarDelegate* infobar_delegate =
384 infobar->delegate()->AsConfirmInfoBarDelegate();
385 return infobar_delegate->GetMessageText();
387 private:
388 DISALLOW_COPY_AND_ASSIGN(GeolocationPermissionContextParamTests);
391 // Tests ----------------------------------------------------------------------
393 TEST_P(GeolocationPermissionContextParamTests, SinglePermissionInfobar) {
394 if (BubbleEnabled()) return;
396 GURL requesting_frame("http://www.example.com/geolocation");
397 NavigateAndCommit(requesting_frame);
398 EXPECT_EQ(0U, infobar_service()->infobar_count());
399 RequestGeolocationPermission(
400 web_contents(), RequestID(0), requesting_frame, true);
401 ASSERT_EQ(1U, infobar_service()->infobar_count());
402 infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
403 ConfirmInfoBarDelegate* infobar_delegate =
404 infobar->delegate()->AsConfirmInfoBarDelegate();
405 ASSERT_TRUE(infobar_delegate);
406 infobar_delegate->Cancel();
407 infobar_service()->RemoveInfoBar(infobar);
408 EXPECT_EQ(1U, closed_infobar_tracker_.size());
409 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar));
412 TEST_P(GeolocationPermissionContextParamTests, SinglePermissionBubble) {
413 if (!BubbleEnabled()) return;
415 GURL requesting_frame("http://www.example.com/geolocation");
416 NavigateAndCommit(requesting_frame);
417 BubbleManagerDocumentLoadCompleted();
419 EXPECT_EQ(0U, GetNumberOfPrompts());
420 RequestGeolocationPermission(
421 web_contents(), RequestID(0), requesting_frame, true);
422 ASSERT_EQ(1U, GetNumberOfPrompts());
425 #if defined(OS_ANDROID)
426 // Infobar-only tests; Android doesn't support permission bubbles.
427 TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
428 GURL requesting_frame("http://www.example.com/geolocation");
429 NavigateAndCommit(requesting_frame);
430 MockLocationSettings::SetLocationStatus(true, true);
431 EXPECT_EQ(0U, infobar_service()->infobar_count());
432 RequestGeolocationPermission(
433 web_contents(), RequestID(0), requesting_frame, true);
434 EXPECT_EQ(1U, infobar_service()->infobar_count());
435 ConfirmInfoBarDelegate* infobar_delegate_0 =
436 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
437 ASSERT_TRUE(infobar_delegate_0);
438 base::string16 text_0 = infobar_delegate_0->GetButtonLabel(
439 ConfirmInfoBarDelegate::BUTTON_OK);
441 Reload();
442 MockLocationSettings::SetLocationStatus(true, false);
443 EXPECT_EQ(0U, infobar_service()->infobar_count());
444 RequestGeolocationPermission(
445 web_contents(), RequestID(0), requesting_frame, true);
446 EXPECT_EQ(0U, infobar_service()->infobar_count());
449 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) {
450 GURL requesting_frame("http://www.example.com/geolocation");
451 NavigateAndCommit(requesting_frame);
452 MockLocationSettings::SetLocationStatus(true, true);
453 EXPECT_EQ(0U, infobar_service()->infobar_count());
454 RequestGeolocationPermission(
455 web_contents(), RequestID(0), requesting_frame, true);
456 EXPECT_EQ(1U, infobar_service()->infobar_count());
457 ConfirmInfoBarDelegate* infobar_delegate =
458 infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
459 ASSERT_TRUE(infobar_delegate);
460 infobar_delegate->Accept();
461 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
462 CheckPermissionMessageSent(0, true);
465 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) {
466 GURL requesting_frame("http://www.example.com/geolocation");
467 NavigateAndCommit(requesting_frame);
468 MockLocationSettings::SetLocationStatus(true, false);
469 EXPECT_EQ(0U, infobar_service()->infobar_count());
470 RequestGeolocationPermission(
471 web_contents(), RequestID(0), requesting_frame, true);
472 EXPECT_EQ(0U, infobar_service()->infobar_count());
474 #endif
476 TEST_P(GeolocationPermissionContextParamTests, QueuedPermission) {
477 GURL requesting_frame_0("http://www.example.com/geolocation");
478 GURL requesting_frame_1("http://www.example-2.com/geolocation");
479 EXPECT_EQ(
480 CONTENT_SETTING_ASK,
481 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_1));
482 EXPECT_EQ(
483 CONTENT_SETTING_ASK,
484 GetGeolocationContentSetting(requesting_frame_1, requesting_frame_1));
486 NavigateAndCommit(requesting_frame_0);
487 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
489 // Check that no permission requests have happened yet.
490 EXPECT_EQ(0U, GetNumberOfPrompts());
492 // Request permission for two frames.
493 RequestGeolocationPermission(
494 web_contents(), RequestID(0), requesting_frame_0, true);
495 RequestGeolocationPermission(
496 web_contents(), RequestID(1), requesting_frame_1, true);
497 // Ensure only one infobar is created.
498 ASSERT_EQ(1U, GetNumberOfPrompts());
499 base::string16 text_0 = GetPromptText();
501 // Accept the first frame.
502 AcceptPrompt();
503 CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW);
504 CheckPermissionMessageSent(0, true);
506 if (!BubbleEnabled()) {
507 infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0);
508 infobar_service()->RemoveInfoBar(infobar_0);
509 EXPECT_EQ(1U, closed_infobar_tracker_.size());
510 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
511 closed_infobar_tracker_.Clear();
514 // Now we should have a new infobar for the second frame.
515 ASSERT_EQ(1U, GetNumberOfPrompts());
516 base::string16 text_1 = GetPromptText();
518 // Check that the messages differ.
519 EXPECT_NE(text_0, text_1);
521 // Cancel (block) this frame.
522 if (BubbleEnabled()) {
523 PermissionBubbleManager* manager =
524 PermissionBubbleManager::FromWebContents(web_contents());
525 DenyBubble(manager);
526 } else {
527 infobars::InfoBar* infobar_1 = infobar_service()->infobar_at(0);
528 infobar_1->delegate()->AsConfirmInfoBarDelegate()->Cancel();
530 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK);
531 CheckPermissionMessageSent(1, false);
533 // Ensure the persisted permissions are ok.
534 EXPECT_EQ(
535 CONTENT_SETTING_ALLOW,
536 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_0));
537 EXPECT_EQ(
538 CONTENT_SETTING_BLOCK,
539 GetGeolocationContentSetting(requesting_frame_1, requesting_frame_0));
542 TEST_P(GeolocationPermissionContextParamTests, HashIsIgnored) {
543 GURL url_a("http://www.example.com/geolocation#a");
544 GURL url_b("http://www.example.com/geolocation#b");
546 // Navigate to the first url.
547 NavigateAndCommit(url_a);
548 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
550 // Check permission is requested.
551 ASSERT_EQ(0U, GetNumberOfPrompts());
552 RequestGeolocationPermission(
553 web_contents(), RequestID(0), url_a, BubbleEnabled());
554 ASSERT_EQ(1U, GetNumberOfPrompts());
556 // Change the hash, we'll still be on the same page.
557 NavigateAndCommit(url_b);
558 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
560 // Accept.
561 AcceptPrompt();
562 CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW);
563 CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW);
564 CheckPermissionMessageSent(0, true);
566 // Cleanup.
567 if (!BubbleEnabled()) {
568 infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
569 infobar_service()->RemoveInfoBar(infobar);
570 EXPECT_EQ(1U, closed_infobar_tracker_.size());
571 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar));
575 TEST_P(GeolocationPermissionContextParamTests, PermissionForFileScheme) {
576 // TODO(felt): The bubble is rejecting file:// permission requests.
577 // Fix and enable this test. crbug.com/444047
578 if (BubbleEnabled()) return;
580 GURL requesting_frame("file://example/geolocation.html");
581 NavigateAndCommit(requesting_frame);
582 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
584 // Check permission is requested.
585 ASSERT_EQ(0U, GetNumberOfPrompts());
586 RequestGeolocationPermission(
587 web_contents(), RequestID(0), requesting_frame, true);
588 EXPECT_EQ(1U, GetNumberOfPrompts());
590 // Accept the frame.
591 AcceptPrompt();
592 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
593 CheckPermissionMessageSent(0, true);
595 // Make sure the setting is not stored.
596 EXPECT_EQ(
597 CONTENT_SETTING_ASK,
598 GetGeolocationContentSetting(requesting_frame, requesting_frame));
601 TEST_P(GeolocationPermissionContextParamTests,
602 CancelGeolocationPermissionRequest) {
603 GURL frame_0("http://www.example.com/geolocation");
604 GURL frame_1("http://www.example-2.com/geolocation");
605 EXPECT_EQ(
606 CONTENT_SETTING_ASK, GetGeolocationContentSetting(frame_0, frame_0));
607 EXPECT_EQ(
608 CONTENT_SETTING_ASK, GetGeolocationContentSetting(frame_1, frame_0));
610 NavigateAndCommit(frame_0);
611 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
613 ASSERT_EQ(0U, GetNumberOfPrompts());
615 // Request permission for two frames.
616 RequestGeolocationPermission(
617 web_contents(), RequestID(0), frame_0, true);
618 RequestGeolocationPermission(
619 web_contents(), RequestID(1), frame_1, true);
621 // Get the first permission request text.
622 ASSERT_EQ(1U, GetNumberOfPrompts());
623 base::string16 text_0 = GetPromptText();
624 ASSERT_FALSE(text_0.empty());
626 // Simulate the frame going away; the request should be removed.
627 if (BubbleEnabled()) {
628 PermissionBubbleManager* manager =
629 PermissionBubbleManager::FromWebContents(web_contents());
630 CloseBubble(manager);
631 } else {
632 geolocation_permission_context_->CancelPermissionRequest(web_contents(),
633 RequestID(0));
636 // Check that the next pending request is created correctly.
637 base::string16 text_1 = GetPromptText();
638 EXPECT_NE(text_0, text_1);
640 // Allow this frame and check that it worked.
641 AcceptPrompt();
642 CheckTabContentsState(frame_1, CONTENT_SETTING_ALLOW);
643 CheckPermissionMessageSent(1, true);
645 // Ensure the persisted permissions are ok.
646 EXPECT_EQ(
647 CONTENT_SETTING_ASK, GetGeolocationContentSetting(frame_0, frame_0));
648 EXPECT_EQ(
649 CONTENT_SETTING_ALLOW, GetGeolocationContentSetting(frame_1, frame_0));
652 TEST_P(GeolocationPermissionContextParamTests, InvalidURL) {
653 // Navigate to the first url.
654 GURL invalid_embedder("about:blank");
655 GURL requesting_frame;
656 NavigateAndCommit(invalid_embedder);
657 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
659 // Nothing should be displayed.
660 EXPECT_EQ(0U, GetNumberOfPrompts());
661 RequestGeolocationPermission(
662 web_contents(), RequestID(0), requesting_frame, true);
663 EXPECT_EQ(0U, GetNumberOfPrompts());
664 CheckPermissionMessageSent(0, false);
667 TEST_P(GeolocationPermissionContextParamTests, SameOriginMultipleTabs) {
668 GURL url_a("http://www.example.com/geolocation");
669 GURL url_b("http://www.example-2.com/geolocation");
670 NavigateAndCommit(url_a); // Tab A0
671 AddNewTab(url_b); // Tab B (extra_tabs_[0])
672 AddNewTab(url_a); // Tab A1 (extra_tabs_[1])
673 if (BubbleEnabled()) {
674 BubbleManagerDocumentLoadCompleted();
675 BubbleManagerDocumentLoadCompleted(extra_tabs_[0]);
676 BubbleManagerDocumentLoadCompleted(extra_tabs_[1]);
678 PermissionBubbleManager* manager_a0 =
679 PermissionBubbleManager::FromWebContents(web_contents());
680 PermissionBubbleManager* manager_b =
681 PermissionBubbleManager::FromWebContents(extra_tabs_[0]);
682 PermissionBubbleManager* manager_a1 =
683 PermissionBubbleManager::FromWebContents(extra_tabs_[1]);
685 // Request permission in all three tabs.
686 RequestGeolocationPermission(
687 web_contents(), RequestID(0), url_a, true);
688 RequestGeolocationPermission(
689 extra_tabs_[0], RequestIDForTab(0, 0), url_b, true);
690 RequestGeolocationPermission(
691 extra_tabs_[1], RequestIDForTab(1, 0), url_a, true);
692 ASSERT_EQ(1U, GetNumberOfPrompts()); // For A0.
693 if (BubbleEnabled()) {
694 ASSERT_EQ(1U, GetBubblesQueueSize(manager_b));
695 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1));
696 } else {
697 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
698 ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
701 // Accept the permission in tab A0.
702 if (BubbleEnabled()) {
703 AcceptBubble(manager_a0);
704 } else {
705 infobars::InfoBar* infobar_a0 = infobar_service()->infobar_at(0);
706 ConfirmInfoBarDelegate* infobar_delegate_a0 =
707 infobar_a0->delegate()->AsConfirmInfoBarDelegate();
708 ASSERT_TRUE(infobar_delegate_a0);
709 infobar_delegate_a0->Accept();
710 infobar_service()->RemoveInfoBar(infobar_a0);
711 EXPECT_EQ(2U, closed_infobar_tracker_.size());
712 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_a0));
714 CheckPermissionMessageSent(0, true);
715 // Because they're the same origin, this will cause tab A1's infobar to
716 // disappear. It does not cause the bubble to disappear: crbug.com/443013.
717 // TODO(felt): Update this test when the bubble's behavior is changed.
718 if (BubbleEnabled())
719 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1));
720 else
721 CheckPermissionMessageSentForTab(1, 0, true);
723 // Either way, tab B should still have a pending permission request.
724 if (BubbleEnabled())
725 ASSERT_EQ(1U, GetBubblesQueueSize(manager_b));
726 else
727 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
730 TEST_P(GeolocationPermissionContextParamTests, QueuedOriginMultipleTabs) {
731 GURL url_a("http://www.example.com/geolocation");
732 GURL url_b("http://www.example-2.com/geolocation");
733 NavigateAndCommit(url_a); // Tab A0.
734 AddNewTab(url_a); // Tab A1.
735 if (BubbleEnabled()) {
736 BubbleManagerDocumentLoadCompleted();
737 BubbleManagerDocumentLoadCompleted(extra_tabs_[0]);
739 PermissionBubbleManager* manager_a0 =
740 PermissionBubbleManager::FromWebContents(web_contents());
741 PermissionBubbleManager* manager_a1 =
742 PermissionBubbleManager::FromWebContents(extra_tabs_[0]);
744 // Request permission in both tabs; the extra tab will have two permission
745 // requests from two origins.
746 RequestGeolocationPermission(
747 web_contents(), RequestID(0), url_a, true);
748 RequestGeolocationPermission(
749 extra_tabs_[0], RequestIDForTab(0, 0), url_a, true);
750 RequestGeolocationPermission(
751 extra_tabs_[0], RequestIDForTab(0, 1), url_b, true);
752 if (BubbleEnabled()) {
753 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a0));
754 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1));
755 } else {
756 ASSERT_EQ(1U, infobar_service()->infobar_count());
757 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
760 // Accept the first request in tab A1.
761 if (BubbleEnabled()) {
762 AcceptBubble(manager_a1);
763 } else {
764 infobars::InfoBar* infobar_a1 = infobar_service_for_tab(0)->infobar_at(0);
765 ConfirmInfoBarDelegate* infobar_delegate_a1 =
766 infobar_a1->delegate()->AsConfirmInfoBarDelegate();
767 ASSERT_TRUE(infobar_delegate_a1);
768 infobar_delegate_a1->Accept();
769 infobar_service_for_tab(0)->RemoveInfoBar(infobar_a1);
770 EXPECT_EQ(2U, closed_infobar_tracker_.size());
771 EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_a1));
773 CheckPermissionMessageSentForTab(0, 0, true);
775 // Because they're the same origin, this will cause tab A0's infobar to
776 // disappear. It does not cause the bubble to disappear: crbug.com/443013.
777 // TODO(felt): Update this test when the bubble's behavior is changed.
778 if (BubbleEnabled()) {
779 EXPECT_EQ(1U, GetBubblesQueueSize(manager_a0));
780 } else {
781 EXPECT_EQ(0U, infobar_service()->infobar_count());
782 CheckPermissionMessageSent(0, true);
785 // The second request should now be visible in tab A1.
786 if (BubbleEnabled())
787 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1));
788 else
789 ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
791 // Accept the second request and check that it's gone.
792 if (BubbleEnabled()) {
793 AcceptBubble(manager_a1);
794 EXPECT_EQ(0U, GetBubblesQueueSize(manager_a1));
795 } else {
796 infobars::InfoBar* infobar_1 = infobar_service_for_tab(0)->infobar_at(0);
797 ConfirmInfoBarDelegate* infobar_delegate_1 =
798 infobar_1->delegate()->AsConfirmInfoBarDelegate();
799 ASSERT_TRUE(infobar_delegate_1);
800 infobar_delegate_1->Accept();
804 TEST_P(GeolocationPermissionContextParamTests, TabDestroyed) {
805 GURL requesting_frame_0("http://www.example.com/geolocation");
806 GURL requesting_frame_1("http://www.example-2.com/geolocation");
807 EXPECT_EQ(
808 CONTENT_SETTING_ASK,
809 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_0));
810 EXPECT_EQ(
811 CONTENT_SETTING_ASK,
812 GetGeolocationContentSetting(requesting_frame_1, requesting_frame_0));
814 NavigateAndCommit(requesting_frame_0);
815 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
817 // Request permission for two frames.
818 RequestGeolocationPermission(
819 web_contents(), RequestID(0), requesting_frame_0, false);
820 RequestGeolocationPermission(
821 web_contents(), RequestID(1), requesting_frame_1, false);
823 // Ensure only one prompt is created.
824 ASSERT_EQ(1U, GetNumberOfPrompts());
826 // Delete the tab contents.
827 if (!BubbleEnabled()) {
828 infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
829 DeleteContents();
830 ASSERT_EQ(1U, closed_infobar_tracker_.size());
831 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar));
834 // The content settings should not have changed.
835 EXPECT_EQ(
836 CONTENT_SETTING_ASK,
837 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_0));
838 EXPECT_EQ(
839 CONTENT_SETTING_ASK,
840 GetGeolocationContentSetting(requesting_frame_1, requesting_frame_0));
843 TEST_P(GeolocationPermissionContextParamTests, LastUsageAudited) {
844 GURL requesting_frame("http://www.example.com/geolocation");
845 NavigateAndCommit(requesting_frame);
846 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
848 base::SimpleTestClock* test_clock = new base::SimpleTestClock;
849 test_clock->SetNow(base::Time::UnixEpoch() +
850 base::TimeDelta::FromSeconds(10));
852 HostContentSettingsMap* map = profile()->GetHostContentSettingsMap();
853 map->SetPrefClockForTesting(scoped_ptr<base::Clock>(test_clock));
855 // The permission shouldn't have been used yet.
856 EXPECT_EQ(map->GetLastUsage(requesting_frame.GetOrigin(),
857 requesting_frame.GetOrigin(),
858 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
860 ASSERT_EQ(0U, GetNumberOfPrompts());
861 RequestGeolocationPermission(
862 web_contents(), RequestID(0), requesting_frame, false);
863 ASSERT_EQ(1U, GetNumberOfPrompts());
865 AcceptPrompt();
866 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
867 CheckPermissionMessageSent(0, true);
869 // Permission has been used at the starting time.
870 EXPECT_EQ(map->GetLastUsage(requesting_frame.GetOrigin(),
871 requesting_frame.GetOrigin(),
872 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
873 10);
875 test_clock->Advance(base::TimeDelta::FromSeconds(3));
876 RequestGeolocationPermission(
877 web_contents(), RequestID(0), requesting_frame, false);
879 // Permission has been used three seconds later.
880 EXPECT_EQ(map->GetLastUsage(requesting_frame.GetOrigin(),
881 requesting_frame.GetOrigin(),
882 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
883 13);
886 TEST_P(GeolocationPermissionContextParamTests, LastUsageAuditedMultipleFrames) {
887 base::SimpleTestClock* test_clock = new base::SimpleTestClock;
888 test_clock->SetNow(base::Time::UnixEpoch() +
889 base::TimeDelta::FromSeconds(10));
891 HostContentSettingsMap* map = profile()->GetHostContentSettingsMap();
892 map->SetPrefClockForTesting(scoped_ptr<base::Clock>(test_clock));
894 GURL requesting_frame_0("http://www.example.com/geolocation");
895 GURL requesting_frame_1("http://www.example-2.com/geolocation");
897 // The permission shouldn't have been used yet.
898 EXPECT_EQ(map->GetLastUsage(requesting_frame_0.GetOrigin(),
899 requesting_frame_0.GetOrigin(),
900 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
902 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(),
903 requesting_frame_0.GetOrigin(),
904 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
907 NavigateAndCommit(requesting_frame_0);
908 if (BubbleEnabled()) BubbleManagerDocumentLoadCompleted();
910 EXPECT_EQ(0U, GetNumberOfPrompts());
912 // Request permission for two frames.
913 RequestGeolocationPermission(
914 web_contents(), RequestID(0), requesting_frame_0, false);
915 RequestGeolocationPermission(
916 web_contents(), RequestID(1), requesting_frame_1, false);
918 // Ensure only one infobar is created.
919 ASSERT_EQ(1U, GetNumberOfPrompts());
921 // Accept the first frame.
922 AcceptPrompt();
923 if (!BubbleEnabled())
924 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0));
925 CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW);
926 CheckPermissionMessageSent(0, true);
928 // Verify that accepting the first didn't accept because it's embedded
929 // in the other.
930 EXPECT_EQ(map->GetLastUsage(requesting_frame_0.GetOrigin(),
931 requesting_frame_0.GetOrigin(),
932 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
933 10);
934 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(),
935 requesting_frame_0.GetOrigin(),
936 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
939 ASSERT_EQ(1U, GetNumberOfPrompts());
941 test_clock->Advance(base::TimeDelta::FromSeconds(1));
943 // Allow the second frame.
944 AcceptPrompt();
945 CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW);
946 CheckPermissionMessageSent(1, true);
947 if (!BubbleEnabled())
948 infobar_service()->RemoveInfoBar(infobar_service()->infobar_at(0));
950 // Verify that the times are different.
951 EXPECT_EQ(map->GetLastUsage(requesting_frame_0.GetOrigin(),
952 requesting_frame_0.GetOrigin(),
953 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
954 10);
955 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(),
956 requesting_frame_0.GetOrigin(),
957 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
958 11);
960 test_clock->Advance(base::TimeDelta::FromSeconds(2));
961 RequestGeolocationPermission(
962 web_contents(), RequestID(0), requesting_frame_0, false);
964 // Verify that requesting permission in one frame doesn't update other where
965 // it is the embedder.
966 EXPECT_EQ(map->GetLastUsage(requesting_frame_0.GetOrigin(),
967 requesting_frame_0.GetOrigin(),
968 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
969 13);
970 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(),
971 requesting_frame_0.GetOrigin(),
972 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
973 11);
976 INSTANTIATE_TEST_CASE_P(GeolocationPermissionContextTestsWithAndWithoutBubbles,
977 GeolocationPermissionContextParamTests,
978 ::testing::Values(false, true));