Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / geolocation / geolocation_permission_context_unittest.cc
blob790168a13a83f7f0da870ec818bb560e70c9465f
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/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"
51 #endif
53 #if defined(ENABLE_EXTENSIONS)
54 #include "extensions/browser/view_type_utils.h"
55 #endif
57 using content::MockRenderProcessHost;
60 // ClosedInfoBarTracker -------------------------------------------------------
62 // We need to track which infobars were closed.
63 class ClosedInfoBarTracker : public content::NotificationObserver {
64 public:
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;
76 void Clear();
78 private:
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(
93 int type,
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 {
114 protected:
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,
131 bool user_gesture);
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,
138 int request_id,
139 bool allowed);
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();
152 void AcceptPrompt();
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(
166 int request_id) {
167 return PermissionRequestID(
168 web_contents()->GetRenderProcessHost()->GetID(),
169 web_contents()->GetMainFrame()->GetRoutingID(),
170 request_id);
173 PermissionRequestID GeolocationPermissionContextTests::RequestIDForTab(
174 int tab,
175 int request_id) {
176 return PermissionRequestID(
177 extra_tabs_[tab]->GetRenderProcessHost()->GetID(),
178 extra_tabs_[tab]->GetMainFrame()->GetRoutingID(),
179 request_id);
182 void GeolocationPermissionContextTests::RequestGeolocationPermission(
183 content::WebContents* web_contents,
184 const PermissionRequestID& id,
185 const GURL& requesting_frame,
186 bool user_gesture) {
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(
202 int request_id,
203 bool allowed) {
204 CheckPermissionMessageSentInternal(process(), request_id, allowed);
207 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
208 int tab,
209 int request_id,
210 bool allowed) {
211 CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost*>(
212 extra_tabs_[tab]->GetRenderProcessHost()),
213 request_id, allowed);
216 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
217 MockRenderProcessHost* process,
218 int request_id,
219 bool allowed) {
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);
237 #endif
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);
272 #endif
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);
283 #endif
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() {
294 extra_tabs_.clear();
295 ChromeRenderViewHostTestHarness::TearDown();
298 size_t GeolocationPermissionContextTests::GetBubblesQueueSize(
299 PermissionBubbleManager* manager) {
300 return manager->requests_.size();
303 void GeolocationPermissionContextTests::AcceptBubble(
304 PermissionBubbleManager* manager) {
305 manager->Accept();
308 void GeolocationPermissionContextTests::DenyBubble(
309 PermissionBubbleManager* manager) {
310 manager->Deny();
313 void GeolocationPermissionContextTests::CloseBubble(
314 PermissionBubbleManager* manager) {
315 manager->Closing();
318 void GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted() {
319 GeolocationPermissionContextTests::BubbleManagerDocumentLoadCompleted(
320 web_contents());
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);
344 } else {
345 return infobar_service()->infobar_count();
349 void GeolocationPermissionContextTests::AcceptPrompt() {
350 if (BubbleEnabled()) {
351 PermissionBubbleManager* manager =
352 PermissionBubbleManager::FromWebContents(web_contents());
353 AcceptBubble(manager);
354 } else {
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);
424 Reload();
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());
457 #endif
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");
462 EXPECT_EQ(
463 CONTENT_SETTING_ASK,
464 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_1));
465 EXPECT_EQ(
466 CONTENT_SETTING_ASK,
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.
485 AcceptPrompt();
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());
508 DenyBubble(manager);
509 } else {
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.
517 EXPECT_EQ(
518 CONTENT_SETTING_ALLOW,
519 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_0));
520 EXPECT_EQ(
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();
543 // Accept.
544 AcceptPrompt();
545 CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW);
546 CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW);
547 CheckPermissionMessageSent(0, true);
549 // Cleanup.
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());
573 // Accept the frame.
574 AcceptPrompt();
575 CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
576 CheckPermissionMessageSent(0, true);
578 // Make sure the setting is not stored.
579 EXPECT_EQ(
580 CONTENT_SETTING_ASK,
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");
587 EXPECT_EQ(
588 CONTENT_SETTING_ASK, GetGeolocationContentSetting(frame_0, frame_0));
589 EXPECT_EQ(
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);
613 } else {
614 geolocation_permission_context_->CancelPermissionRequest(web_contents(),
615 RequestID(0));
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.
623 AcceptPrompt();
624 CheckTabContentsState(frame_1, CONTENT_SETTING_ALLOW);
625 CheckPermissionMessageSent(1, true);
627 // Ensure the persisted permissions are ok.
628 EXPECT_EQ(
629 CONTENT_SETTING_ASK, GetGeolocationContentSetting(frame_0, frame_0));
630 EXPECT_EQ(
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));
678 } else {
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);
686 } else {
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.
700 if (BubbleEnabled())
701 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1));
702 else
703 CheckPermissionMessageSentForTab(1, 0, true);
705 // Either way, tab B should still have a pending permission request.
706 if (BubbleEnabled())
707 ASSERT_EQ(1U, GetBubblesQueueSize(manager_b));
708 else
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));
737 } else {
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);
745 } else {
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));
762 } else {
763 EXPECT_EQ(0U, infobar_service()->infobar_count());
764 CheckPermissionMessageSent(0, true);
767 // The second request should now be visible in tab A1.
768 if (BubbleEnabled())
769 ASSERT_EQ(1U, GetBubblesQueueSize(manager_a1));
770 else
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));
777 } else {
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");
789 EXPECT_EQ(
790 CONTENT_SETTING_ASK,
791 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_0));
792 EXPECT_EQ(
793 CONTENT_SETTING_ASK,
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);
811 DeleteContents();
812 ASSERT_EQ(1U, closed_infobar_tracker_.size());
813 ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar));
816 // The content settings should not have changed.
817 EXPECT_EQ(
818 CONTENT_SETTING_ASK,
819 GetGeolocationContentSetting(requesting_frame_0, requesting_frame_0));
820 EXPECT_EQ(
821 CONTENT_SETTING_ASK,
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());
847 AcceptPrompt();
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(),
855 10);
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(),
865 13);
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.
904 AcceptPrompt();
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
911 // in the other.
912 EXPECT_EQ(map->GetLastUsage(requesting_frame_0.GetOrigin(),
913 requesting_frame_0.GetOrigin(),
914 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
915 10);
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.
926 AcceptPrompt();
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(),
936 10);
937 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(),
938 requesting_frame_0.GetOrigin(),
939 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
940 11);
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(),
951 13);
952 EXPECT_EQ(map->GetLastUsage(requesting_frame_1.GetOrigin(),
953 requesting_frame_0.GetOrigin(),
954 CONTENT_SETTINGS_TYPE_GEOLOCATION).ToDoubleT(),
955 11);