installer_state.h revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
6#define CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
7
8#include <set>
9#include <string>
10#include <vector>
11
12#include "base/basictypes.h"
13#include "base/files/file_path.h"
14#include "base/logging.h"
15#include "base/memory/scoped_ptr.h"
16#include "base/memory/scoped_vector.h"
17#include "base/version.h"
18#include "chrome/installer/util/browser_distribution.h"
19#include "chrome/installer/util/product.h"
20#include "chrome/installer/util/util_constants.h"
21
22#if defined(OS_WIN)
23#include <windows.h>  // NOLINT
24#endif
25
26class CommandLine;
27
28namespace installer {
29
30class ChannelInfo;
31class InstallationState;
32class MasterPreferences;
33
34class ProductState;
35
36typedef std::vector<Product*> Products;
37
38// Encapsulates the state of the current installation operation.  Only valid
39// for installs and upgrades (not for uninstalls or non-install commands).
40// This class interprets the command-line arguments and master preferences and
41// determines the operations to be performed. For example, the Chrome Binaries
42// are automatically added if required in multi-install mode.
43// TODO(erikwright): This is now used a fair bit during uninstall, and
44// InstallerState::Initialize() contains a lot of code for uninstall. The class
45// comment should probably be updated.
46// TODO(grt): Rename to InstallerEngine/Conductor or somesuch?
47class InstallerState {
48 public:
49  enum Level {
50    UNKNOWN_LEVEL,
51    USER_LEVEL,
52    SYSTEM_LEVEL
53  };
54
55  enum PackageType {
56    UNKNOWN_PACKAGE_TYPE,
57    SINGLE_PACKAGE,
58    MULTI_PACKAGE
59  };
60
61  enum Operation {
62    UNINITIALIZED,
63    SINGLE_INSTALL_OR_UPDATE,
64    MULTI_INSTALL,
65    MULTI_UPDATE,
66    UNINSTALL
67  };
68
69  // Constructs an uninitialized instance; see Initialize().
70  InstallerState();
71
72  // Constructs an initialized but empty instance.
73  explicit InstallerState(Level level);
74
75  // Initializes this object based on the current operation.
76  void Initialize(const CommandLine& command_line,
77                  const MasterPreferences& prefs,
78                  const InstallationState& machine_state);
79
80  // Adds a product constructed on the basis of |state|, setting this object's
81  // msi flag if |state| is msi-installed.  Returns the product that was added,
82  // or NULL if |state| is incompatible with this object.  Ownership is not
83  // passed to the caller.
84  Product* AddProductFromState(BrowserDistribution::Type type,
85                               const ProductState& state);
86
87  // Returns the product that was added, or NULL if |product| is incompatible
88  // with this object.  Ownership of |product| is taken by this object, while
89  // ownership of the return value is not passed to the caller.
90  Product* AddProduct(scoped_ptr<Product>* product);
91
92  // Removes |product| from the set of products to be operated on.  The object
93  // pointed to by |product| is freed.  Returns false if |product| is not
94  // present in the set.
95  bool RemoveProduct(const Product* product);
96
97  // The level (user or system) of this operation.
98  Level level() const { return level_; }
99
100  // The package type (single or multi) of this operation.
101  PackageType package_type() const { return package_type_; }
102
103  // An identifier of this operation.
104  Operation operation() const { return operation_; }
105
106  // A convenience method returning level() == SYSTEM_LEVEL.
107  // TODO(grt): Eradicate the bool in favor of the enum.
108  bool system_install() const;
109
110  // A convenience method returning package_type() == MULTI_PACKAGE.
111  // TODO(grt): Eradicate the bool in favor of the enum.
112  bool is_multi_install() const;
113
114  // A convenient method returning the presence of the
115  // --ensure-google-update-present switch.
116  bool ensure_google_update_present() const {
117    return ensure_google_update_present_;
118  }
119
120  // The full path to the place where the operand resides.
121  const base::FilePath& target_path() const { return target_path_; }
122
123  // True if the "msi" preference is set or if a product with the "msi" state
124  // flag is set is to be operated on.
125  bool is_msi() const { return msi_; }
126
127  // True if the --verbose-logging command-line flag is set or if the
128  // verbose_logging master preferences option is true.
129  bool verbose_logging() const { return verbose_logging_; }
130
131#if defined(OS_WIN)
132  HKEY root_key() const { return root_key_; }
133#endif
134
135  // The ClientState key by which we interact with Google Update.
136  const std::wstring& state_key() const { return state_key_; }
137
138  // Convenience method to return the type of the BrowserDistribution associated
139  // with the ClientState key we will be interacting with.
140  BrowserDistribution::Type state_type() const { return state_type_; }
141
142  // Returns the BrowserDistribution instance corresponding to the binaries for
143  // this run if we're operating on a multi-package product.
144  BrowserDistribution* multi_package_binaries_distribution() const {
145    DCHECK(package_type_ == MULTI_PACKAGE);
146    DCHECK(multi_package_distribution_ != NULL);
147    return multi_package_distribution_;
148  }
149
150  const Products& products() const { return products_.get(); }
151
152  // Returns the product of the desired type, or NULL if none found.
153  const Product* FindProduct(BrowserDistribution::Type distribution_type) const;
154
155  // Returns the currently installed version in |target_path|, or NULL if no
156  // products are installed.  Ownership is passed to the caller.
157  base::Version* GetCurrentVersion(
158      const InstallationState& machine_state) const;
159
160  // Returns the critical update version if all of the following are true:
161  // * --critical-update-version=CUV was specified on the command-line.
162  // * current_version == NULL or current_version < CUV.
163  // * new_version >= CUV.
164  // Otherwise, returns an invalid version.
165  base::Version DetermineCriticalVersion(
166      const base::Version* current_version,
167      const base::Version& new_version) const;
168
169  // Returns whether or not there is currently a Chrome Frame instance running.
170  // Note that there isn't a mechanism to lock Chrome Frame in place, so Chrome
171  // Frame may either exit or start up after this is called.
172  bool IsChromeFrameRunning(const InstallationState& machine_state) const;
173
174  // Returns the path to the installer under Chrome version folder
175  // (for example <target_path>\Google\Chrome\Application\<Version>\Installer)
176  base::FilePath GetInstallerDirectory(const base::Version& version) const;
177
178  // Try to delete all directories under |temp_path| whose versions are less
179  // than |new_version| and not equal to |existing_version|. |existing_version|
180  // may be NULL.
181  void RemoveOldVersionDirectories(const base::Version& new_version,
182                                   base::Version* existing_version,
183                                   const base::FilePath& temp_path) const;
184
185  // Adds to |com_dll_list| the list of COM DLLs that are to be registered
186  // and/or unregistered. The list may be empty.
187  void AddComDllList(std::vector<base::FilePath>* com_dll_list) const;
188
189  bool SetChannelFlags(bool set, ChannelInfo* channel_info) const;
190
191  // See InstallUtil::UpdateInstallerStage.
192  void UpdateStage(installer::InstallerStage stage) const;
193
194  // For a MULTI_INSTALL or MULTI_UPDATE operation, updates the Google Update
195  // "ap" values for all products being operated on.
196  void UpdateChannels() const;
197
198  // Sets installer result information in the registry for consumption by Google
199  // Update.  The InstallerResult value is set to 0 (SUCCESS) or 1
200  // (FAILED_CUSTOM_ERROR) depending on whether |status| maps to success or not.
201  // |status| itself is written to the InstallerError value.
202  // |string_resource_id|, if non-zero, identifies a localized string written to
203  // the InstallerResultUIString value.  |launch_cmd|, if non-NULL and
204  // non-empty, is written to the InstallerSuccessLaunchCmdLine value.
205  void WriteInstallerResult(InstallStatus status,
206                            int string_resource_id,
207                            const std::wstring* launch_cmd) const;
208
209  // Returns true if this install needs to register an Active Setup command.
210  bool RequiresActiveSetup() const;
211
212 protected:
213  // Returns true if |file| exists and cannot be opened for exclusive write
214  // access.
215  static bool IsFileInUse(const base::FilePath& file);
216
217  base::FilePath GetDefaultProductInstallPath(BrowserDistribution* dist) const;
218  bool CanAddProduct(const Product& product,
219                     const base::FilePath* product_dir) const;
220  Product* AddProductInDirectory(const base::FilePath* product_dir,
221                                 scoped_ptr<Product>* product);
222  Product* AddProductFromPreferences(
223      BrowserDistribution::Type distribution_type,
224      const MasterPreferences& prefs,
225      const InstallationState& machine_state);
226  bool IsMultiInstallUpdate(const MasterPreferences& prefs,
227                            const InstallationState& machine_state);
228
229  // Enumerates all files named one of
230  // [chrome.exe, old_chrome.exe, new_chrome.exe] in target_path_ and
231  // returns their version numbers in a set.
232  void GetExistingExeVersions(std::set<std::string>* existing_versions) const;
233
234  // Sets this object's level and updates the root_key_ accordingly.
235  void set_level(Level level);
236
237  // Sets this object's package type and updates the multi_package_distribution_
238  // accordingly.
239  void set_package_type(PackageType type);
240
241  Operation operation_;
242  base::FilePath target_path_;
243  std::wstring state_key_;
244  BrowserDistribution::Type state_type_;
245  ScopedVector<Product> products_;
246  BrowserDistribution* multi_package_distribution_;
247  base::Version critical_update_version_;
248  Level level_;
249  PackageType package_type_;
250#if defined(OS_WIN)
251  HKEY root_key_;
252#endif
253  bool msi_;
254  bool verbose_logging_;
255  bool ensure_google_update_present_;
256
257 private:
258  DISALLOW_COPY_AND_ASSIGN(InstallerState);
259};  // class InstallerState
260
261}  // namespace installer
262
263#endif  // CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
264