| // Copyright (c) 2012 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 <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/basictypes.h" |
| #include "base/files/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; |
| |
| 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). |
| // This class interprets the command-line arguments and master preferences and |
| // determines the operations to be performed. For example, the Chrome Binaries |
| // are automatically added if required in multi-install mode. |
| // TODO(erikwright): This is now used a fair bit during uninstall, and |
| // InstallerState::Initialize() contains a lot of code for uninstall. The class |
| // comment should probably be updated. |
| // 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; |
| |
| // A convenient method returning the presence of the |
| // --ensure-google-update-present switch. |
| bool ensure_google_update_present() const { |
| return ensure_google_update_present_; |
| } |
| |
| // The full path to the place where the operand resides. |
| const base::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. |
| base::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. |
| base::Version DetermineCriticalVersion( |
| const base::Version* current_version, |
| const base::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 true if any of the binaries from a multi-install Chrome Frame that |
| // has been migrated to single-install are still in use. |
| bool AreBinariesInUse(const InstallationState& machine_state) const; |
| |
| // Returns the path to the installer under Chrome version folder |
| // (for example <target_path>\Google\Chrome\Application\<Version>\Installer) |
| base::FilePath GetInstallerDirectory(const base::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 base::Version& new_version, |
| base::Version* existing_version, |
| const base::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<base::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; |
| |
| // Returns true if this install needs to register an Active Setup command. |
| bool RequiresActiveSetup() const; |
| |
| protected: |
| // Bits for the |file_bits| argument of AnyExistsAndIsInUse. |
| enum { |
| CHROME_DLL = 1 << 0, |
| CHROME_FRAME_DLL = 1 << 1, |
| CHROME_FRAME_HELPER_DLL = 1 << 2, |
| CHROME_FRAME_HELPER_EXE = 1 << 3, |
| NUM_BINARIES = 4 |
| }; |
| |
| // Returns true if |file| exists and cannot be opened for exclusive write |
| // access. |
| static bool IsFileInUse(const base::FilePath& file); |
| |
| // Clears the instance to an uninitialized state. |
| void Clear(); |
| |
| // Returns true if any file corresponding to a bit in |file_bits| (from the |
| // enum above) for the currently installed version exists and is in use. |
| bool AnyExistsAndIsInUse(const InstallationState& machine_state, |
| uint32 file_bits) const; |
| base::FilePath GetDefaultProductInstallPath(BrowserDistribution* dist) const; |
| bool CanAddProduct(const Product& product, |
| const base::FilePath* product_dir) const; |
| Product* AddProductInDirectory(const base::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); |
| |
| // Enumerates all files named one of |
| // [chrome.exe, old_chrome.exe, new_chrome.exe] in target_path_ and |
| // returns their version numbers in a set. |
| void GetExistingExeVersions(std::set<std::string>* existing_versions) const; |
| |
| // 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_; |
| base::FilePath target_path_; |
| std::wstring state_key_; |
| BrowserDistribution::Type state_type_; |
| ScopedVector<Product> products_; |
| BrowserDistribution* multi_package_distribution_; |
| base::Version critical_update_version_; |
| Level level_; |
| PackageType package_type_; |
| #if defined(OS_WIN) |
| HKEY root_key_; |
| #endif |
| bool msi_; |
| bool verbose_logging_; |
| bool ensure_google_update_present_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(InstallerState); |
| }; // class InstallerState |
| |
| } // namespace installer |
| |
| #endif // CHROME_INSTALLER_UTIL_INSTALLER_STATE_H_ |