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.
5 #ifndef CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
6 #define CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_
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"
23 #include <windows.h> // NOLINT
33 class InstallationState
;
34 class MasterPreferences
;
38 typedef std::vector
<Product
*> Products
;
40 // Encapsulates the state of the current installation operation. Only valid
41 // for installs and upgrades (not for uninstalls or non-install commands).
42 // This class interprets the command-line arguments and master preferences and
43 // determines the operations to be performed. For example, the Chrome Binaries
44 // are automatically added if required in multi-install mode.
45 // TODO(erikwright): This is now used a fair bit during uninstall, and
46 // InstallerState::Initialize() contains a lot of code for uninstall. The class
47 // comment should probably be updated.
48 // TODO(grt): Rename to InstallerEngine/Conductor or somesuch?
49 class InstallerState
{
65 SINGLE_INSTALL_OR_UPDATE
,
71 // Constructs an uninitialized instance; see Initialize().
74 // Constructs an initialized but empty instance.
75 explicit InstallerState(Level level
);
77 // Initializes this object based on the current operation.
78 void Initialize(const base::CommandLine
& command_line
,
79 const MasterPreferences
& prefs
,
80 const InstallationState
& machine_state
);
82 // Adds a product constructed on the basis of |state|, setting this object's
83 // msi flag if |state| is msi-installed. Returns the product that was added,
84 // or NULL if |state| is incompatible with this object. Ownership is not
85 // passed to the caller.
86 Product
* AddProductFromState(BrowserDistribution::Type type
,
87 const ProductState
& state
);
89 // Returns the product that was added, or NULL if |product| is incompatible
90 // with this object. Ownership of |product| is taken by this object, while
91 // ownership of the return value is not passed to the caller.
92 Product
* AddProduct(scoped_ptr
<Product
>* product
);
94 // Removes |product| from the set of products to be operated on. The object
95 // pointed to by |product| is freed. Returns false if |product| is not
96 // present in the set.
97 bool RemoveProduct(const Product
* product
);
99 // The level (user or system) of this operation.
100 Level
level() const { return level_
; }
102 // The package type (single or multi) of this operation.
103 PackageType
package_type() const { return package_type_
; }
105 // An identifier of this operation.
106 Operation
operation() const { return operation_
; }
108 // A convenience method returning level() == SYSTEM_LEVEL.
109 // TODO(grt): Eradicate the bool in favor of the enum.
110 bool system_install() const;
112 // A convenience method returning package_type() == MULTI_PACKAGE.
113 // TODO(grt): Eradicate the bool in favor of the enum.
114 bool is_multi_install() const;
116 // A convenient method returning the presence of the
117 // --ensure-google-update-present switch.
118 bool ensure_google_update_present() const {
119 return ensure_google_update_present_
;
122 // The full path to the place where the operand resides.
123 const base::FilePath
& target_path() const { return target_path_
; }
125 // True if the "msi" preference is set or if a product with the "msi" state
126 // flag is set is to be operated on.
127 bool is_msi() const { return msi_
; }
129 // True if the --verbose-logging command-line flag is set or if the
130 // verbose_logging master preferences option is true.
131 bool verbose_logging() const { return verbose_logging_
; }
134 HKEY
root_key() const { return root_key_
; }
137 // The ClientState key by which we interact with Google Update.
138 const std::wstring
& state_key() const { return state_key_
; }
140 // Convenience method to return the type of the BrowserDistribution associated
141 // with the ClientState key we will be interacting with.
142 BrowserDistribution::Type
state_type() const { return state_type_
; }
144 // Returns the BrowserDistribution instance corresponding to the binaries for
145 // this run if we're operating on a multi-package product.
146 BrowserDistribution
* multi_package_binaries_distribution() const {
147 DCHECK(package_type_
== MULTI_PACKAGE
);
148 DCHECK(multi_package_distribution_
!= NULL
);
149 return multi_package_distribution_
;
152 const Products
& products() const { return products_
.get(); }
154 // Returns the product of the desired type, or NULL if none found.
155 const Product
* FindProduct(BrowserDistribution::Type distribution_type
) const;
157 // Returns the currently installed version in |target_path|, or NULL if no
158 // products are installed. Ownership is passed to the caller.
159 base::Version
* GetCurrentVersion(
160 const InstallationState
& machine_state
) const;
162 // Returns the critical update version if all of the following are true:
163 // * --critical-update-version=CUV was specified on the command-line.
164 // * current_version == NULL or current_version < CUV.
165 // * new_version >= CUV.
166 // Otherwise, returns an invalid version.
167 base::Version
DetermineCriticalVersion(
168 const base::Version
* current_version
,
169 const base::Version
& new_version
) const;
171 // Returns whether or not there is currently a Chrome Frame instance running.
172 // Note that there isn't a mechanism to lock Chrome Frame in place, so Chrome
173 // Frame may either exit or start up after this is called.
174 bool IsChromeFrameRunning(const InstallationState
& machine_state
) const;
176 // Returns true if any of the binaries from a multi-install Chrome Frame that
177 // has been migrated to single-install are still in use.
178 bool AreBinariesInUse(const InstallationState
& machine_state
) const;
180 // Returns the path to the installer under Chrome version folder
181 // (for example <target_path>\Google\Chrome\Application\<Version>\Installer)
182 base::FilePath
GetInstallerDirectory(const base::Version
& version
) const;
184 // Try to delete all directories under |temp_path| whose versions are less
185 // than |new_version| and not equal to |existing_version|. |existing_version|
187 void RemoveOldVersionDirectories(const base::Version
& new_version
,
188 base::Version
* existing_version
,
189 const base::FilePath
& temp_path
) const;
191 // Adds to |com_dll_list| the list of COM DLLs that are to be registered
192 // and/or unregistered. The list may be empty.
193 void AddComDllList(std::vector
<base::FilePath
>* com_dll_list
) const;
195 bool SetChannelFlags(bool set
, ChannelInfo
* channel_info
) const;
197 // See InstallUtil::UpdateInstallerStage.
198 void UpdateStage(installer::InstallerStage stage
) const;
200 // For a MULTI_INSTALL or MULTI_UPDATE operation, updates the Google Update
201 // "ap" values for all products being operated on.
202 void UpdateChannels() const;
204 // Sets installer result information in the registry for consumption by Google
205 // Update. The InstallerResult value is set to 0 (SUCCESS) or 1
206 // (FAILED_CUSTOM_ERROR) depending on whether |status| maps to success or not.
207 // |status| itself is written to the InstallerError value.
208 // |string_resource_id|, if non-zero, identifies a localized string written to
209 // the InstallerResultUIString value. |launch_cmd|, if non-NULL and
210 // non-empty, is written to the InstallerSuccessLaunchCmdLine value.
211 void WriteInstallerResult(InstallStatus status
,
212 int string_resource_id
,
213 const std::wstring
* launch_cmd
) const;
215 // Returns true if this install needs to register an Active Setup command.
216 bool RequiresActiveSetup() const;
219 // Bits for the |file_bits| argument of AnyExistsAndIsInUse.
222 CHROME_FRAME_DLL
= 1 << 1,
223 CHROME_FRAME_HELPER_DLL
= 1 << 2,
224 CHROME_FRAME_HELPER_EXE
= 1 << 3,
228 // Returns true if |file| exists and cannot be opened for exclusive write
230 static bool IsFileInUse(const base::FilePath
& file
);
232 // Clears the instance to an uninitialized state.
235 // Returns true if any file corresponding to a bit in |file_bits| (from the
236 // enum above) for the currently installed version exists and is in use.
237 bool AnyExistsAndIsInUse(const InstallationState
& machine_state
,
238 uint32 file_bits
) const;
239 base::FilePath
GetDefaultProductInstallPath(BrowserDistribution
* dist
) const;
240 bool CanAddProduct(const Product
& product
,
241 const base::FilePath
* product_dir
) const;
242 Product
* AddProductInDirectory(const base::FilePath
* product_dir
,
243 scoped_ptr
<Product
>* product
);
244 Product
* AddProductFromPreferences(
245 BrowserDistribution::Type distribution_type
,
246 const MasterPreferences
& prefs
,
247 const InstallationState
& machine_state
);
248 bool IsMultiInstallUpdate(const MasterPreferences
& prefs
,
249 const InstallationState
& machine_state
);
251 // Enumerates all files named one of
252 // [chrome.exe, old_chrome.exe, new_chrome.exe] in target_path_ and
253 // returns their version numbers in a set.
254 void GetExistingExeVersions(std::set
<std::string
>* existing_versions
) const;
256 // Sets this object's level and updates the root_key_ accordingly.
257 void set_level(Level level
);
259 // Sets this object's package type and updates the multi_package_distribution_
261 void set_package_type(PackageType type
);
263 Operation operation_
;
264 base::FilePath target_path_
;
265 std::wstring state_key_
;
266 BrowserDistribution::Type state_type_
;
267 ScopedVector
<Product
> products_
;
268 BrowserDistribution
* multi_package_distribution_
;
269 base::Version critical_update_version_
;
271 PackageType package_type_
;
276 bool verbose_logging_
;
277 bool ensure_google_update_present_
;
280 DISALLOW_COPY_AND_ASSIGN(InstallerState
);
281 }; // class InstallerState
283 } // namespace installer
285 #endif // CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_