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)// Implementation of the installation validator.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/installation_validator.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/version.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/browser_distribution.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/installer/util/google_update_constants.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/helper.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/installation_state.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace installer {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDistribution::Type
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationValidator::ChromeRules::distribution_type() const {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BrowserDistribution::CHROME_BROWSER;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeRules::AddUninstallSwitchExpectations(
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool is_multi_install =
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx.state.uninstall_command().HasSwitch(switches::kMultiInstall);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome should be present for uninstall iff --multi-install.  This wasn't
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the case in Chrome 10 (between r68996 and r72497), though, so consider it
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // optional.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome-frame --ready-mode should be present for uninstall iff CF in ready
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // mode.
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* cf_state =
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx.machine_state.GetProductState(ctx.system_install,
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        BrowserDistribution::CHROME_FRAME);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool ready_mode =
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cf_state != NULL &&
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cf_state->uninstall_command().HasSwitch(switches::kChromeFrameReadyMode);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         ready_mode));
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::make_pair(std::string(switches::kChromeFrameReadyMode), ready_mode));
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeRules::AddRenameSwitchExpectations(
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool is_multi_install =
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx.state.uninstall_command().HasSwitch(switches::kMultiInstall);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome should not be present for rename.  It was for a time, so we'll be
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // lenient so that mini_installer tests pass.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome-frame --ready-mode should never be present.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::make_pair(std::string(switches::kChromeFrame), false));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::make_pair(std::string(switches::kChromeFrameReadyMode), false));
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallationValidator::ChromeRules::UsageStatsAllowed(
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx) const {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Products must not have usagestats consent values when multi-install
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (only the multi-install binaries may).
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !ctx.state.is_multi_install();
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDistribution::Type
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationValidator::ChromeFrameRules::distribution_type() const {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BrowserDistribution::CHROME_FRAME;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeFrameRules::AddUninstallSwitchExpectations(
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome-frame must be present.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         true));
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome must not be present.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(std::make_pair(std::string(switches::kChrome),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         false));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeFrameRules::AddRenameSwitchExpectations(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome-frame must be present for SxS rename.
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         !ctx.state.is_multi_install()));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome must not be present.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(std::make_pair(std::string(switches::kChrome),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         false));
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallationValidator::ChromeFrameRules::UsageStatsAllowed(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx) const {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Products must not have usagestats consent values when multi-install
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (only the multi-install binaries may).
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !ctx.state.is_multi_install();
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDistribution::Type
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationValidator::ChromeAppHostRules::distribution_type() const {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BrowserDistribution::CHROME_APP_HOST;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeAppHostRules::AddUninstallSwitchExpectations(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // --app-launcher must be present.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expectations->push_back(
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      std::make_pair(std::string(switches::kChromeAppLauncher), true));
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome must not be present.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(std::make_pair(std::string(switches::kChrome),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         false));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // --chrome-frame must not be present.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expectations->push_back(std::make_pair(std::string(switches::kChromeFrame),
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         false));
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeAppHostRules::AddRenameSwitchExpectations(
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(erikwright): I guess there will be none?
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallationValidator::ChromeAppHostRules::UsageStatsAllowed(
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx) const {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // App Host doesn't manage usage stats. The Chrome Binaries will.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserDistribution::Type
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationValidator::ChromeBinariesRules::distribution_type() const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return BrowserDistribution::CHROME_BINARIES;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeBinariesRules::AddUninstallSwitchExpectations(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ChromeBinariesRules::AddRenameSwitchExpectations(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SwitchExpectations* expectations) const {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallationValidator::ChromeBinariesRules::UsageStatsAllowed(
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx) const {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // UsageStats consent values are always allowed on the binaries.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const InstallationValidator::InstallationType
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationValidator::kInstallationTypes[] = {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NO_PRODUCTS,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_SINGLE,
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_MULTI,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_FRAME_SINGLE,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_FRAME_SINGLE_CHROME_SINGLE,
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_FRAME_SINGLE_CHROME_MULTI,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_FRAME_MULTI,
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_FRAME_MULTI_CHROME_MULTI,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_FRAME_READY_MODE_CHROME_MULTI,
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_APP_HOST,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_APP_HOST_CHROME_FRAME_SINGLE,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_APP_HOST_CHROME_FRAME_SINGLE_CHROME_MULTI,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_APP_HOST_CHROME_FRAME_MULTI,
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_APP_HOST_CHROME_FRAME_MULTI_CHROME_MULTI,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_APP_HOST_CHROME_MULTI,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHROME_APP_HOST_CHROME_MULTI_CHROME_FRAME_READY_MODE,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InstallationValidator::ValidateAppCommandFlags(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::set<string16>& flags_exp,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& name,
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool* is_valid) {
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const struct {
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16 exp_key;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool val;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* msg;
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } check_list[] = {
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {google_update::kRegSendsPingsField,
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         app_cmd.sends_pings(),
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         "be configured to send pings"},
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {google_update::kRegWebAccessibleField,
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         app_cmd.is_web_accessible(),
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         "be web accessible"},
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {google_update::kRegAutoRunOnOSUpgradeField,
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         app_cmd.is_auto_run_on_os_upgrade(),
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         "be marked to run on OS upgrade"},
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    {google_update::kRegRunAsUserField,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         app_cmd.is_run_as_user(),
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         "be marked to run as user"},
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (int i = 0; i < arraysize(check_list); ++i) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool expected = flags_exp.find(check_list[i].exp_key) != flags_exp.end();
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (check_list[i].val != expected) {
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *is_valid = false;
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName() << ": "
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << name << " command should " << (expected ? "" : "not ")
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 << check_list[i].msg << ".";
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Validates both "install-application" and "install-extension" depending on
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// what is passed in.
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InstallationValidator::ValidateInstallCommand(
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ProductContext& ctx,
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const wchar_t* expected_command,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const wchar_t* expected_app_name,
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* expected_switch,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine cmd_line(CommandLine::FromString(app_cmd.command_line()));
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 name(expected_command);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath expected_path(
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      installer::GetChromeInstallPath(ctx.system_install, ctx.dist)
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .Append(expected_app_name));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::FilePath::CompareEqualIgnoreCase(expected_path.value(),
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              cmd_line.GetProgram().value())) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << name << "'s path is not "
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << expected_path.value() << ": "
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               << cmd_line.GetProgram().value();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwitchExpectations expected;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected.push_back(std::make_pair(std::string(expected_switch), true));
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<string16> flags_exp;
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegSendsPingsField);
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegWebAccessibleField);
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegRunAsUserField);
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid);
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Validates the "install-application" Google Update product command.
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InstallationValidator::ValidateInstallAppCommand(
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ProductContext& ctx,
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool* is_valid) {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateInstallCommand(ctx, app_cmd, kCmdInstallApp,
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         installer::kChromeAppHostExe,
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ::switches::kInstallFromWebstore, is_valid);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Validates the "install-extension" Google Update product command.
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InstallationValidator::ValidateInstallExtensionCommand(
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ProductContext& ctx,
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool* is_valid) {
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateInstallCommand(ctx, app_cmd, kCmdInstallExtension,
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         installer::kChromeExe,
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                         ::switches::kLimitedInstallFromWebstore, is_valid);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the "on-os-upgrade" Google Update internal command.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateOnOsUpgradeCommand(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine cmd_line(CommandLine::FromString(app_cmd.command_line()));
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 name(kCmdOnOsUpgrade);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateSetupPath(ctx, cmd_line.GetProgram(), name, is_valid);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwitchExpectations expected;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kOnOsUpgrade), true));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.system_install));
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.state.is_multi_install()));
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Expecting kChrome if and only if kMultiInstall.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kChrome),
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.state.is_multi_install()));
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<string16> flags_exp;
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegAutoRunOnOSUpgradeField);
3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid);
3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Validates the "query-eula-acceptance" Google Update product command.
3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void InstallationValidator::ValidateQueryEULAAcceptanceCommand(
3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ProductContext& ctx,
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool* is_valid) {
3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(is_valid);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine cmd_line(CommandLine::FromString(app_cmd.command_line()));
3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 name(kCmdQueryEULAAcceptance);
3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateSetupPath(ctx, cmd_line.GetProgram(), name, is_valid);
3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SwitchExpectations expected;
3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kQueryEULAAcceptance),
3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    true));
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                    ctx.system_install));
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid);
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<string16> flags_exp;
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegWebAccessibleField);
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegRunAsUserField);
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the "quick-enable-cf" Google Update product command.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateQuickEnableCfCommand(
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine cmd_line(CommandLine::FromString(app_cmd.command_line()));
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 name(kCmdQuickEnableCf);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateSetupPath(ctx, cmd_line.GetProgram(), name, is_valid);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwitchExpectations expected;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::make_pair(std::string(switches::kChromeFrameQuickEnable), true));
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.system_install));
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.state.is_multi_install()));
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid);
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<string16> flags_exp;
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegSendsPingsField);
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegWebAccessibleField);
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the "quick-enable-application-host" Google Update product command.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateQuickEnableApplicationHostCommand(
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AppCommand& app_cmd,
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommandLine cmd_line(CommandLine::FromString(app_cmd.command_line()));
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 name(kCmdQuickEnableApplicationHost);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateSetupPath(ctx, cmd_line.GetProgram(), name, is_valid);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwitchExpectations expected;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string(switches::kChromeAppLauncher), true));
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string(switches::kSystemLevel), false));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string(switches::kMultiInstall), true));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string(switches::kEnsureGoogleUpdatePresent), true));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<string16> flags_exp;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegSendsPingsField);
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegWebAccessibleField);
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  flags_exp.insert(google_update::kRegRunAsUserField);
3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid);
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates a product's set of Google Update product commands against a
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// collection of expectations.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateAppCommandExpectations(
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandExpectations& expectations,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandExpectations the_expectations(expectations);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppCommands::CommandMapRange cmd_iterators(
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx.state.commands().GetIterators());
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandExpectations::iterator expectation;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; cmd_iterators.first != cmd_iterators.second; ++cmd_iterators.first) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& cmd_id = cmd_iterators.first->first;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do we have an expectation for this command?
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expectation = the_expectations.find(cmd_id);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (expectation != the_expectations.end()) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (expectation->second)(ctx, cmd_iterators.first->second, is_valid);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Remove this command from the set of expectations since we found it.
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      the_expectations.erase(expectation);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName()
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " has an unexpected Google Update product command named \""
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << cmd_id << "\".";
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Report on any expected commands that weren't present.
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandExpectations::const_iterator scan(the_expectations.begin());
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandExpectations::const_iterator end(the_expectations.end());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; scan != end; ++scan) {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << ctx.dist->GetAppShortCutName()
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << " is missing the Google Update product command named \""
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << scan->first << "\".";
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the multi-install binaries' Google Update commands.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateBinariesCommands(
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The quick-enable-cf command must be present if Chrome Binaries are
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // installed and Chrome Frame is not installed (or installed in ready mode).
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ChannelInfo& channel = ctx.state.channel();
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* binaries_state = ctx.machine_state.GetProductState(
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx.system_install, BrowserDistribution::CHROME_BINARIES);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* cf_state = ctx.machine_state.GetProductState(
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx.system_install, BrowserDistribution::CHROME_FRAME);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandExpectations expectations;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (binaries_state != NULL) {
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cf_state == NULL || channel.IsReadyMode())
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expectations[kCmdQuickEnableCf] = &ValidateQuickEnableCfCommand;
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expectations[kCmdQuickEnableApplicationHost] =
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &ValidateQuickEnableApplicationHostCommand;
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expectations[kCmdQueryEULAAcceptance] = &ValidateQueryEULAAcceptanceCommand;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateAppCommandExpectations(ctx, expectations, is_valid);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the multi-install binaries at level |system_level|.
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateBinaries(
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const InstallationState& machine_state,
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool system_install,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductState& binaries_state,
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ChannelInfo& channel = binaries_state.channel();
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ap must have -multi
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!channel.IsMultiInstall()) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Chrome Binaries are missing \"-multi\" in channel name: \""
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << channel.value() << "\"";
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ap must have -chrome iff Chrome is installed
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* chrome_state = machine_state.GetProductState(
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      system_install, BrowserDistribution::CHROME_BROWSER);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (chrome_state != NULL) {
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!channel.IsChrome()) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Chrome Binaries are missing \"chrome\" in channel name:"
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " \"" << channel.value() << "\"";
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (channel.IsChrome()) {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Chrome Binaries have \"-chrome\" in channel name, yet Chrome"
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  " is not installed: \"" << channel.value() << "\"";
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ap must have -chromeframe iff Chrome Frame is installed multi
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* cf_state = machine_state.GetProductState(
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      system_install, BrowserDistribution::CHROME_FRAME);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cf_state != NULL && cf_state->is_multi_install()) {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!channel.IsChromeFrame()) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Chrome Binaries are missing \"-chromeframe\" in channel"
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    " name: \"" << channel.value() << "\"";
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (channel.IsChromeFrame()) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Chrome Binaries have \"-chromeframe\" in channel name, yet "
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  "Chrome Frame is not installed multi: \"" << channel.value()
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "\"";
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ap must have -readymode iff Chrome Frame is installed in ready-mode
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cf_state != NULL &&
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cf_state->uninstall_command().HasSwitch(
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          installer::switches::kChromeFrameReadyMode)) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!channel.IsReadyMode()) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Chrome Binaries are missing \"-readymode\" in channel"
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    " name: \"" << channel.value() << "\"";
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (channel.IsReadyMode()) {
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Chrome Binaries have \"-readymode\" in channel name, yet "
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  "Chrome Frame is not in ready mode: \"" << channel.value()
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "\"";
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ap must have -applauncher iff Chrome App Launcher is installed multi
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* app_host_state = machine_state.GetProductState(
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      system_install, BrowserDistribution::CHROME_APP_HOST);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (app_host_state != NULL) {
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!app_host_state->is_multi_install()) {
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Chrome App Launcher is installed in non-multi mode.";
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!channel.IsAppLauncher()) {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Chrome Binaries are missing \"-applauncher\" in channel"
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    " name: \"" << channel.value() << "\"";
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (channel.IsAppLauncher()) {
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Chrome Binaries have \"-applauncher\" in channel name, yet "
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  "Chrome App Launcher is not installed: \"" << channel.value()
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "\"";
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome, Chrome Frame, or App Host must be present
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (chrome_state == NULL && cf_state == NULL && app_host_state == NULL) {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Chrome Binaries are present with no other products.";
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome must be multi-install if present.
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (chrome_state != NULL && !chrome_state->is_multi_install()) {
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "Chrome Binaries are present yet Chrome is not multi-install.";
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome Frame must be multi-install if Chrome & App Host are not present.
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cf_state != NULL && app_host_state == NULL && chrome_state == NULL &&
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !cf_state->is_multi_install()) {
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    LOG(ERROR) << "Chrome Binaries are present without Chrome nor App Launcher "
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << "yet Chrome Frame is not multi-install.";
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChromeBinariesRules binaries_rules;
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProductContext ctx(machine_state, system_install, binaries_state,
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     binaries_rules);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateBinariesCommands(ctx, is_valid);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateUsageStats(ctx, is_valid);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the path to |setup_exe| for the product described by |ctx|.
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateSetupPath(const ProductContext& ctx,
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              const base::FilePath& setup_exe,
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              const string16& purpose,
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              bool* is_valid) {
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BrowserDistribution* bins_dist = ctx.dist;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ctx.state.is_multi_install()) {
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bins_dist = BrowserDistribution::GetSpecificDistribution(
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        BrowserDistribution::CHROME_BINARIES);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath expected_path = installer::GetChromeInstallPath(
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ctx.system_install, bins_dist);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected_path = expected_path
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .AppendASCII(ctx.state.version().GetString())
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Append(installer::kInstallerDir)
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      .Append(installer::kSetupExe);
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!base::FilePath::CompareEqualIgnoreCase(expected_path.value(),
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              setup_exe.value())) {
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *is_valid = false;
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << ctx.dist->GetAppShortCutName() << " path to " << purpose
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << " is not " << expected_path.value() << ": "
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               << setup_exe.value();
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates that |command| meets the expectations described in |expected|.
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateCommandExpectations(
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const CommandLine& command,
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SwitchExpectations& expected,
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const string16& source,
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (SwitchExpectations::size_type i = 0, size = expected.size(); i < size;
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       ++i) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SwitchExpectations::value_type& expectation = expected[i];
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (command.HasSwitch(expectation.first) != expectation.second) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName() << " " << source
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << (expectation.second ? " is missing" : " has") << " \""
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << expectation.first << "\""
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << (expectation.second ? "" : " but shouldn't") << ": "
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << command.GetCommandLineString();
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates that |command|, originating from |source|, is formed properly for
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the product described by |ctx|
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateUninstallCommand(const ProductContext& ctx,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     const CommandLine& command,
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                     const string16& source,
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     bool* is_valid) {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateSetupPath(ctx, command.GetProgram(), ASCIIToUTF16("uninstaller"),
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    is_valid);
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool is_multi_install = ctx.state.is_multi_install();
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwitchExpectations expected;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kUninstall), true));
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.system_install));
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    is_multi_install));
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ctx.rules.AddUninstallSwitchExpectations(ctx, &expected);
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateCommandExpectations(ctx, command, expected, source, is_valid);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the rename command for the product described by |ctx|.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateRenameCommand(const ProductContext& ctx,
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  bool* is_valid) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!ctx.state.rename_cmd().empty());
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command = CommandLine::FromString(ctx.state.rename_cmd());
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  string16 name(ASCIIToUTF16("in-use renamer"));
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateSetupPath(ctx, command.GetProgram(), name, is_valid);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SwitchExpectations expected;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kRenameChromeExe),
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    true));
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kSystemLevel),
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.system_install));
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expected.push_back(std::make_pair(std::string(switches::kMultiInstall),
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    ctx.state.is_multi_install()));
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ctx.rules.AddRenameSwitchExpectations(ctx, &expected);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ValidateCommandExpectations(ctx, command, expected, name, is_valid);
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the "opv" and "cmd" values for the product described in |ctx|.
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateOldVersionValues(
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // opv and cmd must both be present or both absent
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ctx.state.old_version() == NULL) {
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ctx.state.rename_cmd().empty()) {
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName()
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " has a rename command but no opv: "
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << ctx.state.rename_cmd();
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctx.state.rename_cmd().empty()) {
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName()
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " has an opv but no rename command: "
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << ctx.state.old_version()->GetString();
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ValidateRenameCommand(ctx, is_valid);
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the multi-install state of the product described in |ctx|.
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateMultiInstallProduct(
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* binaries =
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctx.machine_state.GetProductState(ctx.system_install,
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        BrowserDistribution::CHROME_BINARIES);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!binaries) {
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctx.dist->GetType() == BrowserDistribution::CHROME_APP_HOST) {
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!ctx.machine_state.GetProductState(
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              true,  // system-level
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              BrowserDistribution::CHROME_BINARIES) &&
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          !ctx.machine_state.GetProductState(
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              true,  // system-level
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              BrowserDistribution::CHROME_BROWSER)) {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *is_valid = false;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << ctx.dist->GetAppShortCutName()
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << " (" << ctx.state.version().GetString() << ") is "
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << "installed without Chrome Binaries or a system-level "
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   << "Chrome.";
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName()
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " (" << ctx.state.version().GetString() << ") is installed "
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "without Chrome Binaries.";
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Version must match that of binaries.
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctx.state.version().CompareTo(binaries->version()) != 0) {
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Version of " << ctx.dist->GetAppShortCutName()
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " (" << ctx.state.version().GetString() << ") does not "
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    "match that of Chrome Binaries ("
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << binaries->version().GetString() << ").";
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Channel value must match that of binaries.
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ctx.state.channel().Equals(binaries->channel())) {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Channel name of " << ctx.dist->GetAppShortCutName()
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " (" << ctx.state.channel().value()
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << ") does not match that of Chrome Binaries ("
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << binaries->channel().value() << ").";
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the Google Update commands for the product described in |ctx|.
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateAppCommands(
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductContext& ctx,
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandExpectations expectations;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ctx.dist->GetType() == BrowserDistribution::CHROME_APP_HOST) {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expectations[kCmdInstallApp] = &ValidateInstallAppCommand;
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ctx.dist->GetType() == BrowserDistribution::CHROME_BROWSER) {
7612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expectations[kCmdInstallExtension] = &ValidateInstallExtensionCommand;
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expectations[kCmdOnOsUpgrade] = &ValidateOnOsUpgradeCommand;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateAppCommandExpectations(ctx, expectations, is_valid);
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates usagestats for the product or binaries in |ctx|.
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateUsageStats(const ProductContext& ctx,
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bool* is_valid) {
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD usagestats = 0;
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ctx.state.GetUsageStats(&usagestats)) {
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!ctx.rules.UsageStatsAllowed(ctx)) {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName()
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " has a usagestats value (" << usagestats
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << "), yet should not.";
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (usagestats != 0 && usagestats != 1) {
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *is_valid = false;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << ctx.dist->GetAppShortCutName()
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << " has an unsupported usagestats value (" << usagestats
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 << ").";
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Validates the product described in |product_state| according to |rules|.
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstallationValidator::ValidateProduct(
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const InstallationState& machine_state,
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool system_install,
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductState& product_state,
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProductRules& rules,
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool* is_valid) {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(is_valid);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProductContext ctx(machine_state, system_install, product_state, rules);
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateUninstallCommand(ctx, ctx.state.uninstall_command(),
7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           ASCIIToUTF16("Google Update uninstall command"),
8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           is_valid);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateOldVersionValues(ctx, is_valid);
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ctx.state.is_multi_install())
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ValidateMultiInstallProduct(ctx, is_valid);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateAppCommands(ctx, is_valid);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ValidateUsageStats(ctx, is_valid);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallationValidator::ValidateInstallationTypeForState(
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const InstallationState& machine_state,
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool system_level,
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    InstallationType* type) {
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool rock_on = true;
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *type = NO_PRODUCTS;
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Does the system have any multi-installed products?
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* multi_state =
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      machine_state.GetProductState(system_level,
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    BrowserDistribution::CHROME_BINARIES);
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (multi_state != NULL)
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ValidateBinaries(machine_state, system_level, *multi_state, &rock_on);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is Chrome installed?
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ProductState* product_state =
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      machine_state.GetProductState(system_level,
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    BrowserDistribution::CHROME_BROWSER);
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (product_state != NULL) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeRules chrome_rules;
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ValidateProduct(machine_state, system_level, *product_state,
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    chrome_rules, &rock_on);
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *type = static_cast<InstallationType>(
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *type | (product_state->is_multi_install() ?
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ProductBits::CHROME_MULTI :
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ProductBits::CHROME_SINGLE));
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is Chrome Frame installed?
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  product_state =
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      machine_state.GetProductState(system_level,
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    BrowserDistribution::CHROME_FRAME);
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (product_state != NULL) {
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeFrameRules chrome_frame_rules;
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ValidateProduct(machine_state, system_level, *product_state,
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    chrome_frame_rules, &rock_on);
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int cf_bit = !product_state->is_multi_install() ?
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProductBits::CHROME_FRAME_SINGLE :
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (product_state->uninstall_command().HasSwitch(
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             switches::kChromeFrameReadyMode) ?
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ProductBits::CHROME_FRAME_READY_MODE :
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 ProductBits::CHROME_FRAME_MULTI);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *type = static_cast<InstallationType>(*type | cf_bit);
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Is Chrome App Host installed?
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  product_state =
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      machine_state.GetProductState(system_level,
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    BrowserDistribution::CHROME_APP_HOST);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (product_state != NULL) {
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeAppHostRules chrome_app_host_rules;
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ValidateProduct(machine_state, system_level, *product_state,
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    chrome_app_host_rules, &rock_on);
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *type = static_cast<InstallationType>(*type | ProductBits::CHROME_APP_HOST);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!product_state->is_multi_install()) {
8692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      LOG(ERROR) << "Chrome App Launcher must always be multi-install.";
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rock_on = false;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_NE(std::find(&kInstallationTypes[0],
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      &kInstallationTypes[arraysize(kInstallationTypes)],
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      *type),
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            &kInstallationTypes[arraysize(kInstallationTypes)])
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      << "Invalid combination of products found on system (" << *type << ")";
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rock_on;
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstallationValidator::ValidateInstallationType(bool system_level,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     InstallationType* type) {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type);
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InstallationState machine_state;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  machine_state.Initialize();
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ValidateInstallationTypeForState(machine_state, system_level, type);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace installer
895