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