// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string>

#include "base/compiler_specific.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/content_settings/content_settings_usages_state.h"
#include "chrome/browser/content_settings/host_content_settings_map.h"
#include "chrome/browser/content_settings/tab_specific_content_settings.h"
#include "chrome/browser/infobars/confirm_infobar_delegate.h"
#include "chrome/browser/infobars/infobar.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/content_settings_pattern.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/browser/dom_operation_notification_details.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "net/base/net_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

using content::DomOperationNotificationDetails;
using content::NavigationController;
using content::WebContents;

namespace {


// IFrameLoader ---------------------------------------------------------------

// Used to block until an iframe is loaded via a javascript call.
// Note: NavigateToURLBlockUntilNavigationsComplete doesn't seem to work for
// multiple embedded iframes, as notifications seem to be 'batched'. Instead, we
// load and wait one single frame here by calling a javascript function.
class IFrameLoader : public content::NotificationObserver {
 public:
  IFrameLoader(Browser* browser, int iframe_id, const GURL& url);
  virtual ~IFrameLoader();

  // content::NotificationObserver:
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  const GURL& iframe_url() const { return iframe_url_; }

 private:
  content::NotificationRegistrar registrar_;

  // If true the navigation has completed.
  bool navigation_completed_;

  // If true the javascript call has completed.
  bool javascript_completed_;

  std::string javascript_response_;

  // The URL for the iframe we just loaded.
  GURL iframe_url_;

  DISALLOW_COPY_AND_ASSIGN(IFrameLoader);
};

IFrameLoader::IFrameLoader(Browser* browser, int iframe_id, const GURL& url)
    : navigation_completed_(false),
      javascript_completed_(false) {
  WebContents* web_contents =
      browser->tab_strip_model()->GetActiveWebContents();
  NavigationController* controller = &web_contents->GetController();
  registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
                 content::Source<NavigationController>(controller));
  registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
                 content::NotificationService::AllSources());
  std::string script(base::StringPrintf(
      "window.domAutomationController.setAutomationId(0);"
      "window.domAutomationController.send(addIFrame(%d, \"%s\"));",
      iframe_id, url.spec().c_str()));
  web_contents->GetRenderViewHost()->ExecuteJavascriptInWebFrame(
      base::string16(), UTF8ToUTF16(script));
  content::RunMessageLoop();

  EXPECT_EQ(base::StringPrintf("\"%d\"", iframe_id), javascript_response_);
  registrar_.RemoveAll();
  // Now that we loaded the iframe, let's fetch its src.
  script = base::StringPrintf(
      "window.domAutomationController.send(getIFrameSrc(%d))", iframe_id);
  std::string iframe_src;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(web_contents, script,
                                                     &iframe_src));
  iframe_url_ = GURL(iframe_src);
}

IFrameLoader::~IFrameLoader() {
}

void IFrameLoader::Observe(int type,
                           const content::NotificationSource& source,
                           const content::NotificationDetails& details) {
  if (type == content::NOTIFICATION_LOAD_STOP) {
    navigation_completed_ = true;
  } else if (type == content::NOTIFICATION_DOM_OPERATION_RESPONSE) {
    content::Details<DomOperationNotificationDetails> dom_op_details(details);
    javascript_response_ = dom_op_details->json;
    javascript_completed_ = true;
  }
  if (javascript_completed_ && navigation_completed_)
    base::MessageLoopForUI::current()->Quit();
}


// GeolocationNotificationObserver --------------------------------------------

class GeolocationNotificationObserver : public content::NotificationObserver {
 public:
  // If |wait_for_infobar| is true, AddWatchAndWaitForNotification will block
  // until the infobar has been displayed; otherwise it will block until the
  // navigation is completed.
  explicit GeolocationNotificationObserver(bool wait_for_infobar);
  virtual ~GeolocationNotificationObserver();

  // content::NotificationObserver:
  virtual void Observe(int type,
                       const content::NotificationSource& source,
                       const content::NotificationDetails& details) OVERRIDE;

