OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Implementation of the installation validator. | 5 // Implementation of the installation validator. |
6 | 6 |
7 #include "chrome/installer/util/installation_validator.h" | 7 #include "chrome/installer/util/installation_validator.h" |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <set> | 10 #include <set> |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 80 } |
81 | 81 |
82 bool InstallationValidator::ChromeFrameRules::UsageStatsAllowed( | 82 bool InstallationValidator::ChromeFrameRules::UsageStatsAllowed( |
83 const ProductContext& ctx) const { | 83 const ProductContext& ctx) const { |
84 // Products must not have usagestats consent values when multi-install | 84 // Products must not have usagestats consent values when multi-install |
85 // (only the multi-install binaries may). | 85 // (only the multi-install binaries may). |
86 return !ctx.state.is_multi_install(); | 86 return !ctx.state.is_multi_install(); |
87 } | 87 } |
88 | 88 |
89 BrowserDistribution::Type | 89 BrowserDistribution::Type |
90 InstallationValidator::ChromeAppHostRules::distribution_type() const { | |
91 return BrowserDistribution::CHROME_APP_HOST; | |
92 } | |
93 | |
94 void InstallationValidator::ChromeAppHostRules::AddUninstallSwitchExpectations( | |
95 const ProductContext& ctx, | |
96 SwitchExpectations* expectations) const { | |
97 // --app-launcher must be present. | |
98 expectations->push_back( | |
99 std::make_pair(std::string(switches::kChromeAppLauncher), true)); | |
100 | |
101 // --chrome must not be present. | |
102 expectations->push_back(std::make_pair(std::string(switches::kChrome), | |
103 false)); | |
104 // --chrome-frame must not be present. | |
105 expectations->push_back(std::make_pair(std::string(switches::kChromeFrame), | |
106 false)); | |
107 } | |
108 | |
109 void InstallationValidator::ChromeAppHostRules::AddRenameSwitchExpectations( | |
110 const ProductContext& ctx, | |
111 SwitchExpectations* expectations) const { | |
112 // TODO(erikwright): I guess there will be none? | |
113 } | |
114 | |
115 bool InstallationValidator::ChromeAppHostRules::UsageStatsAllowed( | |
116 const ProductContext& ctx) const { | |
117 // App Host doesn't manage usage stats. The Chrome Binaries will. | |
118 return false; | |
119 } | |
120 | |
121 BrowserDistribution::Type | |
122 InstallationValidator::ChromeBinariesRules::distribution_type() const { | 90 InstallationValidator::ChromeBinariesRules::distribution_type() const { |
123 return BrowserDistribution::CHROME_BINARIES; | 91 return BrowserDistribution::CHROME_BINARIES; |
124 } | 92 } |
125 | 93 |
126 void InstallationValidator::ChromeBinariesRules::AddUninstallSwitchExpectations( | 94 void InstallationValidator::ChromeBinariesRules::AddUninstallSwitchExpectations( |
127 const ProductContext& ctx, | 95 const ProductContext& ctx, |
128 SwitchExpectations* expectations) const { | 96 SwitchExpectations* expectations) const { |
129 NOTREACHED(); | 97 NOTREACHED(); |
130 } | 98 } |
131 | 99 |
(...skipping 13 matching lines...) Expand all Loading... |
145 const InstallationValidator::InstallationType | 113 const InstallationValidator::InstallationType |
146 InstallationValidator::kInstallationTypes[] = { | 114 InstallationValidator::kInstallationTypes[] = { |
147 NO_PRODUCTS, | 115 NO_PRODUCTS, |
148 CHROME_SINGLE, | 116 CHROME_SINGLE, |
149 CHROME_MULTI, | 117 CHROME_MULTI, |
150 CHROME_FRAME_SINGLE, | 118 CHROME_FRAME_SINGLE, |
151 CHROME_FRAME_SINGLE_CHROME_SINGLE, | 119 CHROME_FRAME_SINGLE_CHROME_SINGLE, |
152 CHROME_FRAME_SINGLE_CHROME_MULTI, | 120 CHROME_FRAME_SINGLE_CHROME_MULTI, |
153 CHROME_FRAME_MULTI, | 121 CHROME_FRAME_MULTI, |
154 CHROME_FRAME_MULTI_CHROME_MULTI, | 122 CHROME_FRAME_MULTI_CHROME_MULTI, |
155 CHROME_APP_HOST, | |
156 CHROME_APP_HOST_CHROME_FRAME_SINGLE, | |
157 CHROME_APP_HOST_CHROME_FRAME_SINGLE_CHROME_MULTI, | |
158 CHROME_APP_HOST_CHROME_FRAME_MULTI, | |
159 CHROME_APP_HOST_CHROME_FRAME_MULTI_CHROME_MULTI, | |
160 CHROME_APP_HOST_CHROME_MULTI, | |
161 }; | 123 }; |
162 | 124 |
163 void InstallationValidator::ValidateAppCommandFlags( | 125 void InstallationValidator::ValidateAppCommandFlags( |
164 const ProductContext& ctx, | 126 const ProductContext& ctx, |
165 const AppCommand& app_cmd, | 127 const AppCommand& app_cmd, |
166 const std::set<base::string16>& flags_exp, | 128 const std::set<base::string16>& flags_exp, |
167 const base::string16& name, | 129 const base::string16& name, |
168 bool* is_valid) { | 130 bool* is_valid) { |
169 const struct { | 131 const struct { |
170 const base::string16 exp_key; | 132 const base::string16 exp_key; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 expected.push_back(std::make_pair(std::string(switches::kChrome), | 180 expected.push_back(std::make_pair(std::string(switches::kChrome), |
219 ctx.state.is_multi_install())); | 181 ctx.state.is_multi_install())); |
220 | 182 |
221 ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid); | 183 ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid); |
222 | 184 |
223 std::set<base::string16> flags_exp; | 185 std::set<base::string16> flags_exp; |
224 flags_exp.insert(google_update::kRegAutoRunOnOSUpgradeField); | 186 flags_exp.insert(google_update::kRegAutoRunOnOSUpgradeField); |
225 ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid); | 187 ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid); |
226 } | 188 } |
227 | 189 |
228 // Validates the "query-eula-acceptance" Google Update product command. | |
229 void InstallationValidator::ValidateQueryEULAAcceptanceCommand( | |
230 const ProductContext& ctx, | |
231 const AppCommand& app_cmd, | |
232 bool* is_valid) { | |
233 DCHECK(is_valid); | |
234 | |
235 base::CommandLine cmd_line( | |
236 base::CommandLine::FromString(app_cmd.command_line())); | |
237 base::string16 name(kCmdQueryEULAAcceptance); | |
238 | |
239 ValidateSetupPath(ctx, cmd_line.GetProgram(), name, is_valid); | |
240 | |
241 SwitchExpectations expected; | |
242 expected.push_back(std::make_pair(std::string(switches::kQueryEULAAcceptance), | |
243 true)); | |
244 expected.push_back(std::make_pair(std::string(switches::kSystemLevel), | |
245 ctx.system_install)); | |
246 | |
247 ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid); | |
248 | |
249 std::set<base::string16> flags_exp; | |
250 flags_exp.insert(google_update::kRegWebAccessibleField); | |
251 flags_exp.insert(google_update::kRegRunAsUserField); | |
252 ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid); | |
253 } | |
254 | |
255 // Validates the "quick-enable-application-host" Google Update product command. | |
256 void InstallationValidator::ValidateQuickEnableApplicationHostCommand( | |
257 const ProductContext& ctx, | |
258 const AppCommand& app_cmd, | |
259 bool* is_valid) { | |
260 DCHECK(is_valid); | |
261 | |
262 base::CommandLine cmd_line( | |
263 base::CommandLine::FromString(app_cmd.command_line())); | |
264 base::string16 name(kCmdQuickEnableApplicationHost); | |
265 | |
266 ValidateSetupPath(ctx, cmd_line.GetProgram(), name, is_valid); | |
267 | |
268 SwitchExpectations expected; | |
269 | |
270 expected.push_back(std::make_pair( | |
271 std::string(switches::kChromeAppLauncher), true)); | |
272 expected.push_back(std::make_pair( | |
273 std::string(switches::kSystemLevel), false)); | |
274 expected.push_back(std::make_pair( | |
275 std::string(switches::kMultiInstall), true)); | |
276 expected.push_back(std::make_pair( | |
277 std::string(switches::kEnsureGoogleUpdatePresent), true)); | |
278 | |
279 ValidateCommandExpectations(ctx, cmd_line, expected, name, is_valid); | |
280 | |
281 std::set<base::string16> flags_exp; | |
282 flags_exp.insert(google_update::kRegSendsPingsField); | |
283 flags_exp.insert(google_update::kRegWebAccessibleField); | |
284 flags_exp.insert(google_update::kRegRunAsUserField); | |
285 ValidateAppCommandFlags(ctx, app_cmd, flags_exp, name, is_valid); | |
286 } | |
287 | |
288 // Validates a product's set of Google Update product commands against a | 190 // Validates a product's set of Google Update product commands against a |
289 // collection of expectations. | 191 // collection of expectations. |
290 void InstallationValidator::ValidateAppCommandExpectations( | 192 void InstallationValidator::ValidateAppCommandExpectations( |
291 const ProductContext& ctx, | 193 const ProductContext& ctx, |
292 const CommandExpectations& expectations, | 194 const CommandExpectations& expectations, |
293 bool* is_valid) { | 195 bool* is_valid) { |
294 DCHECK(is_valid); | 196 DCHECK(is_valid); |
295 | 197 |
296 CommandExpectations the_expectations(expectations); | 198 CommandExpectations the_expectations(expectations); |
297 | 199 |
(...skipping 20 matching lines...) Expand all Loading... |
318 CommandExpectations::const_iterator scan(the_expectations.begin()); | 220 CommandExpectations::const_iterator scan(the_expectations.begin()); |
319 CommandExpectations::const_iterator end(the_expectations.end()); | 221 CommandExpectations::const_iterator end(the_expectations.end()); |
320 for (; scan != end; ++scan) { | 222 for (; scan != end; ++scan) { |
321 *is_valid = false; | 223 *is_valid = false; |
322 LOG(ERROR) << ctx.dist->GetDisplayName() | 224 LOG(ERROR) << ctx.dist->GetDisplayName() |
323 << " is missing the Google Update product command named \"" | 225 << " is missing the Google Update product command named \"" |
324 << scan->first << "\"."; | 226 << scan->first << "\"."; |
325 } | 227 } |
326 } | 228 } |
327 | 229 |
328 // Validates the multi-install binaries' Google Update commands. | |
329 void InstallationValidator::ValidateBinariesCommands( | |
330 const ProductContext& ctx, | |
331 bool* is_valid) { | |
332 DCHECK(is_valid); | |
333 | |
334 const ProductState* binaries_state = ctx.machine_state.GetProductState( | |
335 ctx.system_install, BrowserDistribution::CHROME_BINARIES); | |
336 | |
337 CommandExpectations expectations; | |
338 | |
339 if (binaries_state != NULL) { | |
340 expectations[kCmdQuickEnableApplicationHost] = | |
341 &ValidateQuickEnableApplicationHostCommand; | |
342 | |
343 expectations[kCmdQueryEULAAcceptance] = &ValidateQueryEULAAcceptanceCommand; | |
344 } | |
345 | |
346 ValidateAppCommandExpectations(ctx, expectations, is_valid); | |
347 } | |
348 | |
349 // Validates the multi-install binaries at level |system_level|. | 230 // Validates the multi-install binaries at level |system_level|. |
350 void InstallationValidator::ValidateBinaries( | 231 void InstallationValidator::ValidateBinaries( |
351 const InstallationState& machine_state, | 232 const InstallationState& machine_state, |
352 bool system_install, | 233 bool system_install, |
353 const ProductState& binaries_state, | 234 const ProductState& binaries_state, |
354 bool* is_valid) { | 235 bool* is_valid) { |
355 const ChannelInfo& channel = binaries_state.channel(); | 236 const ChannelInfo& channel = binaries_state.channel(); |
356 | 237 |
357 // ap must have -multi | 238 // ap must have -multi |
358 if (!channel.IsMultiInstall()) { | 239 if (!channel.IsMultiInstall()) { |
(...skipping 26 matching lines...) Expand all Loading... |
385 LOG(ERROR) << "Chrome Binaries are missing \"-chromeframe\" in channel" | 266 LOG(ERROR) << "Chrome Binaries are missing \"-chromeframe\" in channel" |
386 " name: \"" << channel.value() << "\""; | 267 " name: \"" << channel.value() << "\""; |
387 } | 268 } |
388 } else if (channel.IsChromeFrame()) { | 269 } else if (channel.IsChromeFrame()) { |
389 *is_valid = false; | 270 *is_valid = false; |
390 LOG(ERROR) << "Chrome Binaries have \"-chromeframe\" in channel name, yet " | 271 LOG(ERROR) << "Chrome Binaries have \"-chromeframe\" in channel name, yet " |
391 "Chrome Frame is not installed multi: \"" << channel.value() | 272 "Chrome Frame is not installed multi: \"" << channel.value() |
392 << "\""; | 273 << "\""; |
393 } | 274 } |
394 | 275 |
395 // ap must have -applauncher iff Chrome App Launcher is installed multi | 276 // Chrome or Chrome Frame must be present |
396 const ProductState* app_host_state = machine_state.GetProductState( | 277 if (chrome_state == NULL && cf_state == NULL) { |
397 system_install, BrowserDistribution::CHROME_APP_HOST); | |
398 if (app_host_state != NULL) { | |
399 if (!app_host_state->is_multi_install()) { | |
400 *is_valid = false; | |
401 LOG(ERROR) << "Chrome App Launcher is installed in non-multi mode."; | |
402 } | |
403 if (!channel.IsAppLauncher()) { | |
404 *is_valid = false; | |
405 LOG(ERROR) << "Chrome Binaries are missing \"-applauncher\" in channel" | |
406 " name: \"" << channel.value() << "\""; | |
407 } | |
408 } else if (channel.IsAppLauncher()) { | |
409 *is_valid = false; | |
410 LOG(ERROR) << "Chrome Binaries have \"-applauncher\" in channel name, yet " | |
411 "Chrome App Launcher is not installed: \"" << channel.value() | |
412 << "\""; | |
413 } | |
414 | |
415 // Chrome, Chrome Frame, or App Host must be present | |
416 if (chrome_state == NULL && cf_state == NULL && app_host_state == NULL) { | |
417 *is_valid = false; | 278 *is_valid = false; |
418 LOG(ERROR) << "Chrome Binaries are present with no other products."; | 279 LOG(ERROR) << "Chrome Binaries are present with no other products."; |
419 } | 280 } |
420 | 281 |
| 282 |
421 // Chrome must be multi-install if present. | 283 // Chrome must be multi-install if present. |
422 if (chrome_state != NULL && !chrome_state->is_multi_install()) { | 284 if (chrome_state != NULL && !chrome_state->is_multi_install()) { |
423 *is_valid = false; | 285 *is_valid = false; |
424 LOG(ERROR) | 286 LOG(ERROR) |
425 << "Chrome Binaries are present yet Chrome is not multi-install."; | 287 << "Chrome Binaries are present yet Chrome is not multi-install."; |
426 } | 288 } |
427 | 289 |
428 // Chrome Frame must be multi-install if Chrome & App Host are not present. | 290 // Chrome Frame must be multi-install if Chrome is not present. |
429 if (cf_state != NULL && app_host_state == NULL && chrome_state == NULL && | 291 if (cf_state != NULL && chrome_state == NULL && |
430 !cf_state->is_multi_install()) { | 292 !cf_state->is_multi_install()) { |
431 *is_valid = false; | 293 *is_valid = false; |
432 LOG(ERROR) << "Chrome Binaries are present without Chrome nor App Launcher " | 294 LOG(ERROR) << "Chrome Binaries are present without Chrome, yet Chrome Frame" |
433 << "yet Chrome Frame is not multi-install."; | 295 << " is not multi-install."; |
434 } | 296 } |
435 | 297 |
436 ChromeBinariesRules binaries_rules; | 298 ChromeBinariesRules binaries_rules; |
437 ProductContext ctx(machine_state, system_install, binaries_state, | 299 ProductContext ctx(machine_state, system_install, binaries_state, |
438 binaries_rules); | 300 binaries_rules); |
439 | 301 |
440 ValidateBinariesCommands(ctx, is_valid); | |
441 | |
442 ValidateUsageStats(ctx, is_valid); | 302 ValidateUsageStats(ctx, is_valid); |
443 } | 303 } |
444 | 304 |
445 // Validates the path to |setup_exe| for the product described by |ctx|. | 305 // Validates the path to |setup_exe| for the product described by |ctx|. |
446 void InstallationValidator::ValidateSetupPath(const ProductContext& ctx, | 306 void InstallationValidator::ValidateSetupPath(const ProductContext& ctx, |
447 const base::FilePath& setup_exe, | 307 const base::FilePath& setup_exe, |
448 const base::string16& purpose, | 308 const base::string16& purpose, |
449 bool* is_valid) { | 309 bool* is_valid) { |
450 DCHECK(is_valid); | 310 DCHECK(is_valid); |
451 | 311 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 // Validates the multi-install state of the product described in |ctx|. | 431 // Validates the multi-install state of the product described in |ctx|. |
572 void InstallationValidator::ValidateMultiInstallProduct( | 432 void InstallationValidator::ValidateMultiInstallProduct( |
573 const ProductContext& ctx, | 433 const ProductContext& ctx, |
574 bool* is_valid) { | 434 bool* is_valid) { |
575 DCHECK(is_valid); | 435 DCHECK(is_valid); |
576 | 436 |
577 const ProductState* binaries = | 437 const ProductState* binaries = |
578 ctx.machine_state.GetProductState(ctx.system_install, | 438 ctx.machine_state.GetProductState(ctx.system_install, |
579 BrowserDistribution::CHROME_BINARIES); | 439 BrowserDistribution::CHROME_BINARIES); |
580 if (!binaries) { | 440 if (!binaries) { |
581 if (ctx.dist->GetType() == BrowserDistribution::CHROME_APP_HOST) { | 441 *is_valid = false; |
582 if (!ctx.machine_state.GetProductState( | 442 LOG(ERROR) << ctx.dist->GetDisplayName() |
583 true, // system-level | 443 << " (" << ctx.state.version().GetString() << ") is installed " |
584 BrowserDistribution::CHROME_BINARIES) && | 444 << "without Chrome Binaries."; |
585 !ctx.machine_state.GetProductState( | |
586 true, // system-level | |
587 BrowserDistribution::CHROME_BROWSER)) { | |
588 *is_valid = false; | |
589 LOG(ERROR) << ctx.dist->GetDisplayName() | |
590 << " (" << ctx.state.version().GetString() << ") is " | |
591 << "installed without Chrome Binaries or a system-level " | |
592 << "Chrome."; | |
593 } | |
594 } else { | |
595 *is_valid = false; | |
596 LOG(ERROR) << ctx.dist->GetDisplayName() | |
597 << " (" << ctx.state.version().GetString() << ") is installed " | |
598 << "without Chrome Binaries."; | |
599 } | |
600 } else { | 445 } else { |
601 // Version must match that of binaries. | 446 // Version must match that of binaries. |
602 if (ctx.state.version().CompareTo(binaries->version()) != 0) { | 447 if (ctx.state.version().CompareTo(binaries->version()) != 0) { |
603 *is_valid = false; | 448 *is_valid = false; |
604 LOG(ERROR) << "Version of " << ctx.dist->GetDisplayName() | 449 LOG(ERROR) << "Version of " << ctx.dist->GetDisplayName() |
605 << " (" << ctx.state.version().GetString() << ") does not " | 450 << " (" << ctx.state.version().GetString() << ") does not " |
606 "match that of Chrome Binaries (" | 451 "match that of Chrome Binaries (" |
607 << binaries->version().GetString() << ")."; | 452 << binaries->version().GetString() << ")."; |
608 } | 453 } |
609 | 454 |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 if (product_state != NULL) { | 559 if (product_state != NULL) { |
715 ChromeFrameRules chrome_frame_rules; | 560 ChromeFrameRules chrome_frame_rules; |
716 ValidateProduct(machine_state, system_level, *product_state, | 561 ValidateProduct(machine_state, system_level, *product_state, |
717 chrome_frame_rules, &rock_on); | 562 chrome_frame_rules, &rock_on); |
718 int cf_bit = !product_state->is_multi_install() ? | 563 int cf_bit = !product_state->is_multi_install() ? |
719 ProductBits::CHROME_FRAME_SINGLE : | 564 ProductBits::CHROME_FRAME_SINGLE : |
720 ProductBits::CHROME_FRAME_MULTI; | 565 ProductBits::CHROME_FRAME_MULTI; |
721 *type = static_cast<InstallationType>(*type | cf_bit); | 566 *type = static_cast<InstallationType>(*type | cf_bit); |
722 } | 567 } |
723 | 568 |
724 // Is Chrome App Host installed? | |
725 product_state = | |
726 machine_state.GetProductState(system_level, | |
727 BrowserDistribution::CHROME_APP_HOST); | |
728 if (product_state != NULL) { | |
729 ChromeAppHostRules chrome_app_host_rules; | |
730 ValidateProduct(machine_state, system_level, *product_state, | |
731 chrome_app_host_rules, &rock_on); | |
732 *type = static_cast<InstallationType>(*type | ProductBits::CHROME_APP_HOST); | |
733 if (!product_state->is_multi_install()) { | |
734 LOG(ERROR) << "Chrome App Launcher must always be multi-install."; | |
735 rock_on = false; | |
736 } | |
737 } | |
738 | |
739 DCHECK_NE(std::find(&kInstallationTypes[0], | 569 DCHECK_NE(std::find(&kInstallationTypes[0], |
740 &kInstallationTypes[arraysize(kInstallationTypes)], | 570 &kInstallationTypes[arraysize(kInstallationTypes)], |
741 *type), | 571 *type), |
742 &kInstallationTypes[arraysize(kInstallationTypes)]) | 572 &kInstallationTypes[arraysize(kInstallationTypes)]) |
743 << "Invalid combination of products found on system (" << *type << ")"; | 573 << "Invalid combination of products found on system (" << *type << ")"; |
744 | 574 |
745 return rock_on; | 575 return rock_on; |
746 } | 576 } |
747 | 577 |
748 // static | 578 // static |
749 bool InstallationValidator::ValidateInstallationType(bool system_level, | 579 bool InstallationValidator::ValidateInstallationType(bool system_level, |
750 InstallationType* type) { | 580 InstallationType* type) { |
751 DCHECK(type); | 581 DCHECK(type); |
752 InstallationState machine_state; | 582 InstallationState machine_state; |
753 | 583 |
754 machine_state.Initialize(); | 584 machine_state.Initialize(); |
755 | 585 |
756 return ValidateInstallationTypeForState(machine_state, system_level, type); | 586 return ValidateInstallationTypeForState(machine_state, system_level, type); |
757 } | 587 } |
758 | 588 |
759 } // namespace installer | 589 } // namespace installer |
OLD | NEW |