installation_state.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// Use of this source code is governed by a BSD-style license that can be
3294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek// found in the LICENSE file.
4294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
5294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "chrome/installer/util/installation_state.h"
6294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
7294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "base/logging.h"
8294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "base/strings/string_util.h"
9294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "base/strings/utf_string_conversions.h"
10294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "base/version.h"
11294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "base/win/registry.h"
12294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "chrome/installer/util/google_update_constants.h"
13294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek#include "chrome/installer/util/install_util.h"
14294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
15294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremeneknamespace installer {
16e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
17256ef642f8feef22fd53be7efa868e8e34752eedTed KremenekProductState::ProductState()
18294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    : uninstall_command_(CommandLine::NO_PROGRAM),
19294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      eula_accepted_(0),
20294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      usagestats_(0),
21294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      msi_(false),
22294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      multi_install_(false),
233070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek      has_eula_accepted_(false),
243070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek      has_oem_install_(false),
250849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek      has_usagestats_(false) {
260849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek}
273070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek
283070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenekbool ProductState::Initialize(bool system_install,
293070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek                              BrowserDistribution::Type type) {
303070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek  return Initialize(system_install,
313070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek                    BrowserDistribution::GetSpecificDistribution(type));
323070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek}
333070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek
343070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek// Initializes |commands| from the "Commands" subkey of |version_key|.
353070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek// Returns false if there is no "Commands" subkey or on error.
363070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek// static
370849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenekbool ProductState::InitializeCommands(const base::win::RegKey& version_key,
383070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek                                      AppCommands* commands) {
393070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek  static const DWORD kAccess = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE;
403070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek  base::win::RegKey commands_key;
410849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek
420849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek  if (commands_key.Open(version_key.Handle(), google_update::kRegCommandsKey,
430849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek                        kAccess) == ERROR_SUCCESS)
443070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek    return commands->Initialize(commands_key);
453070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek  return false;
463070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek}
473070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek
483070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenekbool ProductState::Initialize(bool system_install,
493070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek                              BrowserDistribution* distribution) {
503070e13dca5bbefa32acb80ce4a7b217a6220983Ted Kremenek  const std::wstring version_key(distribution->GetVersionKey());
51294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  const std::wstring state_key(distribution->GetStateKey());
52294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  const HKEY root_key = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
53256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  base::win::RegKey key;
54256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
55256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  // Clear the runway.
56256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  Clear();
57256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
58256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  // Read from the Clients key.
59256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  if (key.Open(root_key, version_key.c_str(),
60256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek               KEY_QUERY_VALUE) == ERROR_SUCCESS) {
61256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    base::string16 version_str;
62256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    if (key.ReadValue(google_update::kRegVersionField,
63256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek                      &version_str) == ERROR_SUCCESS) {
64256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      version_.reset(new Version(base::UTF16ToASCII(version_str)));
65256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      if (!version_->IsValid())
66256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek        version_.reset();
67256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    }
68256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
69256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    // Attempt to read the other values even if the "pv" version value was
70256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    // absent. Note that ProductState instances containing these values will
71894212e9510299abb203801e014fec76b7926a05Ted Kremenek    // only be accessible via InstallationState::GetNonVersionedProductState.
72894212e9510299abb203801e014fec76b7926a05Ted Kremenek    if (key.ReadValue(google_update::kRegOldVersionField,
73294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek                      &version_str) == ERROR_SUCCESS) {
74894212e9510299abb203801e014fec76b7926a05Ted Kremenek      old_version_.reset(new Version(base::UTF16ToASCII(version_str)));
75256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      if (!old_version_->IsValid())
76294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek        old_version_.reset();
77294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    }
78294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
79256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    key.ReadValue(google_update::kRegRenameCmdField, &rename_cmd_);
805eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    if (!InitializeCommands(key, &commands_))
81256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      commands_.Clear();
82256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  }
83294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
84294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  // Read from the ClientState key.
85294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek  if (key.Open(root_key, state_key.c_str(),
86294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek               KEY_QUERY_VALUE) == ERROR_SUCCESS) {
87294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    std::wstring setup_path;
88294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    std::wstring uninstall_arguments;
89294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    // "ap" will be absent if not managed by Google Update.
90294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    channel_.Initialize(key);
91294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
925eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek    // Read in the brand code, it may be absent
93294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    key.ReadValue(google_update::kRegBrandField, &brand_);
94294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek
95256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    // "UninstallString" will be absent for the multi-installer package.
96256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    key.ReadValue(kUninstallStringField, &setup_path);
97894212e9510299abb203801e014fec76b7926a05Ted Kremenek    // "UninstallArguments" will be absent for the multi-installer package.
98894212e9510299abb203801e014fec76b7926a05Ted Kremenek    key.ReadValue(kUninstallArgumentsField, &uninstall_arguments);
99894212e9510299abb203801e014fec76b7926a05Ted Kremenek    InstallUtil::MakeUninstallCommand(setup_path, uninstall_arguments,
100894212e9510299abb203801e014fec76b7926a05Ted Kremenek                                      &uninstall_command_);
101894212e9510299abb203801e014fec76b7926a05Ted Kremenek
102894212e9510299abb203801e014fec76b7926a05Ted Kremenek    // "usagestats" may be absent, 0 (false), or 1 (true).  On the chance that
103894212e9510299abb203801e014fec76b7926a05Ted Kremenek    // different values are permitted in the future, we'll simply hold whatever
104894212e9510299abb203801e014fec76b7926a05Ted Kremenek    // we find.
105256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    has_usagestats_ = (key.ReadValueDW(google_update::kRegUsageStatsField,
106256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek                                       &usagestats_) == ERROR_SUCCESS);
107256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    // "oeminstall" may be present with any value or absent.
108256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    has_oem_install_ = (key.ReadValue(google_update::kRegOemInstallField,
109256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek                                      &oem_install_) == ERROR_SUCCESS);
110894212e9510299abb203801e014fec76b7926a05Ted Kremenek    // "eulaaccepted" may be absent, 0 or 1.
111894212e9510299abb203801e014fec76b7926a05Ted Kremenek    has_eula_accepted_ = (key.ReadValueDW(google_update::kRegEULAAceptedField,
112242384ddb0e0b65dd7e9e0ac0cf3c31cf98b06a6Ted Kremenek                                          &eula_accepted_) == ERROR_SUCCESS);
113242384ddb0e0b65dd7e9e0ac0cf3c31cf98b06a6Ted Kremenek    // "msi" may be absent, 0 or 1
114242384ddb0e0b65dd7e9e0ac0cf3c31cf98b06a6Ted Kremenek    DWORD dw_value = 0;
115242384ddb0e0b65dd7e9e0ac0cf3c31cf98b06a6Ted Kremenek    msi_ = (key.ReadValueDW(google_update::kRegMSIField,
116242384ddb0e0b65dd7e9e0ac0cf3c31cf98b06a6Ted Kremenek                            &dw_value) == ERROR_SUCCESS) && (dw_value != 0);
117242384ddb0e0b65dd7e9e0ac0cf3c31cf98b06a6Ted Kremenek    // Multi-install is implied or is derived from the command-line.
118294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek    if (distribution->GetType() == BrowserDistribution::CHROME_BINARIES)
119294fd0a62b95f512637910bf85c7efa6c2354b50Ted Kremenek      multi_install_ = true;
1200849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek    else
1210849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek      multi_install_ = uninstall_command_.HasSwitch(switches::kMultiInstall);
1220849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek  }
1230849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek
1240849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek  // Read from the ClientStateMedium key.  Values here override those in
1250849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek  // ClientState.
1260849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek  if (system_install &&
1270849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek      key.Open(root_key, distribution->GetStateMediumKey().c_str(),
1280849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek               KEY_QUERY_VALUE) == ERROR_SUCCESS) {
1290849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek    DWORD dword_value = 0;
130256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
131256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    if (key.ReadValueDW(google_update::kRegUsageStatsField,
132256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek                        &dword_value) == ERROR_SUCCESS) {
133256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      has_usagestats_ = true;
134256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      usagestats_ = dword_value;
135256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    }
136256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
137256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    if (key.ReadValueDW(google_update::kRegEULAAceptedField,
138256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek                        &dword_value) == ERROR_SUCCESS) {
139256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      has_eula_accepted_ = true;
140256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      eula_accepted_ = dword_value;
141256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek    }
142256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  }
143256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
144256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  return version_.get() != NULL;
1450849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek}
1460849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek
1470849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenekbase::FilePath ProductState::GetSetupPath() const {
1480849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek  return uninstall_command_.GetProgram();
1490849ade4bb3e90c2fc0ce01ccd330f76f91da732Ted Kremenek}
150256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
151256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenekconst Version& ProductState::version() const {
152256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  DCHECK(version_.get() != NULL);
153256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  return *version_;
154256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek}
155256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek
156256ef642f8feef22fd53be7efa868e8e34752eedTed KremenekProductState& ProductState::CopyFrom(const ProductState& other) {
157256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  channel_.set_value(other.channel_.value());
158256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  version_.reset(other.version_.get() ? new Version(*other.version_) : NULL);
159256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  old_version_.reset(
160256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek      other.old_version_.get() ? new Version(*other.old_version_) : NULL);
161256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  brand_ = other.brand_;
162256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  rename_cmd_ = other.rename_cmd_;
163256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  uninstall_command_ = other.uninstall_command_;
164256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  oem_install_ = other.oem_install_;
165256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  commands_.CopyFrom(other.commands_);
166256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  eula_accepted_ = other.eula_accepted_;
167256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  usagestats_ = other.usagestats_;
168256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  msi_ = other.msi_;
169256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  multi_install_ = other.multi_install_;
170256ef642f8feef22fd53be7efa868e8e34752eedTed Kremenek  has_eula_accepted_ = other.has_eula_accepted_;
1712cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  has_oem_install_ = other.has_oem_install_;
1722cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  has_usagestats_ = other.has_usagestats_;
1732cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks
1742cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  return *this;
1752cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks}
1762cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks
1772cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaksvoid ProductState::Clear() {
1782cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  channel_.set_value(std::wstring());
1792cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  version_.reset();
1802cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  old_version_.reset();
1812cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  brand_.clear();
1822cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  rename_cmd_.clear();
1832cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  oem_install_.clear();
1842cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  uninstall_command_ = CommandLine(CommandLine::NO_PROGRAM);
1852cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  commands_.Clear();
1862cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  eula_accepted_ = 0;
1872cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  usagestats_ = 0;
1882cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  msi_ = false;
1892cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  multi_install_ = false;
1902cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  has_eula_accepted_ = false;
1912cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  has_oem_install_ = false;
1922cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  has_usagestats_ = false;
1932cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks}
1942cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks
1952cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaksbool ProductState::GetEulaAccepted(DWORD* eula_accepted) const {
1962cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  DCHECK(eula_accepted);
1972cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  if (!has_eula_accepted_)
1982cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks    return false;
1992cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  *eula_accepted = eula_accepted_;
2002cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  return true;
2012cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks}
2022cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks
2032cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaksbool ProductState::GetOemInstall(std::wstring* oem_install) const {
2042cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  DCHECK(oem_install);
2052cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  if (!has_oem_install_)
2062cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks    return false;
2072cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  *oem_install = oem_install_;
2082cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  return true;
2092cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks}
2102cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks
211e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rosebool ProductState::GetUsageStats(DWORD* usagestats) const {
212e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  DCHECK(usagestats);
213e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  if (!has_usagestats_)
214e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose    return false;
215e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  *usagestats = usagestats_;
216e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  return true;
217e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose}
218e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
219e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy RoseInstallationState::InstallationState() {
220e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose}
221e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
222e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose// static
223e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Roseint InstallationState::IndexFromDistType(BrowserDistribution::Type type) {
224e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  COMPILE_ASSERT(BrowserDistribution::CHROME_BROWSER == CHROME_BROWSER_INDEX,
225e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose                 unexpected_chrome_browser_distribution_value_);
226e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  COMPILE_ASSERT(BrowserDistribution::CHROME_FRAME == CHROME_FRAME_INDEX,
227e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose                 unexpected_chrome_frame_distribution_value_);
228e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  COMPILE_ASSERT(BrowserDistribution::CHROME_BINARIES == CHROME_BINARIES_INDEX,
229e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose                 unexpected_chrome_frame_distribution_value_);
230e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  COMPILE_ASSERT(BrowserDistribution::CHROME_APP_HOST == CHROME_APP_HOST_INDEX,
231e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose                 unexpected_chrome_frame_distribution_value_);
2322cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  DCHECK(type == BrowserDistribution::CHROME_BROWSER ||
2332cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks         type == BrowserDistribution::CHROME_FRAME ||
234e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose         type == BrowserDistribution::CHROME_BINARIES ||
235e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose         type == BrowserDistribution::CHROME_APP_HOST);
236e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  return type;
237e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose}
238e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
2392cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaksvoid InstallationState::Initialize() {
2402cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  BrowserDistribution* distribution;
2412cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks
2422cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  distribution = BrowserDistribution::GetSpecificDistribution(
243e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose      BrowserDistribution::CHROME_BROWSER);
2442cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  user_products_[CHROME_BROWSER_INDEX].Initialize(false, distribution);
2452cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  system_products_[CHROME_BROWSER_INDEX].Initialize(true, distribution);
2462cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks
247e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  distribution = BrowserDistribution::GetSpecificDistribution(
248e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose      BrowserDistribution::CHROME_FRAME);
249e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  user_products_[CHROME_FRAME_INDEX].Initialize(false, distribution);
250e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  system_products_[CHROME_FRAME_INDEX].Initialize(true, distribution);
251e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
252e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  distribution = BrowserDistribution::GetSpecificDistribution(
253e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose      BrowserDistribution::CHROME_BINARIES);
254e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  user_products_[CHROME_BINARIES_INDEX].Initialize(false, distribution);
255e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  system_products_[CHROME_BINARIES_INDEX].Initialize(true, distribution);
256e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
257e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  distribution = BrowserDistribution::GetSpecificDistribution(
258e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose      BrowserDistribution::CHROME_APP_HOST);
259e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  user_products_[CHROME_APP_HOST_INDEX].Initialize(false, distribution);
2602cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaks  system_products_[CHROME_APP_HOST_INDEX].Initialize(true, distribution);
261e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose}
262e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
263e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Roseconst ProductState* InstallationState::GetNonVersionedProductState(
264e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose    bool system_install,
265e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose    BrowserDistribution::Type type) const {
266e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  const ProductState& product_state = (system_install ? system_products_ :
267e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose      user_products_)[IndexFromDistType(type)];
268e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  return &product_state;
269e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose}
270e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose
2712cbe791d3e9b26f30196c4852da75d9ad67b4ad9Anna Zaksconst ProductState* InstallationState::GetProductState(
272e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose    bool system_install,
273e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose    BrowserDistribution::Type type) const {
274e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  const ProductState* product_state =
275e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose      GetNonVersionedProductState(system_install, type);
276e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose  return product_state->version_.get() == NULL ? NULL : product_state;
277e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose}
278e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose}  // namespace installer
279e38dd95dddb8f1b38469c8d0e28aa1c660489324Jordy Rose