15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/webdriver/webdriver_automation.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_paths.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_writer.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_constants.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_messages.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/automation_json_requests.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/automation_proxy.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/browser_proxy.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/proxy_launcher.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/tab_proxy.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/chrome_process_util.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/webdriver/frame_path.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/webdriver/webdriver_basic_types.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/webdriver/webdriver_error.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/webdriver/webdriver_util.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/registry.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Iterates through each browser executable path, and checks if the path exists
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in any of the given locations. If found, returns true and sets |browser_exe|.
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool CheckForChromeExe(const std::vector<base::FilePath>& browser_exes,
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const std::vector<base::FilePath>& locations,
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       base::FilePath* browser_exe) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < browser_exes.size(); ++i) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < locations.size(); ++j) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath path = locations[j].Append(browser_exes[i]);
577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if (base::PathExists(path)) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *browser_exe = path;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the path to the default Chrome executable. Returns true on success.
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetDefaultChromeExe(base::FilePath* browser_exe) {
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Instead of using chrome constants, we hardcode these constants here so
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that we can locate chrome or chromium regardless of the branding
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chromedriver is built with. It may be argued that then we need to keep
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // these in sync with chrome constants. However, if chrome constants changes,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we need to look for the previous and new versions to support some
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // backwards compatibility.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath browser_exes_array[] = {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(L"chrome.exe")
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath browser_exes_array[] = {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath("Google Chrome.app/Contents/MacOS/Google Chrome"),
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath("Chromium.app/Contents/MacOS/Chromium")
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_LINUX)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath browser_exes_array[] = {
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath("google-chrome"),
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath("chrome"),
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath("chromium"),
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath("chromium-browser")
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath> browser_exes(
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_exes_array, browser_exes_array + arraysize(browser_exes_array));
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Step 1: Check the directory this module resides in. This is done
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // before all else so that the tests will pickup the built chrome.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath module_dir;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (PathService::Get(base::DIR_MODULE, &module_dir)) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t j = 0; j < browser_exes.size(); ++j) {
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath path = module_dir.Append(browser_exes[j]);
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      if (base::PathExists(path)) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *browser_exe = path;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Step 2: Add all possible install locations, in order they should be
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // searched. If a location can only hold a chromium install, add it to
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |chromium_locations|. Since on some platforms we cannot tell by the binary
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // name whether it is chrome or chromium, we search these locations last.
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We attempt to run chrome before chromium, if any install can be found.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath> locations;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath> chromium_locations;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the App Paths registry key location.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const wchar_t kSubKey[] =
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe";
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegKey key(HKEY_CURRENT_USER, kSubKey, KEY_READ);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring path;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (key.ReadValue(L"path", &path) == ERROR_SUCCESS)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    locations.push_back(base::FilePath(path));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::win::RegKey sys_key(HKEY_LOCAL_MACHINE, kSubKey, KEY_READ);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sys_key.ReadValue(L"path", &path) == ERROR_SUCCESS)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    locations.push_back(base::FilePath(path));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the user-level location for Chrome.
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath app_from_google(L"Google\\Chrome\\Application");
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath app_from_chromium(L"Chromium\\Application");
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Environment> env(base::Environment::Create());
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string home_dir;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (env->GetVar("userprofile", &home_dir)) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath default_location(UTF8ToWide(home_dir));
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::win::GetVersion() < base::win::VERSION_VISTA) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_location = default_location.Append(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          L"Local Settings\\Application Data");
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default_location = default_location.Append(L"AppData\\Local");
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    locations.push_back(default_location.Append(app_from_google));
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chromium_locations.push_back(default_location.Append(app_from_chromium));
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the system-level location for Chrome.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string program_dir;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (env->GetVar("ProgramFiles", &program_dir)) {
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    locations.push_back(base::FilePath(UTF8ToWide(program_dir))
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Append(app_from_google));
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chromium_locations.push_back(base::FilePath(UTF8ToWide(program_dir))
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Append(app_from_chromium));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (env->GetVar("ProgramFiles(x86)", &program_dir)) {
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    locations.push_back(base::FilePath(UTF8ToWide(program_dir))
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Append(app_from_google));
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    chromium_locations.push_back(base::FilePath(UTF8ToWide(program_dir))
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        .Append(app_from_chromium));
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath> app_dirs;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  webdriver::GetApplicationDirs(&app_dirs);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  locations.insert(locations.end(), app_dirs.begin(), app_dirs.end());
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_LINUX)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  locations.push_back(base::FilePath("/opt/google/chrome"));
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  locations.push_back(base::FilePath("/usr/local/bin"));
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  locations.push_back(base::FilePath("/usr/local/sbin"));
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  locations.push_back(base::FilePath("/usr/bin"));
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  locations.push_back(base::FilePath("/usr/sbin"));
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  locations.push_back(base::FilePath("/bin"));
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  locations.push_back(base::FilePath("/sbin"));
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add the current directory.
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath current_dir;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file_util::GetCurrentDirectory(&current_dir))
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    locations.push_back(current_dir);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Step 3: For each browser exe path, check each location to see if the
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser is installed there. Check the chromium locations lastly.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckForChromeExe(browser_exes, locations, browser_exe) ||
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CheckForChromeExe(browser_exes, chromium_locations, browser_exe);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message that duplicates a given message but uses a different type.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MessageWithAlternateType : public IPC::Message {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageWithAlternateType(const IPC::Message& msg, int type)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : IPC::Message(msg) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    header()->type = type;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~MessageWithAlternateType() {}
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Filters incoming and outgoing messages on the IO thread. Translates messages
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// from old Chrome versions to the new version. This is needed so that new
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ChromeDriver releases support the current stable and beta channels of Chrome.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kkania): Delete this when Chrome v21 is stable.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BackwardsCompatAutomationMessageFilter
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public IPC::ChannelProxy::MessageFilter,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public IPC::ChannelProxy::OutgoingMessageFilter {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit BackwardsCompatAutomationMessageFilter(AutomationProxy* server);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overriden from IPC::ChannelProxy::MessageFiler.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overriden from IPC::ChannelProxy::OutgoingMessageFiler.
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual IPC::Message* Rewrite(IPC::Message* message) OVERRIDE;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~BackwardsCompatAutomationMessageFilter();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first version of Chrome using the new IPC automation message set,
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after r137672 changed most of the message IDs.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNewAutomationVersion = 1142;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The first version of Chrome using the new JSON interface which takes a
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // browser index instead of a browser handle.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNewJSONInterfaceVersion = 1195;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationProxy* server_;
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool old_version_;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BackwardsCompatAutomationMessageFilter);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackwardsCompatAutomationMessageFilter::BackwardsCompatAutomationMessageFilter(
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationProxy* server)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : server_(server), old_version_(false) {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BackwardsCompatAutomationMessageFilter::OnMessageReceived(
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const IPC::Message& message) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 kOldHelloType = 44,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               kOldInitialLoadsCompleteType = 47,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               kOldInitialNewTabUILoadCompleteType = 267;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (message.type() == kOldHelloType) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    old_version_ = true;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string server_version;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PickleIterator iter(message);
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(message.ReadString(&iter, &server_version));
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    server_->SignalAppLaunch(server_version);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!old_version_)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (message.type()) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kOldInitialLoadsCompleteType:
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_->SignalInitialLoads();
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kOldInitialNewTabUILoadCompleteType:
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      server_->SignalNewTabUITab(-1);
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IPC::Message* BackwardsCompatAutomationMessageFilter::Rewrite(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IPC::Message* message) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int build_no = -1;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string version = server_->server_version();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> version_parts;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitString(version, '.', &version_parts);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(version_parts.size() == 4 &&
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::StringToInt(version_parts[2], &build_no))
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Can't rewrite message (type: " << message->type()
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << ") because unknown server (version: " << version << ")";
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(static_cast<uint32>(AutomationMsg_SendJSONRequest::ID),
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           message->type());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int type = AutomationMsg_SendJSONRequest::ID;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // These old message types are determined by inspecting the line number
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the SendJSONRequest message in older versions of
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // automation_messages_internal.h.
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (build_no < kNewAutomationVersion)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    type = 1301;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (build_no < kNewJSONInterfaceVersion)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    type = 863;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IPC::Message* new_message = new MessageWithAlternateType(*message, type);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete message;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new_message;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BackwardsCompatAutomationMessageFilter::
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ~BackwardsCompatAutomationMessageFilter() {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AddBackwardsCompatFilter(AutomationProxy* proxy) {
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The filter is ref-counted in AddFilter.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BackwardsCompatAutomationMessageFilter* filter =
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new BackwardsCompatAutomationMessageFilter(proxy);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy->channel()->AddFilter(filter);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy->channel()->set_outgoing_message_filter(filter);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebDriverAnonymousProxyLauncher : public AnonymousProxyLauncher {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebDriverAnonymousProxyLauncher()
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : AnonymousProxyLauncher(false) {}
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WebDriverAnonymousProxyLauncher() {}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual AutomationProxy* CreateAutomationProxy(
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta execution_timeout) OVERRIDE {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationProxy* proxy =
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        AnonymousProxyLauncher::CreateAutomationProxy(execution_timeout);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AddBackwardsCompatFilter(proxy);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return proxy;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebDriverNamedProxyLauncher : public NamedProxyLauncher {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebDriverNamedProxyLauncher(const std::string& channel_id,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool launch_browser)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : NamedProxyLauncher(channel_id, launch_browser, false) {}
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~WebDriverNamedProxyLauncher() {}
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual AutomationProxy* CreateAutomationProxy(
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta execution_timeout) OVERRIDE {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationProxy* proxy =
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NamedProxyLauncher::CreateAutomationProxy(execution_timeout);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We can only add the filter here if the browser has not already been
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // started. Otherwise the filter is not guaranteed to receive the
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // first message. The only occasion where we don't launch the browser is
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // in PyAuto, in which case the backwards compat filter isn't needed
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // anyways because ChromeDriver and Chrome are at the same version there.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (launch_browser_)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AddBackwardsCompatFilter(proxy);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return proxy;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace webdriver {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Automation::BrowserOptions::BrowserOptions()
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : command(CommandLine::NO_PROGRAM),
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      detach_process(false),
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ignore_certificate_errors(false) {}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Automation::BrowserOptions::~BrowserOptions() {}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Automation::Automation(const Logger& logger)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : logger_(logger),
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      build_no_(0) {}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Automation::~Automation() {}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::Init(
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BrowserOptions& options,
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int* build_no,
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Prepare Chrome's command line.
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command(CommandLine::NO_PROGRAM);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch("no-sandbox")) {
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command.AppendSwitch(switches::kNoSandbox);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* excludable_switches[] = {
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableHangMonitor,
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisablePromptOnRepost,
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDomAutomationController,
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kFullMemoryCrashReport,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kNoDefaultBrowserCheck,
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kNoFirstRun,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableBackgroundNetworking,
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableSync,
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableTranslate,
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableWebResources,
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kSbDisableAutoUpdate,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kSbDisableDownloadProtection,
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableClientSidePhishingDetection,
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableComponentUpdate,
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kDisableDefaultApps
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> switches(excludable_switches,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      excludable_switches + arraysize(excludable_switches));
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < switches.size(); ++i) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& switch_name = switches[i];
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (options.exclude_switches.find(switch_name) ==
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        options.exclude_switches.end()) {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command.AppendSwitch(switch_name);
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command.AppendSwitch(switches::kEnableLogging);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command.AppendSwitchASCII(switches::kLoggingLevel, "1");
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command.AppendSwitchASCII(switches::kPasswordStore, "basic");
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command.AppendSwitch(switches::kUseMockKeychain);
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (options.detach_process)
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command.AppendSwitch(switches::kAutomationReinitializeOnChannelError);
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (options.ignore_certificate_errors)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command.AppendSwitch(switches::kIgnoreCertificateErrors);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (options.user_data_dir.empty())
40190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    command.AppendArg(content::kAboutBlankURL);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command.AppendArguments(options.command, true /* include_program */);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the Chrome binary.
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command.GetProgram().empty()) {
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath browser_exe;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!GetDefaultChromeExe(&browser_exe)) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(kUnknownError, "Could not find default Chrome binary");
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command.SetProgram(browser_exe);
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!base::PathExists(command.GetProgram())) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string message = base::StringPrintf(
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Could not find Chrome binary at: %" PRFilePath,
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command.GetProgram().value().c_str());
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = new Error(kUnknownError, message);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string chrome_details = base::StringPrintf(
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Using Chrome binary at: %" PRFilePath,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command.GetProgram().value().c_str());
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the ProxyLauncher and launch Chrome.
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In Chrome 13/14, the only way to detach the browser process is to use a
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // named proxy launcher.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(kkania): Remove this when Chrome 15 is stable.
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string channel_id = options.channel_id;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool launch_browser = false;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (options.detach_process) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launch_browser = true;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!channel_id.empty()) {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          kUnknownError, "Cannot detach an already running browser process");
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    channel_id = "chromedriver" + GenerateRandomID();
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath temp_file;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!file_util::CreateTemporaryFile(&temp_file) ||
4437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        !base::DeleteFile(temp_file, false /* recursive */)) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(kUnknownError, "Could not create temporary filename");
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    channel_id = temp_file.value();
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (channel_id.empty()) {
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string command_line_str;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line_str = WideToUTF8(command.GetCommandLineString());
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    command_line_str = command.GetCommandLineString();
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger_.Log(kInfoLogLevel, "Launching chrome: " + command_line_str);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launcher_.reset(new WebDriverAnonymousProxyLauncher());
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger_.Log(kInfoLogLevel, "Using named testing interface");
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launcher_.reset(new WebDriverNamedProxyLauncher(
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        channel_id, launch_browser));
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyLauncher::LaunchState launch_props = {
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,  // clear_profile
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      options.user_data_dir,  // template_user_data
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Closure(),
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      command,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true,  // include_testing_id
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      true   // show_window
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!launcher_->InitializeConnection(launch_props, true)) {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger_.Log(kSevereLogLevel, "Failed to initialize connection");
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = new Error(
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUnknownError,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "Unable to either launch or connect to Chrome. Please check that "
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            "ChromeDriver is up-to-date. " + chrome_details);
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  launcher_->automation()->set_action_timeout(
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds(base::kNoTimeout));
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logger_.Log(kInfoLogLevel, "Connected to Chrome successfully. Version: " +
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              automation()->server_version());
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = DetermineBuildNumber();
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *build_no = build_no_;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the version of Chrome is compatible with this ChromeDriver.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome_details += ", version (" + automation()->server_version() + ")";
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int version = 0;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendGetChromeDriverAutomationVersion(
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), &version, &auto_error)) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (version > automation::kChromeDriverAutomationVersion) {
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = new Error(
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUnknownError,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "ChromeDriver is not compatible with this version of Chrome. " +
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            chrome_details);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::Terminate() {
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (launcher_.get() && launcher_->process() != base::kNullProcessHandle) {
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // There's currently no way to shutdown gracefully with mac chrome.
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // An alert could be open or (open before shutdown is started) and stop
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the whole process. Close any current dialog, try to kill gently, and
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if all else fails, kill it hard.
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error* error = NULL;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AcceptOrDismissAppModalDialog(true /* accept */, &error);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<Error> scoped_error(error);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kill(launcher_->process(), SIGTERM);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation()->Disconnect();
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int exit_code = -1;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!launcher_->WaitForBrowserProcessToQuit(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            base::TimeDelta::FromSeconds(10), &exit_code)) {
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      logger_.Log(kWarningLogLevel, "Chrome still running, terminating...");
528c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ChromeProcessList process_pids(GetRunningChromeProcesses(
529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          launcher_->process_id()));
530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      TerminateAllChromeProcesses(process_pids);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::CloseProcessHandle(launcher_->process());
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logger_.Log(kInfoLogLevel, "Chrome shutdown");
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::ExecuteScript(const WebViewId& view_id,
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const FramePath& frame_path,
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& script,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               std::string* result,
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Error** error) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
5483240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch  scoped_ptr<Value> value;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendExecuteJavascriptJSONRequest(automation(), view_locator,
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        frame_path.value(), script,
5513240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                        &value, &auto_error)) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!value->GetAsString(result))
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = new Error(kUnknownError, "Execute script did not return string");
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::MouseMoveDeprecated(
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Point& p,
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendMouseMoveJSONRequestDeprecated(
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, p.rounded_x(), p.rounded_y(),
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &auto_error)) {
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::MouseClickDeprecated(
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id,
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Point& p,
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation::MouseButton button,
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendMouseClickJSONRequestDeprecated(
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, button, p.rounded_x(),
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          p.rounded_y(), &auto_error)) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::MouseDragDeprecated(
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id,
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Point& start,
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Point& end,
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendMouseDragJSONRequestDeprecated(
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, start.rounded_x(), start.rounded_y(),
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          end.rounded_x(), end.rounded_y(), &auto_error)) {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::MouseButtonUpDeprecated(
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id,
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Point& p,
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckAdvancedInteractionsSupported();
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendMouseButtonUpJSONRequestDeprecated(
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, p.rounded_x(), p.rounded_y(),
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &auto_error)) {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::MouseButtonDownDeprecated(
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id,
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Point& p,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckAdvancedInteractionsSupported();
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendMouseButtonDownJSONRequestDeprecated(
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, p.rounded_x(), p.rounded_y(),
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &auto_error)) {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::MouseDoubleClickDeprecated(
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id,
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Point& p,
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckAdvancedInteractionsSupported();
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendMouseDoubleClickJSONRequestDeprecated(
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, p.rounded_x(), p.rounded_y(),
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &auto_error)) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::DragAndDropFilePaths(
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id, const Point& location,
6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::vector<base::FilePath::StringType>& paths, Error** error) {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error) {
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendDragAndDropFilePathsJSONRequest(
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, location.rounded_x(),
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          location.rounded_y(), paths, &auto_error)) {
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::SendWebKeyEvent(const WebViewId& view_id,
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const WebKeyEvent& key_event,
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 Error** error) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendWebKeyEventJSONRequest(
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, key_event, &auto_error)) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::SendWebMouseEvent(const WebViewId& view_id,
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const WebMouseEvent& event,
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   Error** error) {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
71690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!SendWebMouseEventJSONRequestDeprecated(
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, event, &auto_error)) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::CaptureEntirePageAsPNG(const WebViewId& view_id,
7232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                        const base::FilePath& path,
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        Error** error) {
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
73190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!SendCaptureEntirePageJSONRequestDeprecated(
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, path, &auto_error)) {
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::HeapProfilerDump(const WebViewId& view_id,
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const std::string& reason,
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  Error** error) {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
74790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!SendHeapProfilerDumpJSONRequestDeprecated(
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, reason, &auto_error)) {
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS))
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::NavigateToURL(const WebViewId& view_id,
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const std::string& url,
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Error** error) {
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AutomationMsg_NavigationResponseValues navigate_response;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendNavigateToURLJSONRequest(automation(), view_locator,
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    url, 1, &navigate_response,
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    &auto_error)) {
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(kkania): Do not rely on this enum.
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (navigate_response == AUTOMATION_MSG_NAVIGATION_ERROR)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = new Error(kUnknownError, "Navigation error occurred");
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::NavigateToURLAsync(const WebViewId& view_id,
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const std::string& url,
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    Error** error) {
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!view_id.old_style()) {
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AutomationMsg_NavigationResponseValues navigate_response;
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendNavigateToURLJSONRequest(automation(), view_locator, url,
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      0, &navigate_response, &auto_error)) {
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = Error::FromAutomationError(auto_error);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<BrowserProxy> browser =
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        automation()->GetBrowserWindow(view_locator.browser_index());
794868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!browser.get()) {
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(kUnknownError, "Couldn't obtain browser proxy");
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_refptr<TabProxy> tab = browser->GetTab(view_locator.tab_index());
799868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (!tab.get()) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(kUnknownError, "Couldn't obtain tab proxy");
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!tab->NavigateToURLAsync(GURL(url))) {
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(kUnknownError, "Unable to navigate to url");
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GoForward(const WebViewId& view_id, Error** error) {
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendGoForwardJSONRequest(
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_locator, &auto_error)) {
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GoBack(const WebViewId& view_id, Error** error) {
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendGoBackJSONRequest(automation(), view_locator, &auto_error))
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::Reload(const WebViewId& view_id, Error** error) {
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendReloadJSONRequest(automation(), view_locator, &auto_error))
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GetCookies(const std::string& url,
8463240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                            scoped_ptr<ListValue>* cookies,
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            Error** error) {
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendGetCookiesJSONRequest(automation(), url, cookies, &auto_error))
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::DeleteCookie(const std::string& url,
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const std::string& cookie_name,
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              Error** error) {
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendDeleteCookieJSONRequest(
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), url, cookie_name, &auto_error)) {
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::SetCookie(const std::string& url,
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           DictionaryValue* cookie_dict,
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           Error** error) {
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendSetCookieJSONRequest(automation(), url, cookie_dict, &auto_error))
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GetViews(std::vector<WebViewInfo>* views,
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          Error** error) {
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (build_no_ >= 963) {
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendGetWebViewsJSONRequest(automation(), views, &auto_error))
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = Error::FromAutomationError(auto_error);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendGetTabIdsJSONRequest(automation(), views, &auto_error))
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = Error::FromAutomationError(auto_error);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::DoesViewExist(
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id, bool* does_exist, Error** error) {
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (view_id.old_style()) {
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendIsTabIdValidJSONRequest(
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            automation(), view_id, does_exist, &auto_error))
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = Error::FromAutomationError(auto_error);
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendDoesAutomationObjectExistJSONRequest(
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            automation(), view_id, does_exist, &auto_error))
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = Error::FromAutomationError(auto_error);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::CloseView(const WebViewId& view_id, Error** error) {
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebViewLocator view_locator;
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = ConvertViewIdToLocator(view_id, &view_locator);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendCloseViewJSONRequest(automation(), view_locator, &auto_error))
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::SetViewBounds(const WebViewId& view_id,
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const Rect& bounds,
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Error** error) {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendSetViewBoundsJSONRequest(
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_id, bounds.x(), bounds.y(),
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          bounds.width(), bounds.height(), &auto_error))
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::MaximizeView(const WebViewId& view_id, Error** error) {
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckMaximizeSupported();
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendMaximizeJSONRequest(
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), view_id, &auto_error))
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GetAppModalDialogMessage(std::string* message, Error** error) {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckAlertsSupported();
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendGetAppModalDialogMessageJSONRequest(
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), message, &auto_error)) {
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::AcceptOrDismissAppModalDialog(bool accept, Error** error) {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckAlertsSupported();
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendAcceptOrDismissAppModalDialogJSONRequest(
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), accept, &auto_error)) {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::AcceptPromptAppModalDialog(const std::string& prompt_text,
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            Error** error) {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckAlertsSupported();
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendAcceptPromptAppModalDialogJSONRequest(
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), prompt_text, &auto_error)) {
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GetBrowserVersion(std::string* version) {
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *version = automation()->server_version();
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GetChromeDriverAutomationVersion(int* version, Error** error) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendGetChromeDriverAutomationVersion(automation(), version, &auto_error))
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::WaitForAllViewsToStopLoading(Error** error) {
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
97890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  if (!SendWaitForAllViewsToStopLoadingJSONRequestDeprecated(
97990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          automation(), &auto_error))
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::InstallExtension(
9842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path, std::string* extension_id, Error** error) {
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckNewExtensionInterfaceSupported();
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendInstallExtensionJSONRequest(
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), path, false /* with_ui */, extension_id,
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          &auto_error))
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GetExtensionsInfo(
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::ListValue* extensions_list, Error** error) {
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckNewExtensionInterfaceSupported();
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendGetExtensionsInfoJSONRequest(
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), extensions_list, &auto_error))
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::IsPageActionVisible(
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& tab_id,
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_visible,
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckNewExtensionInterfaceSupported();
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendIsPageActionVisibleJSONRequest(
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), tab_id, extension_id, is_visible, &auto_error))
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::SetExtensionState(
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool enable,
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckNewExtensionInterfaceSupported();
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendSetExtensionStateJSONRequest(
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), extension_id, enable /* enable */,
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          false /* allow_in_incognito */, &auto_error))
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::ClickExtensionButton(
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool browser_action,
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Error** error) {
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendClickExtensionButtonJSONRequest(
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), extension_id, browser_action, &auto_error))
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::UninstallExtension(
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id, Error** error) {
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckNewExtensionInterfaceSupported();
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!SendUninstallExtensionJSONRequest(
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), extension_id, &auto_error))
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::SetLocalStatePreference(const std::string& pref,
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         base::Value* value,
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         Error** error) {
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Value> scoped_value(value);
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In version 927, SetLocalStatePrefs was changed from taking a browser
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // handle to a browser index.
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (build_no_ >= 927) {
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation::Error auto_error;
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendSetLocalStatePreferenceJSONRequest(
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            automation(), pref, scoped_value.release(), &auto_error))
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = Error::FromAutomationError(auto_error);
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string request, response;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue request_dict;
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_dict.SetString("command", "SetLocalStatePrefs");
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_dict.SetString("path", pref);
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_dict.Set("value", scoped_value.release());
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONWriter::Write(&request_dict, &request);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation()->GetBrowserWindow(0)->SendJSONRequest(
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request, -1, &response)) {
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(kUnknownError, base::StringPrintf(
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Failed to set local state pref '%s'", pref.c_str()));
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::SetPreference(const std::string& pref,
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::Value* value,
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               Error** error) {
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Value> scoped_value(value);
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome 17 is on the 963 branch. The first released 18 build should have
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the new SetPrefs method which uses a browser index instead of handle.
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (build_no_ >= 964) {
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation::Error auto_error;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendSetPreferenceJSONRequest(
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            automation(), pref, scoped_value.release(), &auto_error))
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = Error::FromAutomationError(auto_error);
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string request, response;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue request_dict;
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_dict.SetString("command", "SetPrefs");
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_dict.SetInteger("windex", 0);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_dict.SetString("path", pref);
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    request_dict.Set("value", scoped_value.release());
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONWriter::Write(&request_dict, &request);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!automation()->GetBrowserWindow(0)->SendJSONRequest(
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            request, -1, &response)) {
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *error = new Error(kUnknownError, base::StringPrintf(
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "Failed to set pref '%s'", pref.c_str()));
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::GetGeolocation(scoped_ptr<DictionaryValue>* geolocation,
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                Error** error) {
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckGeolocationSupported();
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (geolocation_.get()) {
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    geolocation->reset(geolocation_->DeepCopy());
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = new Error(kUnknownError,
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       "Location must be set before it can be retrieved");
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Automation::OverrideGeolocation(const DictionaryValue* geolocation,
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     Error** error) {
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *error = CheckGeolocationSupported();
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*error)
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation::Error auto_error;
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (SendOverrideGeolocationJSONRequest(
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          automation(), geolocation, &auto_error)) {
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    geolocation_.reset(geolocation->DeepCopy());
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *error = Error::FromAutomationError(auto_error);
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationProxy* Automation::automation() const {
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return launcher_->automation();
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::ConvertViewIdToLocator(
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const WebViewId& view_id, WebViewLocator* view_locator) {
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (view_id.old_style()) {
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int browser_index, tab_index;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation::Error auto_error;
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!SendGetIndicesFromTabIdJSONRequest(
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            automation(), view_id.tab_id(), &browser_index, &tab_index,
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &auto_error))
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return Error::FromAutomationError(auto_error);
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *view_locator = WebViewLocator::ForIndexPair(browser_index, tab_index);
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *view_locator = WebViewLocator::ForViewId(view_id.GetId());
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::DetermineBuildNumber() {
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string version = automation()->server_version();
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> split_version;
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::SplitString(version, '.', &split_version);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (split_version.size() != 4) {
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new Error(
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUnknownError, "Browser version has unrecognized format: " + version);
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!base::StringToInt(split_version[2], &build_no_)) {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new Error(
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kUnknownError, "Browser version has unrecognized format: " + version);
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::CheckVersion(int min_required_build_no,
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const std::string& error_msg) {
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (build_no_ < min_required_build_no)
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new Error(kUnknownError, error_msg);
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::CheckAlertsSupported() {
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckVersion(
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      768, "Alerts are not supported for this version of Chrome");
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::CheckAdvancedInteractionsSupported() {
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* message =
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Advanced user interactions are not supported for this version of Chrome";
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckVersion(750, message);
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::CheckNewExtensionInterfaceSupported() {
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* message =
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Extension interface is not supported for this version of Chrome";
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckVersion(947, message);
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::CheckGeolocationSupported() {
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* message =
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Geolocation automation interface is not supported for this version of "
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Chrome.";
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckVersion(1119, message);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Error* Automation::CheckMaximizeSupported() {
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* message =
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Maximize automation interface is not supported for this version of "
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "Chrome.";
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CheckVersion(1160, message);
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace webdriver
1216