  void AddWatchAndWaitForNotification(content::RenderViewHost* render_view_host,
                                      const std::string& iframe_xpath);

  bool has_infobar() const { return !!infobar_; }
  InfoBar* infobar() { return infobar_; }

 private:
  content::NotificationRegistrar registrar_;
  bool wait_for_infobar_;
  InfoBar* infobar_;
  bool navigation_started_;
  bool navigation_completed_;
  std::string javascript_response_;

  DISALLOW_COPY_AND_ASSIGN(GeolocationNotificationObserver);
};

GeolocationNotificationObserver::GeolocationNotificationObserver(
    bool wait_for_infobar)
    : wait_for_infobar_(wait_for_infobar),
      infobar_(NULL),
      navigation_started_(false),
      navigation_completed_(false) {
  registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE,
                 content::NotificationService::AllSources());
  if (wait_for_infobar) {
    registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED,
                   content::NotificationService::AllSources());
  } else {
    registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
                   content::NotificationService::AllSources());
    registrar_.Add(this, content::NOTIFICATION_LOAD_START,
                   content::NotificationService::AllSources());
    registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
                   content::NotificationService::AllSources());
  }
}

GeolocationNotificationObserver::~GeolocationNotificationObserver() {
}

void GeolocationNotificationObserver::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  if (type == chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED) {
    infobar_ = content::Details<InfoBar::AddedDetails>(details).ptr();
    ASSERT_FALSE(infobar_->delegate()->GetIcon().IsEmpty());
    ASSERT_TRUE(infobar_->delegate()->AsConfirmInfoBarDelegate());
  } else if (type == content::NOTIFICATION_DOM_OPERATION_RESPONSE) {
    content::Details<DomOperationNotificationDetails> dom_op_details(details);
    javascript_response_ = dom_op_details->json;
    LOG(WARNING) << "javascript_response " << javascript_response_;
  } else if ((type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) ||
             (type == content::NOTIFICATION_LOAD_START)) {
    navigation_started_ = true;
  } else if ((type == content::NOTIFICATION_LOAD_STOP) && navigation_started_) {
    navigation_started_ = false;
    navigation_completed_ = true;
  }

  // We're either waiting for just the infobar, or for both a javascript
  // prompt and response.
  if ((wait_for_infobar_ && infobar_) ||
      (navigation_completed_ && !javascript_response_.empty()))
    base::MessageLoopForUI::current()->Quit();
}

void GeolocationNotificationObserver::AddWatchAndWaitForNotification(
    content::RenderViewHost* render_view_host,
    const std::string& iframe_xpath) {
  LOG(WARNING) << "will add geolocation watch";
  std::string script(
      "window.domAutomationController.setAutomationId(0);"
      "window.domAutomationController.send(geoStart());");
  render_view_host->ExecuteJavascriptInWebFrame(UTF8ToUTF16(iframe_xpath),
                                                UTF8ToUTF16(script));
  content::RunMessageLoop();
  registrar_.RemoveAll();
  LOG(WARNING) << "got geolocation watch" << javascript_response_;
  EXPECT_NE("\"0\"", javascript_response_);
  EXPECT_TRUE(wait_for_infobar_ ? (infobar_ != NULL) : navigation_completed_);
}

}  // namespace


// GeolocationBrowserTest -----------------------------------------------------

// This is a browser test for Geolocation.
// It exercises various integration points from javascript <-> browser:
// 1. Infobar is displayed when a geolocation is requested from an unauthorized
// origin.
// 2. Denying the infobar triggers the correct error callback.
// 3. Allowing the infobar does not trigger an error, and allow a geoposition to
// be passed to javascript.
// 4. Permissions persisted in disk are respected.
// 5. Incognito profiles don't use saved permissions.
class GeolocationBrowserTest : public InProcessBrowserTest {
 public:
  enum InitializationOptions {
    INITIALIZATION_NONE,
    INITIALIZATION_OFFTHERECORD,
    INITIALIZATION_NEWTAB,
    INITIALIZATION_IFRAMES,
  };

