Chromium Code Reviews| 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 #include "chrome/installer/util/installer_state.h" | 5 #include "chrome/installer/util/installer_state.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 63 } | 63 } |
| 64 | 64 |
| 65 InstallerState::InstallerState() | 65 InstallerState::InstallerState() |
| 66 : operation_(UNINITIALIZED), | 66 : operation_(UNINITIALIZED), |
| 67 state_type_(BrowserDistribution::CHROME_BROWSER), | 67 state_type_(BrowserDistribution::CHROME_BROWSER), |
| 68 multi_package_distribution_(NULL), | 68 multi_package_distribution_(NULL), |
| 69 level_(UNKNOWN_LEVEL), | 69 level_(UNKNOWN_LEVEL), |
| 70 package_type_(UNKNOWN_PACKAGE_TYPE), | 70 package_type_(UNKNOWN_PACKAGE_TYPE), |
| 71 root_key_(NULL), | 71 root_key_(NULL), |
| 72 msi_(false), | 72 msi_(false), |
| 73 verbose_logging_(false), | 73 verbose_logging_(false) { |
| 74 ensure_google_update_present_(false) { | |
| 75 } | 74 } |
| 76 | 75 |
| 77 InstallerState::InstallerState(Level level) | 76 InstallerState::InstallerState(Level level) |
| 78 : operation_(UNINITIALIZED), | 77 : operation_(UNINITIALIZED), |
| 79 state_type_(BrowserDistribution::CHROME_BROWSER), | 78 state_type_(BrowserDistribution::CHROME_BROWSER), |
| 80 multi_package_distribution_(NULL), | 79 multi_package_distribution_(NULL), |
| 81 level_(UNKNOWN_LEVEL), | 80 level_(UNKNOWN_LEVEL), |
| 82 package_type_(UNKNOWN_PACKAGE_TYPE), | 81 package_type_(UNKNOWN_PACKAGE_TYPE), |
| 83 root_key_(NULL), | 82 root_key_(NULL), |
| 84 msi_(false), | 83 msi_(false), |
| 85 verbose_logging_(false), | 84 verbose_logging_(false) { |
| 86 ensure_google_update_present_(false) { | |
| 87 // Use set_level() so that root_key_ is updated properly. | 85 // Use set_level() so that root_key_ is updated properly. |
| 88 set_level(level); | 86 set_level(level); |
| 89 } | 87 } |
| 90 | 88 |
| 91 void InstallerState::Initialize(const CommandLine& command_line, | 89 void InstallerState::Initialize(const CommandLine& command_line, |
| 92 const MasterPreferences& prefs, | 90 const MasterPreferences& prefs, |
| 93 const InstallationState& machine_state) { | 91 const InstallationState& machine_state) { |
| 94 Clear(); | 92 Clear(); |
| 95 | 93 |
| 96 bool pref_bool; | 94 bool pref_bool; |
| 97 if (!prefs.GetBool(master_preferences::kSystemLevel, &pref_bool)) | 95 if (!prefs.GetBool(master_preferences::kSystemLevel, &pref_bool)) |
| 98 pref_bool = false; | 96 pref_bool = false; |
| 99 set_level(pref_bool ? SYSTEM_LEVEL : USER_LEVEL); | 97 set_level(pref_bool ? SYSTEM_LEVEL : USER_LEVEL); |
| 100 | 98 |
| 101 if (!prefs.GetBool(master_preferences::kVerboseLogging, &verbose_logging_)) | 99 if (!prefs.GetBool(master_preferences::kVerboseLogging, &verbose_logging_)) |
| 102 verbose_logging_ = false; | 100 verbose_logging_ = false; |
| 103 | 101 |
| 104 if (!prefs.GetBool(master_preferences::kMultiInstall, &pref_bool)) | 102 if (!prefs.GetBool(master_preferences::kMultiInstall, &pref_bool)) |
| 105 pref_bool = false; | 103 pref_bool = false; |
| 106 set_package_type(pref_bool ? MULTI_PACKAGE : SINGLE_PACKAGE); | 104 set_package_type(pref_bool ? MULTI_PACKAGE : SINGLE_PACKAGE); |
| 107 | 105 |
| 108 if (!prefs.GetBool(master_preferences::kMsi, &msi_)) | 106 if (!prefs.GetBool(master_preferences::kMsi, &msi_)) |
| 109 msi_ = false; | 107 msi_ = false; |
| 110 | 108 |
| 111 ensure_google_update_present_ = | |
| 112 command_line.HasSwitch(installer::switches::kEnsureGoogleUpdatePresent); | |
| 113 | |
| 114 const bool is_uninstall = command_line.HasSwitch(switches::kUninstall); | 109 const bool is_uninstall = command_line.HasSwitch(switches::kUninstall); |
| 115 | 110 |
| 116 if (prefs.install_chrome()) { | 111 if (prefs.install_chrome()) { |
| 117 Product* p = AddProductFromPreferences( | 112 Product* p = AddProductFromPreferences( |
| 118 BrowserDistribution::CHROME_BROWSER, prefs, machine_state); | 113 BrowserDistribution::CHROME_BROWSER, prefs, machine_state); |
| 119 VLOG(1) << (is_uninstall ? "Uninstall" : "Install") | 114 VLOG(1) << (is_uninstall ? "Uninstall" : "Install") |
| 120 << " distribution: " << p->distribution()->GetDisplayName(); | 115 << " distribution: " << p->distribution()->GetDisplayName(); |
| 121 } | 116 } |
| 122 | 117 |
| 123 if (prefs.install_chrome_app_launcher()) { | 118 |
| 119 // TODO(huangs): remove comment after review! | |
| 120 // Undoing big changes from https://chromiumcodereview.appspot.com/10665002. | |
| 121 if (is_multi_install()) { | |
| 124 Product* p = AddProductFromPreferences( | 122 Product* p = AddProductFromPreferences( |
|
huangs
2015/01/05 06:01:12
This is problematic, since we can't install binari
| |
| 125 BrowserDistribution::CHROME_APP_HOST, prefs, machine_state); | 123 BrowserDistribution::CHROME_BINARIES, prefs, machine_state); |
| 126 VLOG(1) << (is_uninstall ? "Uninstall" : "Install") | 124 VLOG(1) << (is_uninstall ? "Uninstall" : "Install") |
| 127 << " distribution: " << p->distribution()->GetDisplayName(); | 125 << " distribution: " << p->distribution()->GetDisplayName(); |
| 128 } | 126 } |
| 129 | 127 |
| 130 if (!is_uninstall && is_multi_install()) { | |
| 131 bool need_binaries = false; | |
| 132 if (FindProduct(BrowserDistribution::CHROME_APP_HOST)) { | |
| 133 // App Host will happily use Chrome at system level, or binaries at system | |
| 134 // level, even if app host is user level. | |
| 135 const ProductState* chrome_state = machine_state.GetProductState( | |
| 136 true, // system level | |
| 137 BrowserDistribution::CHROME_BROWSER); | |
| 138 // If Chrome is at system-level, multi- or otherwise. We'll use it. | |
| 139 if (!chrome_state) { | |
| 140 const ProductState* binaries_state = machine_state.GetProductState( | |
| 141 true, // system level | |
| 142 BrowserDistribution::CHROME_BINARIES); | |
| 143 if (!binaries_state) | |
| 144 need_binaries = true; | |
| 145 } | |
| 146 } | |
| 147 | |
| 148 // Chrome multi needs Binaries at its own level. | |
| 149 if (FindProduct(BrowserDistribution::CHROME_BROWSER)) | |
| 150 need_binaries = true; | |
| 151 | |
| 152 if (need_binaries && !FindProduct(BrowserDistribution::CHROME_BINARIES)) { | |
| 153 // Force binaries to be installed/updated. | |
| 154 Product* p = AddProductFromPreferences( | |
| 155 BrowserDistribution::CHROME_BINARIES, prefs, machine_state); | |
| 156 VLOG(1) << "Install distribution: " | |
| 157 << p->distribution()->GetDisplayName(); | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 if (is_uninstall && prefs.is_multi_install()) { | |
| 162 if (FindProduct(BrowserDistribution::CHROME_BROWSER)) { | |
| 163 // Uninstall each product of type |type| listed below based on the | |
| 164 // presence or absence of |switch_name| in that product's uninstall | |
| 165 // command. | |
| 166 const struct { | |
| 167 BrowserDistribution::Type type; | |
| 168 const char* switch_name; | |
| 169 bool switch_expected; | |
| 170 } conditional_additions[] = { | |
| 171 // If the App Host is installed, but not the App Launcher, remove it | |
| 172 // with Chrome. Note however that for system-level Chrome uninstalls, | |
| 173 // any installed user-level App Host will remain even if there is no | |
| 174 // App Launcher present (the orphaned app_host.exe will prompt the user | |
| 175 // for further action when executed). | |
| 176 { BrowserDistribution::CHROME_APP_HOST, | |
| 177 switches::kChromeAppLauncher, | |
| 178 false }, | |
| 179 }; | |
| 180 | |
| 181 for (size_t i = 0; i < arraysize(conditional_additions); ++i) { | |
| 182 const ProductState* product_state = machine_state.GetProductState( | |
| 183 system_install(), conditional_additions[i].type); | |
| 184 if (product_state != NULL && | |
| 185 product_state->uninstall_command().HasSwitch( | |
| 186 conditional_additions[i].switch_name) == | |
| 187 conditional_additions[i].switch_expected && | |
| 188 !FindProduct(conditional_additions[i].type)) { | |
| 189 Product* p = AddProductFromPreferences( | |
| 190 conditional_additions[i].type, prefs, machine_state); | |
| 191 VLOG(1) << "Uninstall distribution: " | |
| 192 << p->distribution()->GetDisplayName(); | |
| 193 } | |
| 194 } | |
| 195 } | |
| 196 | |
| 197 bool keep_binaries = false; | |
| 198 // Look for a multi-install product that is not the binaries and that is not | |
| 199 // being uninstalled. If not found, binaries are uninstalled too. | |
| 200 for (size_t i = 0; i < BrowserDistribution::NUM_TYPES; ++i) { | |
| 201 BrowserDistribution::Type type = | |
| 202 static_cast<BrowserDistribution::Type>(i); | |
| 203 | |
| 204 if (type == BrowserDistribution::CHROME_BINARIES) | |
| 205 continue; | |
| 206 | |
| 207 const ProductState* product_state = | |
| 208 machine_state.GetProductState(system_install(), type); | |
| 209 if (product_state == NULL) { | |
| 210 // The product is not installed. | |
| 211 continue; | |
| 212 } | |
| 213 | |
| 214 if (!product_state->is_multi_install() && | |
| 215 type != BrowserDistribution::CHROME_BROWSER) { | |
| 216 // The product is not sharing the binaries. It is ordinarily impossible | |
| 217 // for single-install Chrome to be installed along with any | |
| 218 // multi-install product. Treat single-install Chrome the same as any | |
| 219 // multi-install product just in case the impossible happens. | |
| 220 continue; | |
| 221 } | |
| 222 | |
| 223 // The product is installed. | |
| 224 | |
| 225 if (!FindProduct(type)) { | |
| 226 // The product is not being uninstalled. | |
| 227 if (type != BrowserDistribution::CHROME_APP_HOST) { | |
| 228 keep_binaries = true; | |
| 229 break; | |
| 230 } else { | |
| 231 // If binaries/chrome are at system-level, we can discard them at | |
| 232 // user-level... | |
| 233 if (!machine_state.GetProductState( | |
| 234 true, // system-level | |
| 235 BrowserDistribution::CHROME_BROWSER) && | |
| 236 !machine_state.GetProductState( | |
| 237 true, // system-level | |
| 238 BrowserDistribution::CHROME_BINARIES)) { | |
| 239 // ... otherwise keep them. | |
| 240 keep_binaries = true; | |
| 241 break; | |
| 242 } | |
| 243 } | |
| 244 } | |
| 245 | |
| 246 // The product is being uninstalled. | |
| 247 } | |
| 248 if (!keep_binaries && | |
| 249 machine_state.GetProductState(system_install(), | |
| 250 BrowserDistribution::CHROME_BINARIES)) { | |
| 251 Product* p = AddProductFromPreferences( | |
| 252 BrowserDistribution::CHROME_BINARIES, prefs, machine_state); | |
| 253 VLOG(1) << (is_uninstall ? "Uninstall" : "Install") | |
| 254 << " distribution: " << p->distribution()->GetDisplayName(); | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 BrowserDistribution* operand = NULL; | 128 BrowserDistribution* operand = NULL; |
| 259 | 129 |
| 260 if (is_uninstall) { | 130 if (is_uninstall) { |
| 261 operation_ = UNINSTALL; | 131 operation_ = UNINSTALL; |
| 262 } else if (!prefs.is_multi_install()) { | 132 } else if (!prefs.is_multi_install()) { |
| 263 // For a single-install, the current browser dist is the operand. | 133 // For a single-install, the current browser dist is the operand. |
| 264 operand = BrowserDistribution::GetDistribution(); | 134 operand = BrowserDistribution::GetDistribution(); |
| 265 operation_ = SINGLE_INSTALL_OR_UPDATE; | 135 operation_ = SINGLE_INSTALL_OR_UPDATE; |
| 266 } else if (IsMultiInstallUpdate(prefs, machine_state)) { | 136 } else if (IsMultiInstallUpdate(prefs, machine_state)) { |
| 267 // Updates driven by Google Update take place under the multi-installer's | 137 // Updates driven by Google Update take place under the multi-installer's |
| 268 // app guid. | 138 // app guid. |
| 269 operand = multi_package_distribution_; | 139 operand = multi_package_distribution_; |
| 270 operation_ = MULTI_UPDATE; | 140 operation_ = MULTI_UPDATE; |
| 271 } else { | 141 } else { |
| 272 operation_ = MULTI_INSTALL; | 142 operation_ = MULTI_INSTALL; |
| 273 } | 143 } |
| 274 | 144 |
| 275 // Initial, over, and un-installs will take place under one of the product app | |
| 276 // guids (Chrome, App Host, or Binaries, in order of preference). | |
| 277 if (operand == NULL) { | 145 if (operand == NULL) { |
| 278 BrowserDistribution::Type operand_distribution_type = | |
| 279 BrowserDistribution::CHROME_BINARIES; | |
| 280 if (prefs.install_chrome()) | |
| 281 operand_distribution_type = BrowserDistribution::CHROME_BROWSER; | |
| 282 else if (prefs.install_chrome_app_launcher()) | |
| 283 operand_distribution_type = BrowserDistribution::CHROME_APP_HOST; | |
| 284 | |
| 285 operand = BrowserDistribution::GetSpecificDistribution( | 146 operand = BrowserDistribution::GetSpecificDistribution( |
| 286 operand_distribution_type); | 147 prefs.install_chrome() ? |
| 148 BrowserDistribution::CHROME_BROWSER : | |
| 149 BrowserDistribution::CHROME_BINARIES); | |
| 287 } | 150 } |
| 288 | 151 |
| 289 state_key_ = operand->GetStateKey(); | 152 state_key_ = operand->GetStateKey(); |
| 290 state_type_ = operand->GetType(); | 153 state_type_ = operand->GetType(); |
| 291 | 154 |
| 292 // Parse --critical-update-version=W.X.Y.Z | 155 // Parse --critical-update-version=W.X.Y.Z |
| 293 std::string critical_version_value( | 156 std::string critical_version_value( |
| 294 command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); | 157 command_line.GetSwitchValueASCII(switches::kCriticalUpdateVersion)); |
| 295 critical_update_version_ = Version(critical_version_value); | 158 critical_update_version_ = Version(critical_version_value); |
| 296 } | 159 } |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 599 state_key_.clear(); | 462 state_key_.clear(); |
| 600 state_type_ = BrowserDistribution::CHROME_BROWSER; | 463 state_type_ = BrowserDistribution::CHROME_BROWSER; |
| 601 products_.clear(); | 464 products_.clear(); |
| 602 multi_package_distribution_ = NULL; | 465 multi_package_distribution_ = NULL; |
| 603 critical_update_version_ = base::Version(); | 466 critical_update_version_ = base::Version(); |
| 604 level_ = UNKNOWN_LEVEL; | 467 level_ = UNKNOWN_LEVEL; |
| 605 package_type_ = UNKNOWN_PACKAGE_TYPE; | 468 package_type_ = UNKNOWN_PACKAGE_TYPE; |
| 606 root_key_ = NULL; | 469 root_key_ = NULL; |
| 607 msi_ = false; | 470 msi_ = false; |
| 608 verbose_logging_ = false; | 471 verbose_logging_ = false; |
| 609 ensure_google_update_present_ = false; | |
| 610 } | 472 } |
| 611 | 473 |
| 612 bool InstallerState::AnyExistsAndIsInUse( | 474 bool InstallerState::AnyExistsAndIsInUse( |
| 613 const InstallationState& machine_state, | 475 const InstallationState& machine_state, |
| 614 uint32 file_bits) const { | 476 uint32 file_bits) const { |
| 615 static const wchar_t* const kBinaryFileNames[] = { | 477 static const wchar_t* const kBinaryFileNames[] = { |
| 616 kChromeDll, | 478 kChromeDll, |
| 617 kChromeFrameDll, | 479 kChromeFrameDll, |
| 618 kChromeFrameHelperDll, | 480 kChromeFrameHelperDll, |
| 619 kChromeFrameHelperExe, | 481 kChromeFrameHelperExe, |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 824 } | 686 } |
| 825 if (!install_list->Do()) | 687 if (!install_list->Do()) |
| 826 LOG(ERROR) << "Failed to record installer error information in registry."; | 688 LOG(ERROR) << "Failed to record installer error information in registry."; |
| 827 } | 689 } |
| 828 | 690 |
| 829 bool InstallerState::RequiresActiveSetup() const { | 691 bool InstallerState::RequiresActiveSetup() const { |
| 830 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); | 692 return system_install() && FindProduct(BrowserDistribution::CHROME_BROWSER); |
| 831 } | 693 } |
| 832 | 694 |
| 833 } // namespace installer | 695 } // namespace installer |
| OLD | NEW |