• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "base/compiler_specific.h"
6 #include "base/string_number_conversions.h"
7 #include "base/string_util.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/dom_operation_notification_details.h"
10 #include "chrome/browser/geolocation/geolocation_content_settings_map.h"
11 #include "chrome/browser/geolocation/geolocation_settings_state.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/common/chrome_paths.h"
17 #include "chrome/test/in_process_browser_test.h"
18 #include "chrome/test/ui_test_utils.h"
19 #include "content/browser/geolocation/arbitrator_dependency_factories_for_test.h"
20 #include "content/browser/geolocation/location_arbitrator.h"
21 #include "content/browser/geolocation/mock_location_provider.h"
22 #include "content/browser/renderer_host/render_view_host.h"
23 #include "content/browser/tab_contents/tab_contents.h"
24 #include "content/common/geoposition.h"
25 #include "content/common/notification_details.h"
26 #include "content/common/notification_service.h"
27 #include "content/common/notification_type.h"
28 #include "net/base/net_util.h"
29 #include "net/test/test_server.h"
30 
31 namespace {
32 
33 // Used to block until an iframe is loaded via a javascript call.
34 // Note: NavigateToURLBlockUntilNavigationsComplete doesn't seem to work for
35 // multiple embedded iframes, as notifications seem to be 'batched'. Instead, we
36 // load and wait one single frame here by calling a javascript function.
37 class IFrameLoader : public NotificationObserver {
38  public:
IFrameLoader(Browser * browser,int iframe_id,const GURL & url)39   IFrameLoader(Browser* browser, int iframe_id, const GURL& url)
40       : navigation_completed_(false),
41         javascript_completed_(false) {
42     NavigationController* controller =
43         &browser->GetSelectedTabContents()->controller();
44     registrar_.Add(this, NotificationType::LOAD_STOP,
45                    Source<NavigationController>(controller));
46     registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
47                    NotificationService::AllSources());
48     std::string script = StringPrintf(
49         "window.domAutomationController.setAutomationId(0);"
50         "window.domAutomationController.send(addIFrame(%d, \"%s\"));",
51         iframe_id,
52         url.spec().c_str());
53     browser->GetSelectedTabContents()->render_view_host()->
54         ExecuteJavascriptInWebFrame(string16(), UTF8ToUTF16(script));
55     ui_test_utils::RunMessageLoop();
56 
57     EXPECT_EQ(StringPrintf("\"%d\"", iframe_id), javascript_response_);
58     registrar_.RemoveAll();
59     // Now that we loaded the iframe, let's fetch its src.
60     script = StringPrintf(
61         "window.domAutomationController.send(getIFrameSrc(%d))", iframe_id);
62     std::string iframe_src;
63     EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
64         browser->GetSelectedTabContents()->render_view_host(),
65         L"", UTF8ToWide(script), &iframe_src));
66     iframe_url_ = GURL(iframe_src);
67   }
68 
iframe_url() const69   GURL iframe_url() const { return iframe_url_; }
70 
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)71   virtual void Observe(NotificationType type,
72                        const NotificationSource& source,
73                        const NotificationDetails& details) {
74     if (type == NotificationType::LOAD_STOP) {
75       navigation_completed_ = true;
76     } else if (type == NotificationType::DOM_OPERATION_RESPONSE) {
77       Details<DomOperationNotificationDetails> dom_op_details(details);
78       javascript_response_ = dom_op_details->json();
79       javascript_completed_ = true;
80     }
81     if (javascript_completed_ && navigation_completed_)
82       MessageLoopForUI::current()->Quit();
83   }
84 
85  private:
86   NotificationRegistrar registrar_;
87 
88   // If true the navigation has completed.
89   bool navigation_completed_;
90 
91   // If true the javascript call has completed.
92   bool javascript_completed_;
93 
94   std::string javascript_response_;
95 
96   // The URL for the iframe we just loaded.
97   GURL iframe_url_;
98 
99   DISALLOW_COPY_AND_ASSIGN(IFrameLoader);
100 };
101 
102 class GeolocationNotificationObserver : public NotificationObserver {
103  public:
104   // If |wait_for_infobar| is true, AddWatchAndWaitForNotification will block
105   // until the infobar has been displayed; otherwise it will block until the
106   // navigation is completed.
GeolocationNotificationObserver(bool wait_for_infobar)107   explicit GeolocationNotificationObserver(bool wait_for_infobar)
108     : wait_for_infobar_(wait_for_infobar),
109       infobar_(NULL),
110       navigation_started_(false),
111       navigation_completed_(false) {
112     registrar_.Add(this, NotificationType::DOM_OPERATION_RESPONSE,
113                    NotificationService::AllSources());
114     if (wait_for_infobar) {
115       registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_ADDED,
116                      NotificationService::AllSources());
117     } else {
118       registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
119                      NotificationService::AllSources());
120       registrar_.Add(this, NotificationType::LOAD_START,
121                      NotificationService::AllSources());
122       registrar_.Add(this, NotificationType::LOAD_STOP,
123                      NotificationService::AllSources());
124     }
125   }
126 
AddWatchAndWaitForNotification(RenderViewHost * render_view_host,const std::wstring & iframe_xpath)127   void AddWatchAndWaitForNotification(RenderViewHost* render_view_host,
128                                       const std::wstring& iframe_xpath) {
129     LOG(WARNING) << "will add geolocation watch";
130     std::string script =
131         "window.domAutomationController.setAutomationId(0);"
132         "window.domAutomationController.send(geoStart());";
133     render_view_host->ExecuteJavascriptInWebFrame(WideToUTF16Hack(iframe_xpath),
134                                                   UTF8ToUTF16(script));
135     ui_test_utils::RunMessageLoop();
136     registrar_.RemoveAll();
137     LOG(WARNING) << "got geolocation watch" << javascript_response_;
138     EXPECT_NE("\"0\"", javascript_response_);
139     if (wait_for_infobar_) {
140       EXPECT_TRUE(infobar_);
141     } else {
142       EXPECT_TRUE(navigation_completed_);
143     }
144   }
145 
146   // NotificationObserver
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)147   virtual void Observe(NotificationType type,
148                        const NotificationSource& source,
149                        const NotificationDetails& details) {
150     if (type.value == NotificationType::TAB_CONTENTS_INFOBAR_ADDED) {
151       infobar_ = Details<InfoBarDelegate>(details).ptr();
152       ASSERT_TRUE(infobar_->GetIcon());
153       ASSERT_TRUE(infobar_->AsConfirmInfoBarDelegate());
154     } else if (type == NotificationType::DOM_OPERATION_RESPONSE) {
155       Details<DomOperationNotificationDetails> dom_op_details(details);
156       javascript_response_ = dom_op_details->json();
157       LOG(WARNING) << "javascript_response " << javascript_response_;
158     } else if (type == NotificationType::NAV_ENTRY_COMMITTED ||
159                type == NotificationType::LOAD_START) {
160       navigation_started_ = true;
161     } else if (type == NotificationType::LOAD_STOP) {
162       if (navigation_started_) {
163         navigation_started_ = false;
164         navigation_completed_ = true;
165       }
166     }
167 
168     // We're either waiting for just the inforbar, or for both a javascript
169     // prompt and response.
170     if (wait_for_infobar_ && infobar_)
171       MessageLoopForUI::current()->Quit();
172     else if (navigation_completed_ && !javascript_response_.empty())
173       MessageLoopForUI::current()->Quit();
174   }
175 
176   NotificationRegistrar registrar_;
177   bool wait_for_infobar_;
178   InfoBarDelegate* infobar_;
179   bool navigation_started_;
180   bool navigation_completed_;
181   std::string javascript_response_;
182 };
183 
NotifyGeoposition(const Geoposition & geoposition)184 void NotifyGeoposition(const Geoposition& geoposition) {
185   DCHECK(MockLocationProvider::instance_);
186   MockLocationProvider::instance_->HandlePositionChanged(geoposition);
187   LOG(WARNING) << "MockLocationProvider listeners updated";
188 }
189 
190 // This is a browser test for Geolocation.
191 // It exercises various integration points from javascript <-> browser:
192 // 1. Infobar is displayed when a geolocation is requested from an unauthorized
193 // origin.
194 // 2. Denying the infobar triggers the correct error callback.
195 // 3. Allowing the infobar does not trigger an error, and allow a geoposition to
196 // be passed to javascript.
197 // 4. Permissions persisted in disk are respected.
198 // 5. Incognito profiles don't use saved permissions.
199 class GeolocationBrowserTest : public InProcessBrowserTest {
200  public:
GeolocationBrowserTest()201   GeolocationBrowserTest()
202     : infobar_(NULL),
203       current_browser_(NULL),
204       html_for_tests_("files/geolocation/simple.html"),
205       started_test_server_(false),
206       dependency_factory_(
207           new GeolocationArbitratorDependencyFactoryWithLocationProvider(
208               &NewAutoSuccessMockNetworkLocationProvider)) {
209     EnableDOMAutomation();
210   }
211 
212   // InProcessBrowserTest
SetUpInProcessBrowserTestFixture()213   virtual void SetUpInProcessBrowserTestFixture() {
214     GeolocationArbitrator::SetDependencyFactoryForTest(
215         dependency_factory_.get());
216   }
217 
218   // InProcessBrowserTest
TearDownInProcessBrowserTestFixture()219   virtual void TearDownInProcessBrowserTestFixture() {
220     LOG(WARNING) << "TearDownInProcessBrowserTestFixture. Test Finished.";
221     GeolocationArbitrator::SetDependencyFactoryForTest(NULL);
222   }
223 
224   enum InitializationOptions {
225     INITIALIZATION_NONE,
226     INITIALIZATION_OFFTHERECORD,
227     INITIALIZATION_NEWTAB,
228     INITIALIZATION_IFRAMES,
229   };
230 
Initialize(InitializationOptions options)231   bool Initialize(InitializationOptions options) WARN_UNUSED_RESULT {
232     if (!started_test_server_)
233       started_test_server_ = test_server()->Start();
234     EXPECT_TRUE(started_test_server_);
235     if (!started_test_server_)
236       return false;
237 
238     current_url_ = test_server()->GetURL(html_for_tests_);
239     LOG(WARNING) << "before navigate";
240     if (options == INITIALIZATION_OFFTHERECORD) {
241       ui_test_utils::OpenURLOffTheRecord(browser()->profile(), current_url_);
242       current_browser_ = BrowserList::FindBrowserWithType(
243           browser()->profile()->GetOffTheRecordProfile(), Browser::TYPE_NORMAL,
244           false);
245     } else if (options == INITIALIZATION_NEWTAB) {
246       current_browser_ = browser();
247       current_browser_->NewTab();
248       ui_test_utils::NavigateToURL(current_browser_, current_url_);
249     } else if (options == INITIALIZATION_IFRAMES) {
250       current_browser_ = browser();
251       ui_test_utils::NavigateToURL(current_browser_, current_url_);
252     } else {
253       current_browser_ = browser();
254       ui_test_utils::NavigateToURL(current_browser_, current_url_);
255     }
256     LOG(WARNING) << "after navigate";
257 
258     EXPECT_TRUE(current_browser_);
259     if (!current_browser_)
260       return false;
261 
262     return true;
263   }
264 
LoadIFrames(int number_iframes)265   void LoadIFrames(int number_iframes) {
266       // Limit to 3 iframes.
267       DCHECK(0 < number_iframes && number_iframes <= 3);
268       iframe_urls_.resize(number_iframes);
269       for (int i = 0; i < number_iframes; ++i) {
270         IFrameLoader loader(current_browser_, i, GURL());
271         iframe_urls_[i] = loader.iframe_url();
272       }
273   }
274 
AddGeolocationWatch(bool wait_for_infobar)275   void AddGeolocationWatch(bool wait_for_infobar) {
276     GeolocationNotificationObserver notification_observer(wait_for_infobar);
277     notification_observer.AddWatchAndWaitForNotification(
278         current_browser_->GetSelectedTabContents()->render_view_host(),
279         iframe_xpath_);
280     if (wait_for_infobar) {
281       EXPECT_TRUE(notification_observer.infobar_);
282       infobar_ = notification_observer.infobar_;
283     }
284   }
285 
GeopositionFromLatLong(double latitude,double longitude)286   Geoposition GeopositionFromLatLong(double latitude, double longitude) {
287     Geoposition geoposition;
288     geoposition.latitude = latitude;
289     geoposition.longitude = longitude;
290     geoposition.accuracy = 0;
291     geoposition.error_code = Geoposition::ERROR_CODE_NONE;
292     // Webkit compares the timestamp to wall clock time, so we need
293     // it to be contemporary.
294     geoposition.timestamp = base::Time::Now();
295     EXPECT_TRUE(geoposition.IsValidFix());
296     return geoposition;
297   }
298 
CheckGeoposition(const Geoposition & geoposition)299   void CheckGeoposition(const Geoposition& geoposition) {
300     // Checks we have no error.
301     CheckStringValueFromJavascript("0", "geoGetLastError()");
302     CheckStringValueFromJavascript(base::DoubleToString(geoposition.latitude),
303                                    "geoGetLastPositionLatitude()");
304     CheckStringValueFromJavascript(base::DoubleToString(geoposition.longitude),
305                                    "geoGetLastPositionLongitude()");
306   }
307 
SetInfobarResponse(const GURL & requesting_url,bool allowed)308   void SetInfobarResponse(const GURL& requesting_url, bool allowed) {
309     TabContents* tab_contents = current_browser_->GetSelectedTabContents();
310     TabSpecificContentSettings* content_settings =
311         tab_contents->GetTabSpecificContentSettings();
312     const GeolocationSettingsState& settings_state =
313         content_settings->geolocation_settings_state();
314     size_t state_map_size = settings_state.state_map().size();
315     ASSERT_TRUE(infobar_);
316     LOG(WARNING) << "will set infobar response";
317     if (allowed)
318       infobar_->AsConfirmInfoBarDelegate()->Accept();
319     else
320       infobar_->AsConfirmInfoBarDelegate()->Cancel();
321     WaitForNavigation();
322     tab_contents->RemoveInfoBar(infobar_);
323     LOG(WARNING) << "infobar response set";
324     infobar_ = NULL;
325     EXPECT_GT(settings_state.state_map().size(), state_map_size);
326     GURL requesting_origin = requesting_url.GetOrigin();
327     EXPECT_EQ(1U, settings_state.state_map().count(requesting_origin));
328     ContentSetting expected_setting =
329           allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
330     EXPECT_EQ(expected_setting,
331               settings_state.state_map().find(requesting_origin)->second);
332   }
333 
WaitForNavigation()334   void WaitForNavigation() {
335     LOG(WARNING) << "will block for navigation";
336     NavigationController* controller =
337         &current_browser_->GetSelectedTabContents()->controller();
338     ui_test_utils::WaitForNavigation(controller);
339     LOG(WARNING) << "navigated";
340   }
341 
CheckStringValueFromJavascriptForTab(const std::string & expected,const std::string & function,TabContents * tab_contents)342   void CheckStringValueFromJavascriptForTab(
343       const std::string& expected, const std::string& function,
344       TabContents* tab_contents) {
345     std::string script = StringPrintf(
346         "window.domAutomationController.send(%s)", function.c_str());
347     std::string result;
348     ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
349         tab_contents->render_view_host(),
350         iframe_xpath_, UTF8ToWide(script), &result));
351     EXPECT_EQ(expected, result);
352   }
353 
CheckStringValueFromJavascript(const std::string & expected,const std::string & function)354   void CheckStringValueFromJavascript(
355       const std::string& expected, const std::string& function) {
356     CheckStringValueFromJavascriptForTab(
357         expected, function, current_browser_->GetSelectedTabContents());
358   }
359 
360   InfoBarDelegate* infobar_;
361   Browser* current_browser_;
362   // path element of a URL referencing the html content for this test.
363   std::string html_for_tests_;
364   // This member defines the iframe (or top-level page, if empty) where the
365   // javascript calls will run.
366   std::wstring iframe_xpath_;
367   // The current url for the top level page.
368   GURL current_url_;
369   // If not empty, the GURLs for the iframes loaded by LoadIFrames().
370   std::vector<GURL> iframe_urls_;
371 
372   // TODO(phajdan.jr): Remove after we can ask TestServer whether it is started.
373   bool started_test_server_;
374 
375   scoped_refptr<GeolocationArbitratorDependencyFactory> dependency_factory_;
376 };
377 
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DisplaysPermissionBar)378 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DisplaysPermissionBar) {
379   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
380   AddGeolocationWatch(true);
381 }
382 
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,Geoposition)383 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, Geoposition) {
384   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
385   AddGeolocationWatch(true);
386   SetInfobarResponse(current_url_, true);
387   CheckGeoposition(MockLocationProvider::instance_->position_);
388 }
389 
390 // Crashy, http://crbug.com/70585.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_ErrorOnPermissionDenied)391 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
392                        DISABLED_ErrorOnPermissionDenied) {
393   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
394   AddGeolocationWatch(true);
395   // Infobar was displayed, deny access and check for error code.
396   SetInfobarResponse(current_url_, false);
397   CheckStringValueFromJavascript("1", "geoGetLastError()");
398 }
399 
400 // http://crbug.com/44589. Hangs on Mac, crashes on Windows
401 #if defined(OS_MACOSX) || defined(OS_WINDOWS)
402 #define MAYBE_NoInfobarForSecondTab DISABLED_NoInfobarForSecondTab
403 #else
404 #define MAYBE_NoInfobarForSecondTab NoInfobarForSecondTab
405 #endif
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,MAYBE_NoInfobarForSecondTab)406 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForSecondTab) {
407   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
408   AddGeolocationWatch(true);
409   SetInfobarResponse(current_url_, true);
410   // Disables further prompts from this tab.
411   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
412 
413   // Checks infobar will not be created a second tab.
414   ASSERT_TRUE(Initialize(INITIALIZATION_NEWTAB));
415   AddGeolocationWatch(false);
416   CheckGeoposition(MockLocationProvider::instance_->position_);
417 }
418 
419 // http://crbug.com/44589. Hangs on Mac, crashes on Windows
420 #if defined(OS_MACOSX) || defined(OS_WINDOWS)
421 #define MAYBE_NoInfobarForDeniedOrigin DISABLED_NoInfobarForDeniedOrigin
422 #else
423 #define MAYBE_NoInfobarForDeniedOrigin NoInfobarForDeniedOrigin
424 #endif
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,MAYBE_NoInfobarForDeniedOrigin)425 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, MAYBE_NoInfobarForDeniedOrigin) {
426   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
427   current_browser_->profile()->GetGeolocationContentSettingsMap()->
428       SetContentSetting(current_url_, current_url_, CONTENT_SETTING_BLOCK);
429   AddGeolocationWatch(false);
430   // Checks we have an error for this denied origin.
431   CheckStringValueFromJavascript("1", "geoGetLastError()");
432   // Checks infobar will not be created a second tab.
433   ASSERT_TRUE(Initialize(INITIALIZATION_NEWTAB));
434   AddGeolocationWatch(false);
435   CheckStringValueFromJavascript("1", "geoGetLastError()");
436 }
437 
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,NoInfobarForAllowedOrigin)438 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForAllowedOrigin) {
439   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
440   current_browser_->profile()->GetGeolocationContentSettingsMap()->
441       SetContentSetting(current_url_, current_url_, CONTENT_SETTING_ALLOW);
442   // Checks no infobar will be created and there's no error callback.
443   AddGeolocationWatch(false);
444   CheckGeoposition(MockLocationProvider::instance_->position_);
445 }
446 
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,NoInfobarForOffTheRecord)447 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForOffTheRecord) {
448   // First, check infobar will be created for regular profile
449   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
450   AddGeolocationWatch(true);
451   // Response will be persisted
452   SetInfobarResponse(current_url_, true);
453   CheckGeoposition(MockLocationProvider::instance_->position_);
454   // Disables further prompts from this tab.
455   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
456   // Go incognito, and checks no infobar will be created.
457   ASSERT_TRUE(Initialize(INITIALIZATION_OFFTHERECORD));
458   AddGeolocationWatch(false);
459   CheckGeoposition(MockLocationProvider::instance_->position_);
460 }
461 
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,IFramesWithFreshPosition)462 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, IFramesWithFreshPosition) {
463   html_for_tests_ = "files/geolocation/iframes_different_origin.html";
464   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
465   LoadIFrames(2);
466   LOG(WARNING) << "frames loaded";
467 
468   iframe_xpath_ = L"//iframe[@id='iframe_0']";
469   AddGeolocationWatch(true);
470   SetInfobarResponse(iframe_urls_[0], true);
471   CheckGeoposition(MockLocationProvider::instance_->position_);
472   // Disables further prompts from this iframe.
473   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
474 
475   // Test second iframe from a different origin with a cached geoposition will
476   // create the infobar.
477   iframe_xpath_ = L"//iframe[@id='iframe_1']";
478   AddGeolocationWatch(true);
479 
480   // Back to the first frame, enable navigation and refresh geoposition.
481   iframe_xpath_ = L"//iframe[@id='iframe_0']";
482   CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
483   // MockLocationProvider must have been created.
484   ASSERT_TRUE(MockLocationProvider::instance_);
485   Geoposition fresh_position = GeopositionFromLatLong(3.17, 4.23);
486   NotifyGeoposition(fresh_position);
487   WaitForNavigation();
488   CheckGeoposition(fresh_position);
489 
490   // Disable navigation for this frame.
491   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
492 
493   // Now go ahead an authorize the second frame.
494   iframe_xpath_ = L"//iframe[@id='iframe_1']";
495   // Infobar was displayed, allow access and check there's no error code.
496   SetInfobarResponse(iframe_urls_[1], true);
497   LOG(WARNING) << "Checking position...";
498   CheckGeoposition(fresh_position);
499   LOG(WARNING) << "...done.";
500 }
501 
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,IFramesWithCachedPosition)502 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, IFramesWithCachedPosition) {
503   html_for_tests_ = "files/geolocation/iframes_different_origin.html";
504   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
505   LoadIFrames(2);
506 
507   iframe_xpath_ = L"//iframe[@id='iframe_0']";
508   AddGeolocationWatch(true);
509   SetInfobarResponse(iframe_urls_[0], true);
510   CheckGeoposition(MockLocationProvider::instance_->position_);
511 
512   // Refresh geoposition, but let's not yet create the watch on the second frame
513   // so that it'll fetch from cache.
514   // MockLocationProvider must have been created.
515   ASSERT_TRUE(MockLocationProvider::instance_);
516   Geoposition cached_position = GeopositionFromLatLong(5.67, 8.09);
517   NotifyGeoposition(cached_position);
518   WaitForNavigation();
519   CheckGeoposition(cached_position);
520 
521   // Disable navigation for this frame.
522   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
523 
524   // Now go ahead an authorize the second frame.
525   iframe_xpath_ = L"//iframe[@id='iframe_1']";
526   AddGeolocationWatch(true);
527   // WebKit will use its cache, but we also broadcast a position shortly
528   // afterwards. We're only interested in the first navigation for the success
529   // callback from the cached position.
530   CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
531   SetInfobarResponse(iframe_urls_[1], true);
532   CheckGeoposition(cached_position);
533 }
534 
535 // See http://crbug.com/56033
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_CancelPermissionForFrame)536 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
537                        DISABLED_CancelPermissionForFrame) {
538   html_for_tests_ = "files/geolocation/iframes_different_origin.html";
539   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
540   LoadIFrames(2);
541   LOG(WARNING) << "frames loaded";
542 
543   iframe_xpath_ = L"//iframe[@id='iframe_0']";
544   AddGeolocationWatch(true);
545   SetInfobarResponse(iframe_urls_[0], true);
546   CheckGeoposition(MockLocationProvider::instance_->position_);
547   // Disables further prompts from this iframe.
548   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
549 
550   // Test second iframe from a different origin with a cached geoposition will
551   // create the infobar.
552   iframe_xpath_ = L"//iframe[@id='iframe_1']";
553   AddGeolocationWatch(true);
554 
555   size_t num_infobars_before_cancel =
556       current_browser_->GetSelectedTabContents()->infobar_count();
557   // Change the iframe, and ensure the infobar is gone.
558   IFrameLoader change_iframe_1(current_browser_, 1, current_url_);
559   size_t num_infobars_after_cancel =
560       current_browser_->GetSelectedTabContents()->infobar_count();
561   EXPECT_EQ(num_infobars_before_cancel, num_infobars_after_cancel + 1);
562 }
563 
564 // Disabled, http://crbug.com/66959.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_InvalidUrlRequest)565 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_InvalidUrlRequest) {
566   // Tests that an invalid URL (e.g. from a popup window) is rejected
567   // correctly. Also acts as a regression test for http://crbug.com/40478
568   html_for_tests_ = "files/geolocation/invalid_request_url.html";
569   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
570   TabContents* original_tab = current_browser_->GetSelectedTabContents();
571   CheckStringValueFromJavascript("1", "requestGeolocationFromInvalidUrl()");
572   CheckStringValueFromJavascriptForTab("1", "isAlive()", original_tab);
573 }
574 
575 // Crashy, http://crbug.com/66400.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_NoInfoBarBeforeStart)576 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_NoInfoBarBeforeStart) {
577   // See http://crbug.com/42789
578   html_for_tests_ = "files/geolocation/iframes_different_origin.html";
579   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
580   LoadIFrames(2);
581   LOG(WARNING) << "frames loaded";
582 
583   // Access navigator.geolocation, but ensure it won't request permission.
584   iframe_xpath_ = L"//iframe[@id='iframe_1']";
585   CheckStringValueFromJavascript("object", "geoAccessNavigatorGeolocation()");
586 
587   iframe_xpath_ = L"//iframe[@id='iframe_0']";
588   AddGeolocationWatch(true);
589   SetInfobarResponse(iframe_urls_[0], true);
590   CheckGeoposition(MockLocationProvider::instance_->position_);
591   CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
592 
593   // Permission should be requested after adding a watch.
594   iframe_xpath_ = L"//iframe[@id='iframe_1']";
595   AddGeolocationWatch(true);
596   SetInfobarResponse(iframe_urls_[1], true);
597   CheckGeoposition(MockLocationProvider::instance_->position_);
598 }
599 
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,TwoWatchesInOneFrame)600 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, TwoWatchesInOneFrame) {
601   html_for_tests_ = "files/geolocation/two_watches.html";
602   ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
603   // First, set the JavaScript to navigate when it receives |final_position|.
604   const Geoposition final_position = GeopositionFromLatLong(3.17, 4.23);
605   std::string script = StringPrintf(
606       "window.domAutomationController.send(geoSetFinalPosition(%f, %f))",
607       final_position.latitude, final_position.longitude);
608   std::string js_result;
609   EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
610       current_browser_->GetSelectedTabContents()->render_view_host(),
611       L"", UTF8ToWide(script), &js_result));
612   EXPECT_EQ(js_result, "ok");
613 
614   // Send a position which both geolocation watches will receive.
615   AddGeolocationWatch(true);
616   SetInfobarResponse(current_url_, true);
617   CheckGeoposition(MockLocationProvider::instance_->position_);
618 
619   // The second watch will now have cancelled. Ensure an update still makes
620   // its way through to the first watcher.
621   NotifyGeoposition(final_position);
622   WaitForNavigation();
623   CheckGeoposition(final_position);
624 }
625 
626 // Hangs flakily, http://crbug.com/70588.
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,DISABLED_TabDestroyed)627 IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_TabDestroyed) {
628   html_for_tests_ = "files/geolocation/tab_destroyed.html";
629   ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
630   LoadIFrames(3);
631 
632   iframe_xpath_ = L"//iframe[@id='iframe_0']";
633   AddGeolocationWatch(true);
634 
635   iframe_xpath_ = L"//iframe[@id='iframe_1']";
636   AddGeolocationWatch(false);
637 
638   iframe_xpath_ = L"//iframe[@id='iframe_2']";
639   AddGeolocationWatch(false);
640 
641   std::string script =
642       "window.domAutomationController.setAutomationId(0);"
643       "window.domAutomationController.send(window.close());";
644   bool result =
645       ui_test_utils::ExecuteJavaScript(
646       current_browser_->GetSelectedTabContents()->render_view_host(),
647       L"", UTF8ToWide(script));
648   EXPECT_EQ(result, true);
649 }
650 
651 }  // namespace
652