  GeolocationBrowserTest();
  virtual ~GeolocationBrowserTest();

  // InProcessBrowserTest:
  virtual void SetUpOnMainThread() OVERRIDE;
  virtual void TearDownInProcessBrowserTestFixture() OVERRIDE;

  Browser* current_browser() { return current_browser_; }
  void set_html_for_tests(const std::string& html_for_tests) {
    html_for_tests_ = html_for_tests;
  }
  const std::string& iframe_xpath() const { return iframe_xpath_; }
  void set_iframe_xpath(const std::string& iframe_xpath) {
    iframe_xpath_ = iframe_xpath;
  }
  const GURL& current_url() const { return current_url_; }
  const GURL& iframe_url(size_t i) const { return iframe_urls_[i]; }
  double fake_latitude() const { return fake_latitude_; }
  double fake_longitude() const { return fake_longitude_; }

  // Initializes the test server and navigates to the initial url.
  bool Initialize(InitializationOptions options) WARN_UNUSED_RESULT;

  // Loads the specified number of iframes.
  void LoadIFrames(int number_iframes);

  // Start watching for geolocation notifications. If |wait_for_infobar| is
  // true, wait for the infobar to be displayed. Otherwise wait for a javascript
  // response.
  void AddGeolocationWatch(bool wait_for_infobar);

  // Checks that no errors have been received in javascript, and checks that the
  // position most recently received in javascript matches |latitude| and
  // |longitude|.
  void CheckGeoposition(double latitude, double longitude);

  // For |requesting_url| if |allowed| is true accept the infobar. Otherwise
  // cancel it.
  void SetInfoBarResponse(const GURL& requesting_url, bool allowed);

  // Executes |function| in |web_contents| and checks that the return value
  // matches |expected|.
  void CheckStringValueFromJavascriptForTab(const std::string& expected,
                                            const std::string& function,
                                            WebContents* web_contents);

  // Executes |function| and checks that the return value matches |expected|.
  void CheckStringValueFromJavascript(const std::string& expected,
                                      const std::string& function);

  // Sets a new position and sends a notification with the new position.
  void NotifyGeoposition(double latitude, double longitude);

 private:
  InfoBar* infobar_;
  Browser* current_browser_;
  // path element of a URL referencing the html content for this test.
  std::string html_for_tests_;
  // This member defines the iframe (or top-level page, if empty) where the
  // javascript calls will run.
  std::string iframe_xpath_;
  // The current url for the top level page.
  GURL current_url_;
  // If not empty, the GURLs for the iframes loaded by LoadIFrames().
  std::vector<GURL> iframe_urls_;
  double fake_latitude_;
  double fake_longitude_;

  DISALLOW_COPY_AND_ASSIGN(GeolocationBrowserTest);
};

GeolocationBrowserTest::GeolocationBrowserTest()
  : infobar_(NULL),
    current_browser_(NULL),
    html_for_tests_("/geolocation/simple.html"),
    fake_latitude_(1.23),
    fake_longitude_(4.56) {
}

GeolocationBrowserTest::~GeolocationBrowserTest() {
}

void GeolocationBrowserTest::SetUpOnMainThread() {
  ui_test_utils::OverrideGeolocation(fake_latitude_, fake_longitude_);
}

void GeolocationBrowserTest::TearDownInProcessBrowserTestFixture() {
  LOG(WARNING) << "TearDownInProcessBrowserTestFixture. Test Finished.";
}

bool GeolocationBrowserTest::Initialize(InitializationOptions options) {
  if (!embedded_test_server()->Started() &&
      !embedded_test_server()->InitializeAndWaitUntilReady()) {
    ADD_FAILURE() << "Test server failed to start.";
    return false;
  }

  current_url_ = embedded_test_server()->GetURL(html_for_tests_);
  LOG(WARNING) << "before navigate";
  if (options == INITIALIZATION_OFFTHERECORD) {
    current_browser_ = ui_test_utils::OpenURLOffTheRecord(
        browser()->profile(), current_url_);
  } else {
    current_browser_ = browser();
    if (options == INITIALIZATION_NEWTAB)
      chrome::NewTab(current_browser_);
    ui_test_utils::NavigateToURL(current_browser_, current_url_);
  }
  LOG(WARNING) << "after navigate";

  EXPECT_TRUE(current_browser_);
  return !!current_browser_;
}

