- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / geolocation / chrome_geolocation_permission_context_unittest.cc
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.
4
5 #include "chrome/browser/geolocation/chrome_geolocation_permission_context.h"
6
7 #include <set>
8 #include <string>
9 #include <utility>
10
11 #include "base/bind.h"
12 #include "base/containers/hash_tables.h"
13 #include "base/memory/scoped_vector.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "chrome/browser/chrome_notification_types.h"
16 #include "chrome/browser/content_settings/host_content_settings_map.h"
17 #include "chrome/browser/content_settings/permission_request_id.h"
18 #include "chrome/browser/content_settings/tab_specific_content_settings.h"
19 #include "chrome/browser/geolocation/chrome_geolocation_permission_context_factory.h"
20 #include "chrome/browser/infobars/confirm_infobar_delegate.h"
21 #include "chrome/browser/infobars/infobar.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 "content/public/browser/navigation_details.h"
26 #include "content/public/browser/notification_registrar.h"
27 #include "content/public/browser/notification_service.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/test/mock_render_process_host.h"
30 #include "content/public/test/test_renderer_host.h"
31 #include "content/public/test/web_contents_tester.h"
32 #include "extensions/browser/view_type_utils.h"
33 #include "testing/gtest/include/gtest/gtest.h"
34
35 #if defined(OS_ANDROID)
36 #include "base/prefs/pref_service.h"
37 #include "chrome/browser/android/mock_google_location_settings_helper.h"
38 #include "chrome/common/pref_names.h"
39 #endif
40
41 using content::MockRenderProcessHost;
42
43
44 // ClosedInfoBarTracker -------------------------------------------------------
45
46 // We need to track which infobars were closed.
47 class ClosedInfoBarTracker : public content::NotificationObserver {
48  public:
49   ClosedInfoBarTracker();
50   virtual ~ClosedInfoBarTracker();
51
52   // content::NotificationObserver:
53   virtual void Observe(int type,
54                        const content::NotificationSource& source,
55                        const content::NotificationDetails& details) OVERRIDE;
56
57   size_t size() const { return removed_infobars_.size(); }
58
59   bool Contains(InfoBarDelegate* infobar) const;
60   void Clear();
61
62  private:
63   FRIEND_TEST_ALL_PREFIXES(GeolocationPermissionContextTests, TabDestroyed);
64   content::NotificationRegistrar registrar_;
65   std::set<InfoBarDelegate*> removed_infobars_;
66 };
67
68 ClosedInfoBarTracker::ClosedInfoBarTracker() {
69   registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED,
70                  content::NotificationService::AllSources());
71 }
72
73 ClosedInfoBarTracker::~ClosedInfoBarTracker() {
74 }
75
76 void ClosedInfoBarTracker::Observe(
77     int type,
78     const content::NotificationSource& source,
79     const content::NotificationDetails& details) {
80   DCHECK(type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_REMOVED);
81   removed_infobars_.insert(
82       content::Details<InfoBarRemovedDetails>(details)->first);
83 }
84
85 bool ClosedInfoBarTracker::Contains(InfoBarDelegate* infobar) const {
86   return removed_infobars_.count(infobar) != 0;
87 }
88
89 void ClosedInfoBarTracker::Clear() {
90   removed_infobars_.clear();
91 }
92
93
94 // GeolocationPermissionContextTests ------------------------------------------
95
96 class GeolocationPermissionContextTests
97     : public ChromeRenderViewHostTestHarness {
98  protected:
99   // ChromeRenderViewHostTestHarness:
100   virtual void SetUp() OVERRIDE;
101   virtual void TearDown() OVERRIDE;
102
103   PermissionRequestID RequestID(int bridge_id);
104   PermissionRequestID RequestIDForTab(int tab, int bridge_id);
105   InfoBarService* infobar_service() {
106     return InfoBarService::FromWebContents(web_contents());
107   }
108   InfoBarService* infobar_service_for_tab(int tab) {
109     return InfoBarService::FromWebContents(extra_tabs_[tab]);
110   }
111
112   void RequestGeolocationPermission(const PermissionRequestID& id,
113                                     const GURL& requesting_frame);
114   void CancelGeolocationPermissionRequest(const PermissionRequestID& id,
115                                           const GURL& requesting_frame);
116   void PermissionResponse(const PermissionRequestID& id,
117                           bool allowed);
118   void CheckPermissionMessageSent(int bridge_id, bool allowed);
119   void CheckPermissionMessageSentForTab(int tab, int bridge_id, bool allowed);
120   void CheckPermissionMessageSentInternal(MockRenderProcessHost* process,
121                                           int bridge_id,
122                                           bool allowed);
123   void AddNewTab(const GURL& url);
124   void CheckTabContentsState(const GURL& requesting_frame,
125                              ContentSetting expected_content_setting);
126
127   scoped_refptr<ChromeGeolocationPermissionContext>
128       geolocation_permission_context_;
129   ClosedInfoBarTracker closed_infobar_tracker_;
130   ScopedVector<content::WebContents> extra_tabs_;
131
132   // A map between renderer child id and a pair represending the bridge id and
133   // whether the requested permission was allowed.
134   base::hash_map<int, std::pair<int, bool> > responses_;
135 };
136
137 PermissionRequestID GeolocationPermissionContextTests::RequestID(
138     int bridge_id) {
139   return PermissionRequestID(
140       web_contents()->GetRenderProcessHost()->GetID(),
141       web_contents()->GetRenderViewHost()->GetRoutingID(),
142       bridge_id);
143 }
144
145 PermissionRequestID GeolocationPermissionContextTests::RequestIDForTab(
146     int tab,
147     int bridge_id) {
148   return PermissionRequestID(
149       extra_tabs_[tab]->GetRenderProcessHost()->GetID(),
150       extra_tabs_[tab]->GetRenderViewHost()->GetRoutingID(),
151       bridge_id);
152 }
153
154 void GeolocationPermissionContextTests::RequestGeolocationPermission(
155     const PermissionRequestID& id,
156     const GURL& requesting_frame) {
157   geolocation_permission_context_->RequestGeolocationPermission(
158       id.render_process_id(), id.render_view_id(), id.bridge_id(),
159       requesting_frame,
160       base::Bind(&GeolocationPermissionContextTests::PermissionResponse,
161                  base::Unretained(this), id));
162 }
163
164 void GeolocationPermissionContextTests::CancelGeolocationPermissionRequest(
165     const PermissionRequestID& id,
166     const GURL& requesting_frame) {
167   geolocation_permission_context_->CancelGeolocationPermissionRequest(
168       id.render_process_id(), id.render_view_id(), id.bridge_id(),
169       requesting_frame);
170 }
171
172 void GeolocationPermissionContextTests::PermissionResponse(
173     const PermissionRequestID& id,
174     bool allowed) {
175   responses_[id.render_process_id()] = std::make_pair(id.bridge_id(), allowed);
176 }
177
178 void GeolocationPermissionContextTests::CheckPermissionMessageSent(
179     int bridge_id,
180     bool allowed) {
181   CheckPermissionMessageSentInternal(process(), bridge_id, allowed);
182 }
183
184 void GeolocationPermissionContextTests::CheckPermissionMessageSentForTab(
185     int tab,
186     int bridge_id,
187     bool allowed) {
188   CheckPermissionMessageSentInternal(static_cast<MockRenderProcessHost*>(
189       extra_tabs_[tab]->GetRenderProcessHost()),
190       bridge_id, allowed);
191 }
192
193 void GeolocationPermissionContextTests::CheckPermissionMessageSentInternal(
194     MockRenderProcessHost* process,
195     int bridge_id,
196     bool allowed) {
197   ASSERT_EQ(responses_.count(process->GetID()), 1U);
198   EXPECT_EQ(bridge_id, responses_[process->GetID()].first);
199   EXPECT_EQ(allowed, responses_[process->GetID()].second);
200   responses_.erase(process->GetID());
201 }
202
203 void GeolocationPermissionContextTests::AddNewTab(const GURL& url) {
204   content::WebContents* new_tab = content::WebContents::Create(
205       content::WebContents::CreateParams(profile()));
206   new_tab->GetController().LoadURL(
207       url, content::Referrer(), content::PAGE_TRANSITION_TYPED, std::string());
208   content::RenderViewHostTester::For(new_tab->GetRenderViewHost())->
209       SendNavigate(extra_tabs_.size() + 1, url);
210
211   // Set up required helpers, and make this be as "tabby" as the code requires.
212   extensions::SetViewType(new_tab, extensions::VIEW_TYPE_TAB_CONTENTS);
213   InfoBarService::CreateForWebContents(new_tab);
214
215   extra_tabs_.push_back(new_tab);
216 }
217
218 void GeolocationPermissionContextTests::CheckTabContentsState(
219     const GURL& requesting_frame,
220     ContentSetting expected_content_setting) {
221   TabSpecificContentSettings* content_settings =
222       TabSpecificContentSettings::FromWebContents(web_contents());
223   const ContentSettingsUsagesState::StateMap& state_map =
224       content_settings->geolocation_usages_state().state_map();
225   EXPECT_EQ(1U, state_map.count(requesting_frame.GetOrigin()));
226   EXPECT_EQ(0U, state_map.count(requesting_frame));
227   ContentSettingsUsagesState::StateMap::const_iterator settings =
228       state_map.find(requesting_frame.GetOrigin());
229   ASSERT_FALSE(settings == state_map.end())
230       << "geolocation state not found " << requesting_frame;
231   EXPECT_EQ(expected_content_setting, settings->second);
232 }
233
234 void GeolocationPermissionContextTests::SetUp() {
235   ChromeRenderViewHostTestHarness::SetUp();
236
237   // Set up required helpers, and make this be as "tabby" as the code requires.
238   extensions::SetViewType(web_contents(), extensions::VIEW_TYPE_TAB_CONTENTS);
239   InfoBarService::CreateForWebContents(web_contents());
240   TabSpecificContentSettings::CreateForWebContents(web_contents());
241 #if defined(OS_ANDROID)
242   MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
243 #endif
244   geolocation_permission_context_ =
245       ChromeGeolocationPermissionContextFactory::GetForProfile(profile());
246 }
247
248 void GeolocationPermissionContextTests::TearDown() {
249   extra_tabs_.clear();
250   ChromeRenderViewHostTestHarness::TearDown();
251 }
252
253 // Tests ----------------------------------------------------------------------
254
255 TEST_F(GeolocationPermissionContextTests, SinglePermission) {
256   GURL requesting_frame("http://www.example.com/geolocation");
257   NavigateAndCommit(requesting_frame);
258   EXPECT_EQ(0U, infobar_service()->infobar_count());
259   RequestGeolocationPermission(RequestID(0), requesting_frame);
260   ASSERT_EQ(1U, infobar_service()->infobar_count());
261   ConfirmInfoBarDelegate* infobar_delegate =
262       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
263   ASSERT_TRUE(infobar_delegate);
264   infobar_delegate->Cancel();
265   infobar_service()->RemoveInfoBar(infobar_delegate);
266   EXPECT_EQ(1U, closed_infobar_tracker_.size());
267   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate));
268   delete infobar_delegate;
269 }
270
271 #if defined(OS_ANDROID)
272 TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
273   GURL requesting_frame("http://www.example.com/geolocation");
274   NavigateAndCommit(requesting_frame);
275   MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
276   EXPECT_EQ(0U, infobar_service()->infobar_count());
277   RequestGeolocationPermission(RequestID(0), requesting_frame);
278   EXPECT_EQ(1U, infobar_service()->infobar_count());
279   ConfirmInfoBarDelegate* infobar_delegate_0 =
280       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
281   ASSERT_TRUE(infobar_delegate_0);
282   string16 text_0 = infobar_delegate_0->GetButtonLabel(
283       ConfirmInfoBarDelegate::BUTTON_OK);
284
285   NavigateAndCommit(requesting_frame);
286   MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
287   EXPECT_EQ(0U, infobar_service()->infobar_count());
288   RequestGeolocationPermission(RequestID(0), requesting_frame);
289   EXPECT_EQ(1U, infobar_service()->infobar_count());
290   ConfirmInfoBarDelegate* infobar_delegate_1 =
291       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
292   ASSERT_TRUE(infobar_delegate_1);
293   string16 text_1 = infobar_delegate_1->GetButtonLabel(
294       ConfirmInfoBarDelegate::BUTTON_OK);
295   EXPECT_NE(text_0, text_1);
296
297   NavigateAndCommit(requesting_frame);
298   MockGoogleLocationSettingsHelper::SetLocationStatus(false, false);
299   EXPECT_EQ(0U, infobar_service()->infobar_count());
300   RequestGeolocationPermission(RequestID(0), requesting_frame);
301   EXPECT_EQ(0U, infobar_service()->infobar_count());
302 }
303
304 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) {
305   GURL requesting_frame("http://www.example.com/geolocation");
306   NavigateAndCommit(requesting_frame);
307   MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
308   EXPECT_EQ(0U, infobar_service()->infobar_count());
309   RequestGeolocationPermission(RequestID(0), requesting_frame);
310   EXPECT_EQ(1U, infobar_service()->infobar_count());
311   ConfirmInfoBarDelegate* infobar_delegate =
312       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
313   ASSERT_TRUE(infobar_delegate);
314   infobar_delegate->Accept();
315   CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
316   CheckPermissionMessageSent(0, true);
317 }
318
319 TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) {
320   GURL requesting_frame("http://www.example.com/geolocation");
321   NavigateAndCommit(requesting_frame);
322   MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
323   EXPECT_EQ(0U, infobar_service()->infobar_count());
324   RequestGeolocationPermission(RequestID(0), requesting_frame);
325   EXPECT_EQ(1U, infobar_service()->infobar_count());
326   ConfirmInfoBarDelegate* infobar_delegate =
327       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
328   ASSERT_TRUE(infobar_delegate);
329   infobar_delegate->Accept();
330   EXPECT_TRUE(
331       MockGoogleLocationSettingsHelper::WasGoogleLocationSettingsCalled());
332 }
333 #endif
334
335 TEST_F(GeolocationPermissionContextTests, QueuedPermission) {
336   GURL requesting_frame_0("http://www.example.com/geolocation");
337   GURL requesting_frame_1("http://www.example-2.com/geolocation");
338   EXPECT_EQ(CONTENT_SETTING_ASK,
339             profile()->GetHostContentSettingsMap()->GetContentSetting(
340                 requesting_frame_0, requesting_frame_0,
341                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
342   EXPECT_EQ(CONTENT_SETTING_ASK,
343             profile()->GetHostContentSettingsMap()->GetContentSetting(
344                 requesting_frame_1, requesting_frame_0,
345                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
346
347   NavigateAndCommit(requesting_frame_0);
348   EXPECT_EQ(0U, infobar_service()->infobar_count());
349   // Request permission for two frames.
350   RequestGeolocationPermission(RequestID(0), requesting_frame_0);
351   RequestGeolocationPermission(RequestID(1), requesting_frame_1);
352   // Ensure only one infobar is created.
353   ASSERT_EQ(1U, infobar_service()->infobar_count());
354   ConfirmInfoBarDelegate* infobar_delegate_0 =
355       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
356   ASSERT_TRUE(infobar_delegate_0);
357   string16 text_0 = infobar_delegate_0->GetMessageText();
358
359   // Accept the first frame.
360   infobar_delegate_0->Accept();
361   CheckTabContentsState(requesting_frame_0, CONTENT_SETTING_ALLOW);
362   CheckPermissionMessageSent(0, true);
363
364   infobar_service()->RemoveInfoBar(infobar_delegate_0);
365   EXPECT_EQ(1U, closed_infobar_tracker_.size());
366   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
367   closed_infobar_tracker_.Clear();
368   delete infobar_delegate_0;
369   // Now we should have a new infobar for the second frame.
370   ASSERT_EQ(1U, infobar_service()->infobar_count());
371
372   ConfirmInfoBarDelegate* infobar_delegate_1 =
373       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
374   ASSERT_TRUE(infobar_delegate_1);
375   string16 text_1 = infobar_delegate_1->GetMessageText();
376   EXPECT_NE(text_0, text_1);
377
378   // Cancel (block) this frame.
379   infobar_delegate_1->Cancel();
380   CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_BLOCK);
381   CheckPermissionMessageSent(1, false);
382   infobar_service()->RemoveInfoBar(infobar_delegate_1);
383   EXPECT_EQ(1U, closed_infobar_tracker_.size());
384   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
385   delete infobar_delegate_1;
386   EXPECT_EQ(0U, infobar_service()->infobar_count());
387   // Ensure the persisted permissions are ok.
388   EXPECT_EQ(CONTENT_SETTING_ALLOW,
389             profile()->GetHostContentSettingsMap()->GetContentSetting(
390                 requesting_frame_0, requesting_frame_0,
391                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
392
393   EXPECT_EQ(CONTENT_SETTING_BLOCK,
394             profile()->GetHostContentSettingsMap()->GetContentSetting(
395                 requesting_frame_1, requesting_frame_0,
396                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
397 }
398
399 TEST_F(GeolocationPermissionContextTests, HashIsIgnored) {
400   GURL url_a("http://www.example.com/geolocation#a");
401   GURL url_b("http://www.example.com/geolocation#b");
402
403   // Navigate to the first url and check permission is requested.
404   NavigateAndCommit(url_a);
405   EXPECT_EQ(0U, infobar_service()->infobar_count());
406   RequestGeolocationPermission(RequestID(0), url_a);
407   ASSERT_EQ(1U, infobar_service()->infobar_count());
408   ConfirmInfoBarDelegate* infobar_delegate =
409       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
410   ASSERT_TRUE(infobar_delegate);
411
412   // Change the hash, we'll still be on the same page.
413   NavigateAndCommit(url_b);
414
415   // Accept.
416   infobar_delegate->Accept();
417   CheckTabContentsState(url_a, CONTENT_SETTING_ALLOW);
418   CheckTabContentsState(url_b, CONTENT_SETTING_ALLOW);
419   CheckPermissionMessageSent(0, true);
420
421   // Cleanup.
422   infobar_service()->RemoveInfoBar(infobar_delegate);
423   EXPECT_EQ(1U, closed_infobar_tracker_.size());
424   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate));
425   closed_infobar_tracker_.Clear();
426   delete infobar_delegate;
427 }
428
429 TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) {
430   GURL requesting_frame("file://example/geolocation.html");
431   NavigateAndCommit(requesting_frame);
432   EXPECT_EQ(0U, infobar_service()->infobar_count());
433   RequestGeolocationPermission(RequestID(0), requesting_frame);
434   EXPECT_EQ(1U, infobar_service()->infobar_count());
435   ConfirmInfoBarDelegate* infobar_delegate =
436       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
437   ASSERT_TRUE(infobar_delegate);
438   // Accept the frame.
439   infobar_delegate->Accept();
440   CheckTabContentsState(requesting_frame, CONTENT_SETTING_ALLOW);
441   CheckPermissionMessageSent(0, true);
442   infobar_service()->RemoveInfoBar(infobar_delegate);
443   delete infobar_delegate;
444
445   // Make sure the setting is not stored.
446   EXPECT_EQ(CONTENT_SETTING_ASK,
447       profile()->GetHostContentSettingsMap()->GetContentSetting(
448           requesting_frame,
449           requesting_frame,
450           CONTENT_SETTINGS_TYPE_GEOLOCATION,
451           std::string()));
452 }
453
454 TEST_F(GeolocationPermissionContextTests, CancelGeolocationPermissionRequest) {
455   GURL requesting_frame_0("http://www.example.com/geolocation");
456   GURL requesting_frame_1("http://www.example-2.com/geolocation");
457   EXPECT_EQ(CONTENT_SETTING_ASK,
458             profile()->GetHostContentSettingsMap()->GetContentSetting(
459                 requesting_frame_0, requesting_frame_0,
460                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
461
462   EXPECT_EQ(CONTENT_SETTING_ASK,
463             profile()->GetHostContentSettingsMap()->GetContentSetting(
464                 requesting_frame_1, requesting_frame_0,
465                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
466
467   NavigateAndCommit(requesting_frame_0);
468   EXPECT_EQ(0U, infobar_service()->infobar_count());
469   // Request permission for two frames.
470   RequestGeolocationPermission(RequestID(0), requesting_frame_0);
471   RequestGeolocationPermission(RequestID(1), requesting_frame_1);
472   ASSERT_EQ(1U, infobar_service()->infobar_count());
473
474   ConfirmInfoBarDelegate* infobar_delegate_0 =
475       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
476   ASSERT_TRUE(infobar_delegate_0);
477   string16 text_0 = infobar_delegate_0->GetMessageText();
478
479   // Simulate the frame going away, ensure the infobar for this frame
480   // is removed and the next pending infobar is created.
481   CancelGeolocationPermissionRequest(RequestID(0), requesting_frame_0);
482   EXPECT_EQ(1U, closed_infobar_tracker_.size());
483   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
484   closed_infobar_tracker_.Clear();
485   delete infobar_delegate_0;
486   ASSERT_EQ(1U, infobar_service()->infobar_count());
487
488   ConfirmInfoBarDelegate* infobar_delegate_1 =
489       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
490   ASSERT_TRUE(infobar_delegate_1);
491   string16 text_1 = infobar_delegate_1->GetMessageText();
492   EXPECT_NE(text_0, text_1);
493
494   // Allow this frame.
495   infobar_delegate_1->Accept();
496   CheckTabContentsState(requesting_frame_1, CONTENT_SETTING_ALLOW);
497   CheckPermissionMessageSent(1, true);
498   infobar_service()->RemoveInfoBar(infobar_delegate_1);
499   EXPECT_EQ(1U, closed_infobar_tracker_.size());
500   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
501   delete infobar_delegate_1;
502   EXPECT_EQ(0U, infobar_service()->infobar_count());
503   // Ensure the persisted permissions are ok.
504   EXPECT_EQ(CONTENT_SETTING_ASK,
505             profile()->GetHostContentSettingsMap()->GetContentSetting(
506                 requesting_frame_0, requesting_frame_0,
507                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
508
509   EXPECT_EQ(CONTENT_SETTING_ALLOW,
510             profile()->GetHostContentSettingsMap()->GetContentSetting(
511                 requesting_frame_1, requesting_frame_0,
512                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
513 }
514
515 TEST_F(GeolocationPermissionContextTests, InvalidURL) {
516   GURL invalid_embedder("about:blank");
517   GURL requesting_frame;
518   NavigateAndCommit(invalid_embedder);
519   EXPECT_EQ(0U, infobar_service()->infobar_count());
520   RequestGeolocationPermission(RequestID(0), requesting_frame);
521   EXPECT_EQ(0U, infobar_service()->infobar_count());
522   CheckPermissionMessageSent(0, false);
523 }
524
525 TEST_F(GeolocationPermissionContextTests, SameOriginMultipleTabs) {
526   GURL url_a("http://www.example.com/geolocation");
527   GURL url_b("http://www.example-2.com/geolocation");
528   NavigateAndCommit(url_a);
529   AddNewTab(url_b);
530   AddNewTab(url_a);
531
532   EXPECT_EQ(0U, infobar_service()->infobar_count());
533   RequestGeolocationPermission(RequestID(0), url_a);
534   ASSERT_EQ(1U, infobar_service()->infobar_count());
535
536   RequestGeolocationPermission(RequestIDForTab(0, 0), url_b);
537   EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
538
539   RequestGeolocationPermission(RequestIDForTab(1, 0), url_a);
540   ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
541
542   ConfirmInfoBarDelegate* removed_infobar =
543       infobar_service_for_tab(1)->infobar_at(0)->AsConfirmInfoBarDelegate();
544
545   // Accept the first tab.
546   ConfirmInfoBarDelegate* infobar_delegate_0 =
547       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
548   ASSERT_TRUE(infobar_delegate_0);
549   infobar_delegate_0->Accept();
550   CheckPermissionMessageSent(0, true);
551   infobar_service()->RemoveInfoBar(infobar_delegate_0);
552   EXPECT_EQ(2U, closed_infobar_tracker_.size());
553   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
554   delete infobar_delegate_0;
555   // Now the infobar for the tab with the same origin should have gone.
556   EXPECT_EQ(0U, infobar_service_for_tab(1)->infobar_count());
557   CheckPermissionMessageSentForTab(1, 0, true);
558   EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
559   closed_infobar_tracker_.Clear();
560   // Destroy the infobar that has just been removed.
561   delete removed_infobar;
562
563   // But the other tab should still have the info bar...
564   ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
565   ConfirmInfoBarDelegate* infobar_delegate_1 =
566       infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
567   infobar_delegate_1->Cancel();
568   infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1);
569   EXPECT_EQ(1U, closed_infobar_tracker_.size());
570   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
571   delete infobar_delegate_1;
572 }
573
574 TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) {
575   GURL url_a("http://www.example.com/geolocation");
576   GURL url_b("http://www.example-2.com/geolocation");
577   NavigateAndCommit(url_a);
578   AddNewTab(url_a);
579
580   EXPECT_EQ(0U, infobar_service()->infobar_count());
581   RequestGeolocationPermission(RequestID(0), url_a);
582   ASSERT_EQ(1U, infobar_service()->infobar_count());
583
584   RequestGeolocationPermission(RequestIDForTab(0, 0), url_a);
585   EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
586
587   RequestGeolocationPermission(RequestIDForTab(0, 1), url_b);
588   ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
589
590   ConfirmInfoBarDelegate* removed_infobar =
591       infobar_service()->infobar_at(0)->AsConfirmInfoBarDelegate();
592
593   // Accept the second tab.
594   ConfirmInfoBarDelegate* infobar_delegate_0 =
595       infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
596   ASSERT_TRUE(infobar_delegate_0);
597   infobar_delegate_0->Accept();
598   CheckPermissionMessageSentForTab(0, 0, true);
599   infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_0);
600   EXPECT_EQ(2U, closed_infobar_tracker_.size());
601   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_0));
602   delete infobar_delegate_0;
603   // Now the infobar for the tab with the same origin should have gone.
604   EXPECT_EQ(0U, infobar_service()->infobar_count());
605   CheckPermissionMessageSent(0, true);
606   EXPECT_TRUE(closed_infobar_tracker_.Contains(removed_infobar));
607   closed_infobar_tracker_.Clear();
608   delete removed_infobar;
609
610   // And we should have the queued infobar displayed now.
611   ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
612
613   // Accept the second infobar.
614   ConfirmInfoBarDelegate* infobar_delegate_1 =
615       infobar_service_for_tab(0)->infobar_at(0)->AsConfirmInfoBarDelegate();
616   ASSERT_TRUE(infobar_delegate_1);
617   infobar_delegate_1->Accept();
618   CheckPermissionMessageSentForTab(0, 1, true);
619   infobar_service_for_tab(0)->RemoveInfoBar(infobar_delegate_1);
620   EXPECT_EQ(1U, closed_infobar_tracker_.size());
621   EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_delegate_1));
622   delete infobar_delegate_1;
623 }
624
625 TEST_F(GeolocationPermissionContextTests, TabDestroyed) {
626   GURL requesting_frame_0("http://www.example.com/geolocation");
627   GURL requesting_frame_1("http://www.example-2.com/geolocation");
628   EXPECT_EQ(CONTENT_SETTING_ASK,
629             profile()->GetHostContentSettingsMap()->GetContentSetting(
630                 requesting_frame_0, requesting_frame_0,
631                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
632
633   EXPECT_EQ(CONTENT_SETTING_ASK,
634             profile()->GetHostContentSettingsMap()->GetContentSetting(
635                 requesting_frame_1, requesting_frame_0,
636                 CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string()));
637
638   NavigateAndCommit(requesting_frame_0);
639   EXPECT_EQ(0U, infobar_service()->infobar_count());
640   // Request permission for two frames.
641   RequestGeolocationPermission(RequestID(0), requesting_frame_0);
642   RequestGeolocationPermission(RequestID(1), requesting_frame_1);
643   // Ensure only one infobar is created.
644   ASSERT_EQ(1U, infobar_service()->infobar_count());
645   InfoBarDelegate* infobar = infobar_service()->infobar_at(0);
646
647   // Delete the tab contents.
648   DeleteContents();
649   delete infobar;
650
651   // During contents destruction, the infobar will have been closed, and the
652   // pending request should have been cleared without an infobar being created.
653   ASSERT_EQ(1U, closed_infobar_tracker_.size());
654   ASSERT_TRUE(closed_infobar_tracker_.Contains(infobar));
655 }
656
657 TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) {
658   GURL requesting_frame_0("http://www.example.com/geolocation");
659   GURL requesting_frame_1("http://www.example-2.com/geolocation");
660   NavigateAndCommit(requesting_frame_0);
661   NavigateAndCommit(requesting_frame_1);
662   EXPECT_EQ(0U, infobar_service()->infobar_count());
663   // Go back: navigate to a pending entry before requesting geolocation
664   // permission.
665   web_contents()->GetController().GoBack();
666   // Request permission for the committed frame (not the pending one).
667   RequestGeolocationPermission(RequestID(0), requesting_frame_1);
668   // Ensure the infobar is created.
669   ASSERT_EQ(1U, infobar_service()->infobar_count());
670   InfoBarDelegate* infobar_delegate = infobar_service()->infobar_at(0);
671   ASSERT_TRUE(infobar_delegate);
672   // Ensure the infobar wouldn't expire for a navigation to the committed entry.
673   content::LoadCommittedDetails details;
674   details.entry = web_contents()->GetController().GetLastCommittedEntry();
675   EXPECT_FALSE(infobar_delegate->ShouldExpire(details));
676   // Ensure the infobar will expire when we commit the pending navigation.
677   details.entry = web_contents()->GetController().GetActiveEntry();
678   EXPECT_TRUE(infobar_delegate->ShouldExpire(details));
679
680   // Delete the tab contents.
681   DeleteContents();
682   delete infobar_delegate;
683 }