summaryrefslogtreecommitdiffstats
path: root/chrome/installer/util/installer_state.h
blob: 5fe4fc8d40bb737bc3070b35c00ca16cbe27bee9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
#define CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_

#include <string>
#include <vector>

#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/version.h"
#include "chrome/installer/util/browser_distribution.h"
#include "chrome/installer/util/product.h"
#include "chrome/installer/util/util_constants.h"

#if defined(OS_WIN)
#include <windows.h>  // NOLINT
#endif

class CommandLine;
class Version;

namespace installer {

class ChannelInfo;
class InstallationState;
class MasterPreferences;

class ProductState;

typedef std::vector<Product*> Products;

// Encapsulates the state of the current installation operation.  Only valid
// for installs and upgrades (not for uninstalls or non-install commands).
// TODO(grt): Rename to InstallerEngine/Conductor or somesuch?
class InstallerState {
 public:
  enum Level {
    UNKNOWN_LEVEL,
    USER_LEVEL,
    SYSTEM_LEVEL
  };

  enum PackageType {
    UNKNOWN_PACKAGE_TYPE,
    SINGLE_PACKAGE,
    MULTI_PACKAGE
  };

  enum Operation {
    UNINITIALIZED,
    SINGLE_INSTALL_OR_UPDATE,
    MULTI_INSTALL,
    MULTI_UPDATE,
    UNINSTALL
  };

  // Constructs an uninitialized instance; see Initialize().
  InstallerState();

  // Constructs an initialized but empty instance.
  explicit InstallerState(Level level);

  // Initializes this object based on the current operation.
  void Initialize(const CommandLine& command_line,
                  const MasterPreferences& prefs,
                  const InstallationState& machine_state);

  // Adds a product constructed on the basis of |state|, setting this object's
  // msi flag if |state| is msi-installed.  Returns the product that was added,
  // or NULL if |state| is incompatible with this object.  Ownership is not
  // passed to the caller.
  Product* AddProductFromState(BrowserDistribution::Type type,
                               const ProductState& state);

  // Returns the product that was added, or NULL if |product| is incompatible
  // with this object.  Ownership of |product| is taken by this object, while
  // ownership of the return value is not passed to the caller.
  Product* AddProduct(scoped_ptr<Product>* product);

  // Removes |product| from the set of products to be operated on.  The object
  // pointed to by |product| is freed.  Returns false if |product| is not
  // present in the set.
  bool RemoveProduct(const Product* product);

  // The level (user or system) of this operation.
  Level level() const { return level_; }

  // The package type (single or multi) of this operation.
  PackageType package_type() const { return package_type_; }

  // An identifier of this operation.
  Operation operation() const { return operation_; }

  // A convenience method returning level() == SYSTEM_LEVEL.
  // TODO(grt): Eradicate the bool in favor of the enum.
  bool system_install() const;

  // A convenience method returning package_type() == MULTI_PACKAGE.
  // TODO(grt): Eradicate the bool in favor of the enum.
  bool is_multi_install() const;

  // The full path to the place where the operand resides.
  const FilePath& target_path() const { return target_path_; }

  // True if the "msi" preference is set or if a product with the "msi" state
  // flag is set is to be operated on.
  bool is_msi() const { return msi_; }

  // True if the --verbose-logging command-line flag is set or if the
  // verbose_logging master preferences option is true.
  bool verbose_logging() const { return verbose_logging_; }

#if defined(OS_WIN)
  HKEY root_key() const { return root_key_; }
#endif

  // The ClientState key by which we interact with Google Update.
  const std::wstring& state_key() const { return state_key_; }

  // Convenience method to return the type of the BrowserDistribution associated
  // with the ClientState key we will be interacting with.
  BrowserDistribution::Type state_type() const { return state_type_; }

  // Returns the BrowserDistribution instance corresponding to the binaries for
  // this run if we're operating on a multi-package product.
  BrowserDistribution* multi_package_binaries_distribution() const {
    DCHECK(package_type_ == MULTI_PACKAGE);
    DCHECK(multi_package_distribution_ != NULL);
    return multi_package_distribution_;
  }