void GeolocationBrowserTest::LoadIFrames(int number_iframes) {
  // Limit to 3 iframes.
  DCHECK_LT(0, number_iframes);
  DCHECK_LE(number_iframes, 3);
  iframe_urls_.resize(number_iframes);
  for (int i = 0; i < number_iframes; ++i) {
    IFrameLoader loader(current_browser_, i, GURL());
    iframe_urls_[i] = loader.iframe_url();
  }
}

void GeolocationBrowserTest::AddGeolocationWatch(bool wait_for_infobar) {
  GeolocationNotificationObserver notification_observer(wait_for_infobar);
  notification_observer.AddWatchAndWaitForNotification(
      current_browser_->tab_strip_model()->GetActiveWebContents()->
          GetRenderViewHost(),
      iframe_xpath());
  if (wait_for_infobar) {
    EXPECT_TRUE(notification_observer.has_infobar());
    infobar_ = notification_observer.infobar();
  }
}

void GeolocationBrowserTest::CheckGeoposition(double latitude,
                                              double longitude) {
  // Checks we have no error.
  CheckStringValueFromJavascript("0", "geoGetLastError()");
  CheckStringValueFromJavascript(base::DoubleToString(latitude),
                                 "geoGetLastPositionLatitude()");
  CheckStringValueFromJavascript(base::DoubleToString(longitude),
                                 "geoGetLastPositionLongitude()");
}

void GeolocationBrowserTest::SetInfoBarResponse(const GURL& requesting_url,
                                                bool allowed) {
  WebContents* web_contents =
      current_browser_->tab_strip_model()->GetActiveWebContents();
  TabSpecificContentSettings* content_settings =
      TabSpecificContentSettings::FromWebContents(web_contents);
  const ContentSettingsUsagesState& usages_state =
      content_settings->geolocation_usages_state();
  size_t state_map_size = usages_state.state_map().size();
  ASSERT_TRUE(infobar_);
  LOG(WARNING) << "will set infobar response";
  {
    content::WindowedNotificationObserver observer(
        content::NOTIFICATION_LOAD_STOP,
        content::Source<NavigationController>(&web_contents->GetController()));
    if (allowed)
      infobar_->delegate()->AsConfirmInfoBarDelegate()->Accept();
    else
      infobar_->delegate()->AsConfirmInfoBarDelegate()->Cancel();
    observer.Wait();
  }

  InfoBarService::FromWebContents(web_contents)->RemoveInfoBar(infobar_);
  LOG(WARNING) << "infobar response set";
  infobar_ = NULL;
  EXPECT_GT(usages_state.state_map().size(), state_map_size);
  GURL requesting_origin(requesting_url.GetOrigin());
  EXPECT_EQ(1U, usages_state.state_map().count(requesting_origin));
  ContentSetting expected_setting =
        allowed ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
  EXPECT_EQ(expected_setting,
            usages_state.state_map().find(requesting_origin)->second);
}

void GeolocationBrowserTest::CheckStringValueFromJavascriptForTab(
    const std::string& expected,
    const std::string& function,
    WebContents* web_contents) {
  std::string script(base::StringPrintf(
      "window.domAutomationController.send(%s)", function.c_str()));
  std::string result;
  ASSERT_TRUE(content::ExecuteScriptInFrameAndExtractString(
      web_contents, iframe_xpath_, script, &result));
  EXPECT_EQ(expected, result);
}

void GeolocationBrowserTest::CheckStringValueFromJavascript(
    const std::string& expected,
    const std::string& function) {
  CheckStringValueFromJavascriptForTab(
      expected, function,
      current_browser_->tab_strip_model()->GetActiveWebContents());
}

