Home | History | Annotate | Download | only in util
      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 
     26 class CommandLine;
     27 
     28 namespace installer {
     29 
     30 class ChannelInfo;
     31 class InstallationState;
     32 class MasterPreferences;
     33 
     34 class ProductState;
     35 
     36 typedef 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?
     47 class 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