installation_validator.h revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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_INSTALLATION_VALIDATOR_H_
6#define CHROME_INSTALLER_UTIL_INSTALLATION_VALIDATOR_H_
7
8#include <map>
9#include <set>
10#include <utility>
11#include <vector>
12
13#include "base/basictypes.h"
14#include "base/compiler_specific.h"
15#include "base/strings/string16.h"
16#include "chrome/installer/util/browser_distribution.h"
17
18class CommandLine;
19
20namespace base {
21class FilePath;
22}
23
24namespace installer {
25
26class InstallationState;
27class AppCommand;
28class ProductState;
29
30// A class that validates the state of an installation.  Violations are logged
31// via LOG(ERROR).
32class InstallationValidator {
33 public:
34  class ProductBits {
35   public:
36    // Bits that form the components of an installation type.
37    enum {
38      CHROME_SINGLE           = 0x01,
39      CHROME_MULTI            = 0x02,
40      CHROME_FRAME_SINGLE     = 0x04,
41      CHROME_FRAME_MULTI      = 0x08,
42      CHROME_APP_HOST         = 0x10,
43    };
44  };  // class ProductBits
45
46  // Identifiers of all valid installation types.
47  enum InstallationType {
48    NO_PRODUCTS = 0,
49    CHROME_SINGLE =
50        ProductBits::CHROME_SINGLE,
51    CHROME_MULTI =
52        ProductBits::CHROME_MULTI,
53    CHROME_FRAME_SINGLE =
54        ProductBits::CHROME_FRAME_SINGLE,
55    CHROME_FRAME_SINGLE_CHROME_SINGLE =
56        ProductBits::CHROME_FRAME_SINGLE | ProductBits::CHROME_SINGLE,
57    CHROME_FRAME_SINGLE_CHROME_MULTI =
58        ProductBits::CHROME_FRAME_SINGLE | ProductBits::CHROME_MULTI,
59    CHROME_FRAME_MULTI =
60        ProductBits::CHROME_FRAME_MULTI,
61    CHROME_FRAME_MULTI_CHROME_MULTI =
62        ProductBits::CHROME_FRAME_MULTI | ProductBits::CHROME_MULTI,
63    CHROME_APP_HOST =
64        ProductBits::CHROME_APP_HOST,
65    CHROME_APP_HOST_CHROME_FRAME_SINGLE =
66        ProductBits::CHROME_APP_HOST | ProductBits::CHROME_FRAME_SINGLE,
67    CHROME_APP_HOST_CHROME_FRAME_SINGLE_CHROME_MULTI =
68        ProductBits::CHROME_APP_HOST | ProductBits::CHROME_FRAME_SINGLE |
69        ProductBits::CHROME_MULTI,
70    CHROME_APP_HOST_CHROME_FRAME_MULTI =
71        ProductBits::CHROME_APP_HOST | ProductBits::CHROME_FRAME_MULTI,
72    CHROME_APP_HOST_CHROME_FRAME_MULTI_CHROME_MULTI =
73        ProductBits::CHROME_APP_HOST | ProductBits::CHROME_FRAME_MULTI |
74        ProductBits::CHROME_MULTI,
75    CHROME_APP_HOST_CHROME_MULTI =
76        ProductBits::CHROME_APP_HOST | ProductBits::CHROME_MULTI,
77  };
78
79  // Validates |machine_state| at user or system level, returning true if valid.
80  // |type| is populated in either case, although it is a best-guess when the
81  // method returns false.
82  static bool ValidateInstallationTypeForState(
83      const InstallationState& machine_state,
84      bool system_level,
85      InstallationType* type);
86
87  // Validates the machine's current installation at user or system level,
88  // returning true and populating |type| if valid.
89  static bool ValidateInstallationType(bool system_level,
90                                       InstallationType* type);
91
92 protected:
93  struct ProductContext;
94  typedef std::vector<std::pair<std::string, bool> > SwitchExpectations;
95  typedef void (*CommandValidatorFn)(const ProductContext& ctx,
96                                     const AppCommand& app_cmd,
97                                     bool* is_valid);
98  typedef std::map<base::string16, CommandValidatorFn> CommandExpectations;
99
100  // An interface to product-specific validation rules.
101  class ProductRules {
102   public:
103    virtual ~ProductRules() { }
104    virtual BrowserDistribution::Type distribution_type() const = 0;
105    virtual void AddUninstallSwitchExpectations(
106        const ProductContext& ctx,
107        SwitchExpectations* expectations) const = 0;
108    virtual void AddRenameSwitchExpectations(
109        const ProductContext& ctx,
110        SwitchExpectations* expectations) const = 0;
111    // Return true if the rules allow usagestats setting.
112    virtual bool UsageStatsAllowed(const ProductContext& ctx) const = 0;
113  };
114
115  // Validation rules for the Chrome browser.
116  class ChromeRules : public ProductRules {
117   public:
118    virtual BrowserDistribution::Type distribution_type() const OVERRIDE;
119    virtual void AddUninstallSwitchExpectations(
120        const ProductContext& ctx,
121        SwitchExpectations* expectations) const OVERRIDE;
122    virtual void AddRenameSwitchExpectations(
123        const ProductContext& ctx,
124        SwitchExpectations* expectations) const OVERRIDE;
125    virtual bool UsageStatsAllowed(const ProductContext& ctx) const OVERRIDE;
126  };
127
128  // Validation rules for Chrome Frame.
129  class ChromeFrameRules : public ProductRules {
130   public:
131    virtual BrowserDistribution::Type distribution_type() const OVERRIDE;
132    virtual void AddUninstallSwitchExpectations(
133        const ProductContext& ctx,
134        SwitchExpectations* expectations) const OVERRIDE;
135    virtual void AddRenameSwitchExpectations(
136        const ProductContext& ctx,
137        SwitchExpectations* expectations) const OVERRIDE;
138    virtual bool UsageStatsAllowed(const ProductContext& ctx) const OVERRIDE;
139  };
140
141  // Validation rules for Chrome App Host.
142  class ChromeAppHostRules : public ProductRules {
143   public:
144    virtual BrowserDistribution::Type distribution_type() const OVERRIDE;
145    virtual void AddUninstallSwitchExpectations(
146        const ProductContext& ctx,
147        SwitchExpectations* expectations) const OVERRIDE;
148    virtual void AddRenameSwitchExpectations(
149        const ProductContext& ctx,
150        SwitchExpectations* expectations) const OVERRIDE;
151    virtual bool UsageStatsAllowed(const ProductContext& ctx) const OVERRIDE;
152  };
153
154  // Validation rules for the multi-install Chrome binaries.
155  class ChromeBinariesRules : public ProductRules {
156   public:
157    virtual BrowserDistribution::Type distribution_type() const OVERRIDE;
158    virtual void AddUninstallSwitchExpectations(
159        const ProductContext& ctx,
160        SwitchExpectations* expectations) const OVERRIDE;
161    virtual void AddRenameSwitchExpectations(
162        const ProductContext& ctx,
163        SwitchExpectations* expectations) const OVERRIDE;
164    virtual bool UsageStatsAllowed(const ProductContext& ctx) const OVERRIDE;
165  };
166
167  struct ProductContext {
168    ProductContext(const InstallationState& machine_state_in,
169                   bool system_install_in,
170                   const ProductState& state_in,
171                   const ProductRules& rules_in)
172        : machine_state(machine_state_in),
173          system_install(system_install_in),
174          dist(BrowserDistribution::GetSpecificDistribution(
175              rules_in.distribution_type())),
176          state(state_in),
177          rules(rules_in) {
178    }
179
180    const InstallationState& machine_state;
181    bool system_install;
182    BrowserDistribution* dist;
183    const ProductState& state;
184    const ProductRules& rules;
185  };
186
187  // Helper to validate the values of bool elements in AppCommand, and to output
188  // error messages. |flag_expect| is a bit mask specifying the expected
189  // presence/absence of bool variables.
190  static void ValidateAppCommandFlags(
191      const ProductContext& ctx,
192      const AppCommand& app_cmd,
193      const std::set<base::string16>& flags_expected,
194      const base::string16& name,
195      bool* is_valid);
196  static void ValidateInstallCommand(const ProductContext& ctx,
197                                     const AppCommand& app_cmd,
198                                     const wchar_t* expected_command,
199                                     const wchar_t* expected_app_name,
200                                     const char* expected_switch,
201                                     bool* is_valid);
202  static void ValidateInstallAppCommand(const ProductContext& ctx,
203                                        const AppCommand& app_cmd,
204                                        bool* is_valid);
205  static void ValidateInstallExtensionCommand(const ProductContext& ctx,
206                                              const AppCommand& app_cmd,
207                                              bool* is_valid);
208  static void ValidateOnOsUpgradeCommand(const ProductContext& ctx,
209                                         const AppCommand& app_cmd,
210                                         bool* is_valid);
211  static void ValidateQueryEULAAcceptanceCommand(const ProductContext& ctx,
212                                                 const AppCommand& app_cmd,
213                                                 bool* is_valid);
214  static void ValidateQuickEnableApplicationHostCommand(
215    const ProductContext& ctx,
216    const AppCommand& app_cmd,
217    bool* is_valid);
218
219  static void ValidateAppCommandExpectations(
220      const ProductContext& ctx,
221      const CommandExpectations& expectations,
222      bool* is_valid);
223  static void ValidateBinariesCommands(const ProductContext& ctx,
224                                       bool* is_valid);
225  static void ValidateBinaries(const InstallationState& machine_state,
226                               bool system_install,
227                               const ProductState& binaries_state,
228                               bool* is_valid);
229  static void ValidateSetupPath(const ProductContext& ctx,
230                                const base::FilePath& setup_exe,
231                                const base::string16& purpose,
232                                bool* is_valid);
233  static void ValidateCommandExpectations(const ProductContext& ctx,
234                                          const CommandLine& command,
235                                          const SwitchExpectations& expected,
236                                          const base::string16& source,
237                                          bool* is_valid);
238  static void ValidateUninstallCommand(const ProductContext& ctx,
239                                       const CommandLine& command,
240                                       const base::string16& source,
241                                       bool* is_valid);
242  static void ValidateRenameCommand(const ProductContext& ctx,
243                                    bool* is_valid);
244  static void ValidateOldVersionValues(const ProductContext& ctx,
245                                       bool* is_valid);
246  static void ValidateMultiInstallProduct(const ProductContext& ctx,
247                                          bool* is_valid);
248  static void ValidateAppCommands(const ProductContext& ctx,
249                                  bool* is_valid);
250  static void ValidateUsageStats(const ProductContext& ctx,
251                                 bool* is_valid);
252  static void ValidateProduct(const InstallationState& machine_state,
253                              bool system_install,
254                              const ProductState& product_state,
255                              const ProductRules& rules,
256                              bool* is_valid);
257
258  // A collection of all valid installation types.
259  static const InstallationType kInstallationTypes[];
260
261 private:
262  DISALLOW_IMPLICIT_CONSTRUCTORS(InstallationValidator);
263};
264
265}  // namespace installer
266
267#endif  // CHROME_INSTALLER_UTIL_INSTALLATION_VALIDATOR_H_
268