void GeolocationBrowserTest::NotifyGeoposition(double latitude,
                                               double longitude) {
  fake_latitude_ = latitude;
  fake_longitude_ = longitude;
  ui_test_utils::OverrideGeolocation(latitude, longitude);
  LOG(WARNING) << "MockLocationProvider listeners updated";
}


// Tests ----------------------------------------------------------------------

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DisplaysPermissionBar) {
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  AddGeolocationWatch(true);
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, Geoposition) {
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  AddGeolocationWatch(true);
  SetInfoBarResponse(current_url(), true);
  CheckGeoposition(fake_latitude(), fake_longitude());
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
                       ErrorOnPermissionDenied) {
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  AddGeolocationWatch(true);
  // Infobar was displayed, deny access and check for error code.
  SetInfoBarResponse(current_url(), false);
  CheckStringValueFromJavascript("1", "geoGetLastError()");
}

// See http://crbug.com/308358
IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, DISABLED_NoInfobarForSecondTab) {
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  AddGeolocationWatch(true);
  SetInfoBarResponse(current_url(), true);
  // Disables further prompts from this tab.
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");

  // Checks infobar will not be created a second tab.
  ASSERT_TRUE(Initialize(INITIALIZATION_NEWTAB));
  AddGeolocationWatch(false);
  CheckGeoposition(fake_latitude(), fake_longitude());
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForDeniedOrigin) {
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  current_browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(current_url()),
      ContentSettingsPattern::FromURLNoWildcard(current_url()),
      CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string(), CONTENT_SETTING_BLOCK);
  AddGeolocationWatch(false);
  // Checks we have an error for this denied origin.
  CheckStringValueFromJavascript("1", "geoGetLastError()");
  // Checks infobar will not be created a second tab.
  ASSERT_TRUE(Initialize(INITIALIZATION_NEWTAB));
  AddGeolocationWatch(false);
  CheckStringValueFromJavascript("1", "geoGetLastError()");
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForAllowedOrigin) {
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  current_browser()->profile()->GetHostContentSettingsMap()->SetContentSetting(
      ContentSettingsPattern::FromURLNoWildcard(current_url()),
      ContentSettingsPattern::FromURLNoWildcard(current_url()),
      CONTENT_SETTINGS_TYPE_GEOLOCATION, std::string(), CONTENT_SETTING_ALLOW);
  // Checks no infobar will be created and there's no error callback.
  AddGeolocationWatch(false);
  CheckGeoposition(fake_latitude(), fake_longitude());
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfobarForOffTheRecord) {
  // First, check infobar will be created for regular profile
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  AddGeolocationWatch(true);
  // Response will be persisted
  SetInfoBarResponse(current_url(), true);
  CheckGeoposition(fake_latitude(), fake_longitude());
  // Disables further prompts from this tab.
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
  // Go incognito, and checks no infobar will be created.
  ASSERT_TRUE(Initialize(INITIALIZATION_OFFTHERECORD));
  AddGeolocationWatch(false);
  CheckGeoposition(fake_latitude(), fake_longitude());
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoLeakFromOffTheRecord) {
  // First, check infobar will be created for incognito profile.
  ASSERT_TRUE(Initialize(INITIALIZATION_OFFTHERECORD));
  AddGeolocationWatch(true);
  // Response won't be persisted.
  SetInfoBarResponse(current_url(), true);
  CheckGeoposition(fake_latitude(), fake_longitude());
  // Disables further prompts from this tab.
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");
  // Go to the regular profile, infobar will be created.
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  AddGeolocationWatch(true);
  SetInfoBarResponse(current_url(), false);
  CheckStringValueFromJavascript("1", "geoGetLastError()");
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, IFramesWithFreshPosition) {
  set_html_for_tests("/geolocation/iframes_different_origin.html");
  ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
  LoadIFrames(2);
  LOG(WARNING) << "frames loaded";

  set_iframe_xpath("//iframe[@id='iframe_0']");
  AddGeolocationWatch(true);
  SetInfoBarResponse(iframe_url(0), true);
  CheckGeoposition(fake_latitude(), fake_longitude());
  // Disables further prompts from this iframe.
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");

  // Test second iframe from a different origin with a cached geoposition will
  // create the infobar.
  set_iframe_xpath("//iframe[@id='iframe_1']");
  AddGeolocationWatch(true);

  // Back to the first frame, enable navigation and refresh geoposition.
  set_iframe_xpath("//iframe[@id='iframe_0']");
  CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
  double fresh_position_latitude = 3.17;
  double fresh_position_longitude = 4.23;
  content::WindowedNotificationObserver observer(
      content::NOTIFICATION_LOAD_STOP,
      content::Source<NavigationController>(
          &current_browser()->tab_strip_model()->GetActiveWebContents()->
              GetController()));
  NotifyGeoposition(fresh_position_latitude, fresh_position_longitude);
  observer.Wait();
  CheckGeoposition(fresh_position_latitude, fresh_position_longitude);

  // Disable navigation for this frame.
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");

  // Now go ahead an authorize the second frame.
  set_iframe_xpath("//iframe[@id='iframe_1']");
  // Infobar was displayed, allow access and check there's no error code.
  SetInfoBarResponse(iframe_url(1), true);
  LOG(WARNING) << "Checking position...";
  CheckGeoposition(fresh_position_latitude, fresh_position_longitude);
  LOG(WARNING) << "...done.";
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest,
                       IFramesWithCachedPosition) {
  set_html_for_tests("/geolocation/iframes_different_origin.html");
  ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
  LoadIFrames(2);

  set_iframe_xpath("//iframe[@id='iframe_0']");
  AddGeolocationWatch(true);
  SetInfoBarResponse(iframe_url(0), true);
  CheckGeoposition(fake_latitude(), fake_longitude());

  // Refresh geoposition, but let's not yet create the watch on the second frame
  // so that it'll fetch from cache.
  double cached_position_latitude = 5.67;
  double cached_position_lognitude = 8.09;
  content::WindowedNotificationObserver observer(
      content::NOTIFICATION_LOAD_STOP,
      content::Source<NavigationController>(
          &current_browser()->tab_strip_model()->GetActiveWebContents()->
              GetController()));
  NotifyGeoposition(cached_position_latitude, cached_position_lognitude);
  observer.Wait();
  CheckGeoposition(cached_position_latitude, cached_position_lognitude);

  // Disable navigation for this frame.
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");

  // Now go ahead an authorize the second frame.
  set_iframe_xpath("//iframe[@id='iframe_1']");
  AddGeolocationWatch(true);
  // WebKit will use its cache, but we also broadcast a position shortly
  // afterwards. We're only interested in the first navigation for the success
  // callback from the cached position.
  CheckStringValueFromJavascript("1", "geoSetMaxNavigateCount(1)");
  SetInfoBarResponse(iframe_url(1), true);
  CheckGeoposition(cached_position_latitude, cached_position_lognitude);
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, CancelPermissionForFrame) {
  set_html_for_tests("/geolocation/iframes_different_origin.html");
  ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
  LoadIFrames(2);
  LOG(WARNING) << "frames loaded";

  set_iframe_xpath("//iframe[@id='iframe_0']");
  AddGeolocationWatch(true);
  SetInfoBarResponse(iframe_url(0), true);
  CheckGeoposition(fake_latitude(), fake_longitude());
  // Disables further prompts from this iframe.
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");

  // Test second iframe from a different origin with a cached geoposition will
  // create the infobar.
  set_iframe_xpath("//iframe[@id='iframe_1']");
  AddGeolocationWatch(true);

  InfoBarService* infobar_service = InfoBarService::FromWebContents(
      current_browser()->tab_strip_model()->GetActiveWebContents());
  size_t num_infobars_before_cancel = infobar_service->infobar_count();
  // Change the iframe, and ensure the infobar is gone.
  IFrameLoader change_iframe_1(current_browser(), 1, current_url());
  size_t num_infobars_after_cancel = infobar_service->infobar_count();
  EXPECT_EQ(num_infobars_before_cancel, num_infobars_after_cancel + 1);
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, InvalidUrlRequest) {
  // Tests that an invalid URL (e.g. from a popup window) is rejected
  // correctly. Also acts as a regression test for http://crbug.com/40478
  set_html_for_tests("/geolocation/invalid_request_url.html");
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  WebContents* original_tab =
      current_browser()->tab_strip_model()->GetActiveWebContents();
  CheckStringValueFromJavascript("1", "requestGeolocationFromInvalidUrl()");
  CheckStringValueFromJavascriptForTab("1", "isAlive()", original_tab);
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, NoInfoBarBeforeStart) {
  // See http://crbug.com/42789
  set_html_for_tests("/geolocation/iframes_different_origin.html");
  ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
  LoadIFrames(2);
  LOG(WARNING) << "frames loaded";

  // Access navigator.geolocation, but ensure it won't request permission.
  set_iframe_xpath("//iframe[@id='iframe_1']");
  CheckStringValueFromJavascript("object", "geoAccessNavigatorGeolocation()");

  set_iframe_xpath("//iframe[@id='iframe_0']");
  AddGeolocationWatch(true);
  SetInfoBarResponse(iframe_url(0), true);
  CheckGeoposition(fake_latitude(), fake_longitude());
  CheckStringValueFromJavascript("0", "geoSetMaxNavigateCount(0)");

  // Permission should be requested after adding a watch.
  set_iframe_xpath("//iframe[@id='iframe_1']");
  AddGeolocationWatch(true);
  SetInfoBarResponse(iframe_url(1), true);
  CheckGeoposition(fake_latitude(), fake_longitude());
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, TwoWatchesInOneFrame) {
  set_html_for_tests("/geolocation/two_watches.html");
  ASSERT_TRUE(Initialize(INITIALIZATION_NONE));
  // First, set the JavaScript to navigate when it receives |final_position|.
  double final_position_latitude = 3.17;
  double final_position_longitude = 4.23;
  std::string script = base::StringPrintf(
      "window.domAutomationController.send(geoSetFinalPosition(%f, %f))",
      final_position_latitude, final_position_longitude);
  std::string js_result;
  EXPECT_TRUE(content::ExecuteScriptAndExtractString(
      current_browser()->tab_strip_model()->GetActiveWebContents(), script,
      &js_result));
  EXPECT_EQ(js_result, "ok");

  // Send a position which both geolocation watches will receive.
  AddGeolocationWatch(true);
  SetInfoBarResponse(current_url(), true);
  CheckGeoposition(fake_latitude(), fake_longitude());

  // The second watch will now have cancelled. Ensure an update still makes
  // its way through to the first watcher.
  content::WindowedNotificationObserver observer(
      content::NOTIFICATION_LOAD_STOP,
      content::Source<NavigationController>(
          &current_browser()->tab_strip_model()->GetActiveWebContents()->
              GetController()));
  NotifyGeoposition(final_position_latitude, final_position_longitude);
  observer.Wait();
  CheckGeoposition(final_position_latitude, final_position_longitude);
}

IN_PROC_BROWSER_TEST_F(GeolocationBrowserTest, TabDestroyed) {
  set_html_for_tests("/geolocation/tab_destroyed.html");
  ASSERT_TRUE(Initialize(INITIALIZATION_IFRAMES));
  LoadIFrames(3);

  set_iframe_xpath("//iframe[@id='iframe_0']");
  AddGeolocationWatch(true);

  set_iframe_xpath("//iframe[@id='iframe_1']");
  AddGeolocationWatch(false);

  set_iframe_xpath("//iframe[@id='iframe_2']");
  AddGeolocationWatch(false);

  std::string script =
      "window.domAutomationController.send(window.close());";
  bool result = content::ExecuteScript(
      current_browser()->tab_strip_model()->GetActiveWebContents(), script);
  EXPECT_EQ(result, true);
}
