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