  const Products& products() const { return products_.get(); }

  // Returns the product of the desired type, or NULL if none found.
  const Product* FindProduct(BrowserDistribution::Type distribution_type) const;

  // Returns the currently installed version in |target_path|, or NULL if no
  // products are installed.  Ownership is passed to the caller.
  Version* GetCurrentVersion(const InstallationState& machine_state) const;

  // Returns the critical update version if all of the following are true:
  // * --critical-update-version=CUV was specified on the command-line.
  // * current_version == NULL or current_version < CUV.
  // * new_version >= CUV.
  // Otherwise, returns an invalid version.
  Version DetermineCriticalVersion(const Version* current_version,
                                   const Version& new_version) const;

  // Returns whether or not there is currently a Chrome Frame instance running.
  // Note that there isn't a mechanism to lock Chrome Frame in place, so Chrome
  // Frame may either exit or start up after this is called.
  bool IsChromeFrameRunning(const InstallationState& machine_state) const;

  // Returns the path to the installer under Chrome version folder
  // (for example <target_path>\Google\Chrome\Application\<Version>\Installer)
  FilePath GetInstallerDirectory(const Version& version) const;

  // Try to delete all directories under |temp_path| whose versions are less
  // than |new_version| and not equal to |existing_version|. |existing_version|
  // may be NULL.
  void RemoveOldVersionDirectories(const Version& new_version,
                                   Version* existing_version,
                                   const FilePath& temp_path) const;

  // Adds to |com_dll_list| the list of COM DLLs that are to be registered
  // and/or unregistered. The list may be empty.
  void AddComDllList(std::vector<FilePath>* com_dll_list) const;

  bool SetChannelFlags(bool set, ChannelInfo* channel_info) const;

  // See InstallUtil::UpdateInstallerStage.
  void UpdateStage(installer::InstallerStage stage) const;

  // For a MULTI_INSTALL or MULTI_UPDATE operation, updates the Google Update
  // "ap" values for all products being operated on.
  void UpdateChannels() const;

  // Sets installer result information in the registry for consumption by Google
  // Update.  The InstallerResult value is set to 0 (SUCCESS) or 1
  // (FAILED_CUSTOM_ERROR) depending on whether |status| maps to success or not.
  // |status| itself is written to the InstallerError value.
  // |string_resource_id|, if non-zero, identifies a localized string written to
  // the InstallerResultUIString value.  |launch_cmd|, if non-NULL and
  // non-empty, is written to the InstallerSuccessLaunchCmdLine value.
  void WriteInstallerResult(InstallStatus status,
                            int string_resource_id,
                            const std::wstring* launch_cmd) const;

 protected:
  static bool IsFileInUse(const FilePath& file);

  FilePath GetDefaultProductInstallPath(BrowserDistribution* dist) const;
  bool CanAddProduct(const Product& product, const FilePath* product_dir) const;
  Product* AddProductInDirectory(const FilePath* product_dir,
                                 scoped_ptr<Product>* product);
  Product* AddProductFromPreferences(
      BrowserDistribution::Type distribution_type,
      const MasterPreferences& prefs,
      const InstallationState& machine_state);
  bool IsMultiInstallUpdate(const MasterPreferences& prefs,
                            const InstallationState& machine_state);

  // Sets this object's level and updates the root_key_ accordingly.
  void set_level(Level level);

  // Sets this object's package type and updates the multi_package_distribution_
  // accordingly.
  void set_package_type(PackageType type);

  Operation operation_;
  FilePath target_path_;
  std::wstring state_key_;
  BrowserDistribution::Type state_type_;
  ScopedVector<Product> products_;
  BrowserDistribution* multi_package_distribution_;
  Version critical_update_version_;
  Level level_;
  PackageType package_type_;
#if defined(OS_WIN)
  HKEY root_key_;
#endif
  bool msi_;
  bool verbose_logging_;

 private:
  DISALLOW_COPY_AND_ASSIGN(InstallerState);
};  // class InstallerState

}  // namespace installer

#endif  // CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_