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/mini_installer_test/installer_test_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
9bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/kill.h"
10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/launch.h"
11bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "base/process/process.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_result_codes.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/google_update_constants.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/helper.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/install_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/util_constants.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/mini_installer_test/mini_installer_test_constants.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using installer::InstallationValidator;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDistribution::Type ToBrowserDistributionType(
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationValidator::InstallationType type) {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kChromeMask =
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (InstallationValidator::ProductBits::CHROME_SINGLE |
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       InstallationValidator::ProductBits::CHROME_MULTI);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kChromeFrameMask =
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (InstallationValidator::ProductBits::CHROME_FRAME_SINGLE |
33d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)       InstallationValidator::ProductBits::CHROME_FRAME_MULTI);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kBinariesMask =
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (InstallationValidator::ProductBits::CHROME_MULTI |
36d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)       InstallationValidator::ProductBits::CHROME_FRAME_MULTI);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Default return is CHROME_BINARIES.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution::Type ret_value = BrowserDistribution::CHROME_BINARIES;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type & kChromeMask)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret_value = BrowserDistribution::CHROME_BROWSER;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type & kChromeFrameMask)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret_value = BrowserDistribution::CHROME_FRAME;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type & kBinariesMask)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret_value = BrowserDistribution::CHROME_BINARIES;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret_value;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace installer_test {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeleteInstallDirectory(bool system_level,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            InstallationValidator::InstallationType type) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string version = GetVersion(type);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (version.empty())
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool has_install_dir = GetInstallDirectory(system_level,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             ToBrowserDistributionType(type),
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             &path);
617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!has_install_dir || !base::PathExists(path))
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path = path.AppendASCII(version);
647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  return base::DeleteFile(path, true);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DeleteRegistryKey(bool system_level,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       InstallationValidator::InstallationType type) {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution* dist = BrowserDistribution::GetSpecificDistribution(
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ToBrowserDistributionType(type));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType key(google_update::kRegPathClients);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  key.push_back(base::FilePath::kSeparators[0]);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  key.append(dist->GetAppGuid());
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HKEY root = system_level ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return InstallUtil::DeleteRegistryKey(root, key);
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetChromeInstallDirectory(bool system_level, base::FilePath* path) {
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetInstallDirectory(system_level,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserDistribution::CHROME_BROWSER, path);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetInstallDirectory(bool system_level,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         BrowserDistribution::Type type, base::FilePath* path) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution* dist =
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserDistribution::GetSpecificDistribution(type);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *path = installer::GetChromeInstallPath(system_level, dist);
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath parent;
89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (system_level)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PathService::Get(base::DIR_PROGRAM_FILES, &parent);
91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  else
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PathService::Get(base::DIR_LOCAL_APP_DATA, &parent);
93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return parent.IsParent(*path);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetInstalledProducts(
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<installer_test::InstalledProduct>* products) {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Clear out the products list.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  products->clear();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check user-level and system-level for products.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution* current_dist;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  installer_test::InstalledProduct current_prod;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < 2; ++i) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const bool system_level = (i != 0);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationValidator::InstallationType type =
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InstallationValidator::NO_PRODUCTS;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_valid =
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        InstallationValidator::ValidateInstallationType(system_level, &type);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type != InstallationValidator::NO_PRODUCTS) {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      current_dist = BrowserDistribution::GetSpecificDistribution(
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ToBrowserDistributionType(type));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Version version;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      InstallUtil::GetChromeVersion(current_dist, system_level, &version);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (version.IsValid()) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_prod.type = type;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_prod.version = version.GetString();
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        current_prod.system = system_level;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        products->push_back(current_prod);
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !products->empty();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ValidateInstall(bool system_level,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     InstallationValidator::InstallationType expected,
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const std::string& version) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetVersion(expected) != version)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstallationValidator::InstallationType type;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstallationValidator::ValidateInstallationType(system_level, &type);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == InstallationValidator::NO_PRODUCTS) {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "No installed Chrome or Chrome Frame versions found.";
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((type & expected) == 0) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Expected type: " << expected << "\n Actual type: " << type;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetVersion(InstallationValidator::InstallationType product) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<installer_test::InstalledProduct> installed;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (GetInstalledProducts(&installed)) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (size_t i = 0; i < installed.size(); ++i) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if ((installed[i].type & product) != 0) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return installed[i].version;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return "";
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Install(const base::FilePath& installer) {
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!base::PathExists(installer)) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Installer does not exist: " << installer.MaybeAsASCII();
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command(installer);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Running installer command: "
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << command.GetCommandLineString();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return installer_test::RunAndWaitForCommandToFinish(command);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Install(const base::FilePath& installer, const SwitchBuilder& switches) {
1677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!base::PathExists(installer)) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Installer does not exist: " << installer.MaybeAsASCII();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command(installer);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command.AppendArguments(switches.GetSwitches(), false);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Running installer command: "
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            << command.GetCommandLineString();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return installer_test::RunAndWaitForCommandToFinish(command);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LaunchChrome(bool close_after_launch, bool system_level) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::CleanupProcesses(installer::kChromeExe, base::TimeDelta(),
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         content::RESULT_CODE_HUNG, NULL);
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath install_path;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetChromeInstallDirectory(
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      system_level, &install_path)) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not find Chrome install directory";
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  install_path = install_path.Append(installer::kChromeExe);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine browser(install_path);
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath exe = browser.GetProgram();
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Browser launch command: " << browser.GetCommandLineString();
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle chrome;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!base::LaunchProcess(browser, base::LaunchOptions(), &chrome)) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not launch process: " << exe.value();
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (close_after_launch) {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::KillProcess(chrome, 0, true)) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to close chrome.exe after launch.";
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool LaunchIE(const std::string& url) {
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath browser_path;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(base::DIR_PROGRAM_FILES, &browser_path);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser_path = browser_path.Append(mini_installer_constants::kIELocation);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser_path = browser_path.Append(mini_installer_constants::kIEProcessName);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine cmd_line(browser_path);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cmd_line.AppendArg(url);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UninstallAll() {
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::CleanupProcesses(installer::kChromeExe, base::TimeDelta(),
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         content::RESULT_CODE_HUNG, NULL);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::CleanupProcesses(installer::kChromeFrameHelperExe, base::TimeDelta(),
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         content::RESULT_CODE_HUNG, NULL);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<installer_test::InstalledProduct> installed;
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!GetInstalledProducts(&installed)) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(WARNING) << "No installed products to uninstall.";
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret_val = false;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < installed.size(); ++i) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!Uninstall(installed[i].system, installed[i].type))
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ret_val = false;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret_val;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Uninstall(bool system_level,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               InstallationValidator::InstallationType type) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<BrowserDistribution::Type> products;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ToBrowserDistributionType(type) !=
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BrowserDistribution::CHROME_BINARIES) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    products.push_back(ToBrowserDistributionType(type));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    products.push_back(BrowserDistribution::CHROME_BROWSER);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    products.push_back(BrowserDistribution::CHROME_FRAME);
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret_val = false;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < products.size(); ++i) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!Uninstall(system_level, products[i]))
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ret_val = false;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret_val;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Uninstall(bool system_level,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               BrowserDistribution::Type product) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMultiMask =
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (InstallationValidator::ProductBits::CHROME_MULTI |
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       InstallationValidator::ProductBits::CHROME_FRAME_MULTI);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine uninstall_cmd(InstallUtil::GetChromeUninstallCmd(system_level,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      product));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine::StringType archive =
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      uninstall_cmd.GetProgram().DirName().AppendASCII("chrome.7z").value();
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uninstall_cmd.AppendSwitch(installer::switches::kUninstall);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uninstall_cmd.AppendSwitch(installer::switches::kForceUninstall);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uninstall_cmd.AppendSwitchNative(
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::switches::kInstallArchive, archive);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (system_level)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uninstall_cmd.AppendSwitch(installer::switches::kSystemLevel);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((product & kMultiMask) !=0)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uninstall_cmd.AppendSwitch(installer::switches::kMultiInstall);
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LOG(INFO) << "Uninstall command: " << uninstall_cmd.GetCommandLineString();
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool ret_val = RunAndWaitForCommandToFinish(uninstall_cmd);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Close IE notification when uninstalling Chrome Frame.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::CleanupProcesses(mini_installer_constants::kIEProcessName,
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         base::TimeDelta(),
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         content::RESULT_CODE_HUNG, NULL);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ret_val;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RunAndWaitForCommandToFinish(CommandLine command) {
2817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!base::PathExists(command.GetProgram())) {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Command executable does not exist: "
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << command.GetProgram().MaybeAsASCII();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ProcessHandle process;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!base::LaunchProcess(command, base::LaunchOptions(), &process)) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to launch command: "
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << command.GetCommandLineString();
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!base::WaitForSingleProcess(process, base::TimeDelta::FromMinutes(1))) {
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Launched process did not complete.";
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
300