Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Side by Side Diff: chrome/installer/setup/install_worker.cc

Issue 10805043: (re-commit) Implement installation of the Chrome App Host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix setup_unittests Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 // This file contains the definitions of the installer functions that build 5 // This file contains the definitions of the installer functions that build
6 // the WorkItemList used to install the application. 6 // the WorkItemList used to install the application.
7 7
8 #include "chrome/installer/setup/install_worker.h" 8 #include "chrome/installer/setup/install_worker.h"
9 9
10 #include <oaidl.h> 10 #include <oaidl.h>
11 #include <shlobj.h> 11 #include <shlobj.h>
12 #include <time.h> 12 #include <time.h>
13 13
14 #include <vector> 14 #include <vector>
15 15
16 #include "base/command_line.h" 16 #include "base/command_line.h"
17 #include "base/file_path.h" 17 #include "base/file_path.h"
18 #include "base/file_util.h" 18 #include "base/file_util.h"
19 #include "base/logging.h" 19 #include "base/logging.h"
20 #include "base/path_service.h" 20 #include "base/path_service.h"
21 #include "base/string16.h" 21 #include "base/string16.h"
22 #include "base/string_util.h" 22 #include "base/string_util.h"
23 #include "base/utf_string_conversions.h" 23 #include "base/utf_string_conversions.h"
24 #include "base/version.h" 24 #include "base/version.h"
25 #include "base/win/registry.h" 25 #include "base/win/registry.h"
26 #include "base/win/windows_version.h" 26 #include "base/win/windows_version.h"
27 #include "chrome/common/chrome_constants.h" 27 #include "chrome/common/chrome_constants.h"
28 #include "chrome/common/chrome_switches.h"
28 #include "chrome/installer/setup/install.h" 29 #include "chrome/installer/setup/install.h"
29 #include "chrome/installer/setup/setup_constants.h" 30 #include "chrome/installer/setup/setup_constants.h"
30 #include "chrome/installer/setup/setup_util.h" 31 #include "chrome/installer/setup/setup_util.h"
31 #include "chrome/installer/util/browser_distribution.h" 32 #include "chrome/installer/util/browser_distribution.h"
32 #include "chrome/installer/util/conditional_work_item_list.h" 33 #include "chrome/installer/util/conditional_work_item_list.h"
33 #include "chrome/installer/util/create_reg_key_work_item.h" 34 #include "chrome/installer/util/create_reg_key_work_item.h"
34 #include "chrome/installer/util/google_update_constants.h" 35 #include "chrome/installer/util/google_update_constants.h"
35 #include "chrome/installer/util/helper.h" 36 #include "chrome/installer/util/helper.h"
36 #include "chrome/installer/util/install_util.h" 37 #include "chrome/installer/util/install_util.h"
37 #include "chrome/installer/util/installation_state.h" 38 #include "chrome/installer/util/installation_state.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 const FilePath& temp_path, 97 const FilePath& temp_path,
97 const Version& new_version, 98 const Version& new_version,
98 WorkItemList* install_list) { 99 WorkItemList* install_list) {
99 DCHECK(install_list); 100 DCHECK(install_list);
100 FilePath installer_dir(installer_state.GetInstallerDirectory(new_version)); 101 FilePath installer_dir(installer_state.GetInstallerDirectory(new_version));
101 install_list->AddCreateDirWorkItem(installer_dir); 102 install_list->AddCreateDirWorkItem(installer_dir);
102 103
103 FilePath exe_dst(installer_dir.Append(setup_path.BaseName())); 104 FilePath exe_dst(installer_dir.Append(setup_path.BaseName()));
104 FilePath archive_dst(installer_dir.Append(archive_path.BaseName())); 105 FilePath archive_dst(installer_dir.Append(archive_path.BaseName()));
105 106
106 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(), 107 if (exe_dst != setup_path) {
107 temp_path.value(), WorkItem::ALWAYS); 108 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(),
109 temp_path.value(), WorkItem::ALWAYS);
110 }
108 111
109 // In the past, we copied rather than moved for system level installs so that 112 if (archive_path != archive_dst) {
110 // the permissions of %ProgramFiles% would be picked up. Now that |temp_path| 113 // In the past, we copied rather than moved for system level installs so
111 // is in %ProgramFiles% for system level installs (and in %LOCALAPPDATA% 114 // that the permissions of %ProgramFiles% would be picked up. Now that
112 // otherwise), there is no need to do this for the archive. Setup.exe, on 115 // |temp_path| is in %ProgramFiles% for system level installs (and in
113 // the other hand, is created elsewhere so it must always be copied. 116 // %LOCALAPPDATA% otherwise), there is no need to do this for the archive.
114 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(), 117 // Setup.exe, on the other hand, is created elsewhere so it must always be
115 temp_path.value(), WorkItem::ALWAYS_MOVE); 118 // copied.
119 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(),
120 temp_path.value(), WorkItem::ALWAYS_MOVE);
121 }
116 } 122 }
117 123
118 // This method adds work items to create (or update) Chrome uninstall entry in 124 // This method adds work items to create (or update) Chrome uninstall entry in
119 // either the Control Panel->Add/Remove Programs list or in the Omaha client 125 // either the Control Panel->Add/Remove Programs list or in the Omaha client
120 // state key if running under an MSI installer. 126 // state key if running under an MSI installer.
121 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, 127 void AddUninstallShortcutWorkItems(const InstallerState& installer_state,
122 const FilePath& setup_path, 128 const FilePath& setup_path,
123 const Version& new_version, 129 const Version& new_version,
124 WorkItemList* install_list, 130 WorkItemList* install_list,
125 const Product& product) { 131 const Product& product) {
(...skipping 10 matching lines...) Expand all
136 // locate the setup.exe instance used for binary patching. 142 // locate the setup.exe instance used for binary patching.
137 // Do not quote the command line for the MSI invocation. 143 // Do not quote the command line for the MSI invocation.
138 FilePath install_path(installer_state.target_path()); 144 FilePath install_path(installer_state.target_path());
139 FilePath installer_path(installer_state.GetInstallerDirectory(new_version)); 145 FilePath installer_path(installer_state.GetInstallerDirectory(new_version));
140 installer_path = installer_path.Append(setup_path.BaseName()); 146 installer_path = installer_path.Append(setup_path.BaseName());
141 147
142 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); 148 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM);
143 AppendUninstallCommandLineFlags(installer_state, product, 149 AppendUninstallCommandLineFlags(installer_state, product,
144 &uninstall_arguments); 150 &uninstall_arguments);
145 151
146 // The Chrome uninstallation command serves as the master uninstall command 152 // If Chrome Frame is installed in Ready Mode, add --chrome-frame to Chrome's
147 // for Chrome + all other products (i.e. Chrome Frame) that do not have an 153 // uninstall entry. We skip this processing in case of uninstall since this
148 // uninstall entry in the Add/Remove Programs dialog. We skip this processing 154 // means that Chrome Frame is being uninstalled, so there's no need to do any
149 // in case of uninstall since this means that Chrome Frame is being 155 // looping.
150 // uninstalled, so there's no need to do any looping.
151 if (product.is_chrome() && 156 if (product.is_chrome() &&
152 installer_state.operation() != InstallerState::UNINSTALL) { 157 installer_state.operation() != InstallerState::UNINSTALL) {
153 const Products& products = installer_state.products(); 158 const Product* chrome_frame =
154 for (size_t i = 0; i < products.size(); ++i) { 159 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME);
155 const Product& p = *products[i]; 160 if (chrome_frame && chrome_frame->HasOption(kOptionReadyMode))
156 if (!p.is_chrome() && !p.ShouldCreateUninstallEntry()) 161 chrome_frame->AppendProductFlags(&uninstall_arguments);
157 p.AppendProductFlags(&uninstall_arguments);
158 }
159 } 162 }
160 163
161 std::wstring update_state_key(browser_dist->GetStateKey()); 164 std::wstring update_state_key(browser_dist->GetStateKey());
162 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); 165 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key);
163 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, 166 install_list->AddSetRegValueWorkItem(reg_root, update_state_key,
164 installer::kUninstallStringField, installer_path.value(), true); 167 installer::kUninstallStringField, installer_path.value(), true);
165 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, 168 install_list->AddSetRegValueWorkItem(reg_root, update_state_key,
166 installer::kUninstallArgumentsField, 169 installer::kUninstallArgumentsField,
167 uninstall_arguments.GetCommandLineString(), true); 170 uninstall_arguments.GetCommandLineString(), true);
168 171
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 if (version_components.size() == 4) { 224 if (version_components.size() == 4) {
222 // Our version should be in major.minor.build.rev. 225 // Our version should be in major.minor.build.rev.
223 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, 226 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
224 L"VersionMajor", static_cast<DWORD>(version_components[2]), true); 227 L"VersionMajor", static_cast<DWORD>(version_components[2]), true);
225 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, 228 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
226 L"VersionMinor", static_cast<DWORD>(version_components[3]), true); 229 L"VersionMinor", static_cast<DWORD>(version_components[3]), true);
227 } 230 }
228 } 231 }
229 } 232 }
230 233
231 // Add uninstall-related work items for multi-install scenarios.
232 void AddMultiUninstallWorkItems(const InstallerState& installer_state,
233 const FilePath& setup_path,
234 const Version& new_version,
235 WorkItemList* install_list) {
236 DCHECK(installer_state.is_multi_install());
237
238 // The mini_installer needs a reliable way to locate setup.exe for diff
239 // updates. For single-installs, the product's ClientState key is consulted
240 // (Chrome's or Chrome Frame's). For multi-installs, the binaries' key is
241 // used.
242 const HKEY reg_root = installer_state.root_key();
243 std::wstring binaries_state_key(
244 installer_state.multi_package_binaries_distribution()->GetStateKey());
245 FilePath installer_path(
246 installer_state.GetInstallerDirectory(new_version)
247 .Append(setup_path.BaseName()));
248 install_list->AddCreateRegKeyWorkItem(reg_root, binaries_state_key);
249 install_list->AddSetRegValueWorkItem(reg_root, binaries_state_key,
250 installer::kUninstallStringField, installer_path.value(), true);
251 }
252
253 // Create Version key for a product (if not already present) and sets the new 234 // Create Version key for a product (if not already present) and sets the new
254 // product version as the last step. 235 // product version as the last step.
255 void AddVersionKeyWorkItems(HKEY root, 236 void AddVersionKeyWorkItems(HKEY root,
256 BrowserDistribution* dist, 237 BrowserDistribution* dist,
257 const Version& new_version, 238 const Version& new_version,
258 bool add_language_identifier, 239 bool add_language_identifier,
259 WorkItemList* list) { 240 WorkItemList* list) {
260 // Create Version key for each distribution (if not already present) and set 241 // Create Version key for each distribution (if not already present) and set
261 // the new product version as the last step. 242 // the new product version as the last step.
262 std::wstring version_key(dist->GetVersionKey()); 243 std::wstring version_key(dist->GetVersionKey());
(...skipping 16 matching lines...) Expand all
279 list->AddSetRegValueWorkItem(root, version_key, 260 list->AddSetRegValueWorkItem(root, version_key,
280 google_update::kRegLangField, language, 261 google_update::kRegLangField, language,
281 false); // do not overwrite language 262 false); // do not overwrite language
282 } 263 }
283 list->AddSetRegValueWorkItem(root, version_key, 264 list->AddSetRegValueWorkItem(root, version_key,
284 google_update::kRegVersionField, 265 google_update::kRegVersionField,
285 ASCIIToWide(new_version.GetString()), 266 ASCIIToWide(new_version.GetString()),
286 true); // overwrite version 267 true); // overwrite version
287 } 268 }
288 269
270 void AddInstallAppCommandWorkItems(const InstallerState& installer_state,
271 const InstallationState& machine_state,
272 const FilePath* setup_path,
273 const Version* new_version,
274 const Product& product,
275 WorkItemList* work_item_list) {
276 DCHECK(product.is_chrome_app_host());
277
278 std::wstring cmd_key(product.distribution()->GetVersionKey());
279 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey)
280 .append(1, L'\\').append(kCmdInstallApp);
281
282 if (installer_state.operation() != InstallerState::UNINSTALL) {
283 FilePath target_path(installer_state.target_path());
284 CommandLine cmd_line(target_path.Append(installer::kChromeAppHostExe));
285 cmd_line.AppendSwitchASCII(::switches::kAppsInstallFromManifestURL, "%1");
286
287 AppCommand cmd(cmd_line.GetCommandLineString(), true, true);
288 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list);
289 } else {
290 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(),
291 cmd_key)->set_log_message(
292 "removing install-application command");
293 }
294 }
295
289 void AddProductSpecificWorkItems(const InstallationState& original_state, 296 void AddProductSpecificWorkItems(const InstallationState& original_state,
290 const InstallerState& installer_state, 297 const InstallerState& installer_state,
291 const FilePath& setup_path, 298 const FilePath& setup_path,
292 const Version& new_version, 299 const Version& new_version,
293 WorkItemList* list) { 300 WorkItemList* list) {
294 const Products& products = installer_state.products(); 301 const Products& products = installer_state.products();
295 for (size_t i = 0; i < products.size(); ++i) { 302 for (size_t i = 0; i < products.size(); ++i) {
296 const Product& p = *products[i]; 303 const Product& p = *products[i];
297 if (p.is_chrome_frame()) { 304 if (p.is_chrome_frame()) {
298 AddChromeFrameWorkItems(original_state, installer_state, setup_path, 305 AddChromeFrameWorkItems(original_state, installer_state, setup_path,
299 new_version, p, list); 306 new_version, p, list);
300 } 307 }
308 if (p.is_chrome_app_host()) {
309 AddInstallAppCommandWorkItems(installer_state, original_state,
310 &setup_path, &new_version, p, list);
311 }
301 } 312 }
302 } 313 }
303 314
304 // Mirror oeminstall the first time anything is installed multi. There is no 315 // Mirror oeminstall the first time anything is installed multi. There is no
305 // need to update the value on future install/update runs since this value never 316 // need to update the value on future install/update runs since this value never
306 // changes. Note that the value is removed by Google Update after EULA 317 // changes. Note that the value is removed by Google Update after EULA
307 // acceptance is processed. 318 // acceptance is processed.
308 void AddOemInstallWorkItems(const InstallationState& original_state, 319 void AddOemInstallWorkItems(const InstallationState& original_state,
309 const InstallerState& installer_state, 320 const InstallerState& installer_state,
310 WorkItemList* install_list) { 321 WorkItemList* install_list) {
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 installer_state.operation() == InstallerState::MULTI_UPDATE); 475 installer_state.operation() == InstallerState::MULTI_UPDATE);
465 476
466 HKEY root_key = installer_state.root_key(); 477 HKEY root_key = installer_state.root_key();
467 bool value_found = false; 478 bool value_found = false;
468 DWORD usagestats = 0; 479 DWORD usagestats = 0;
469 const Products& products = installer_state.products(); 480 const Products& products = installer_state.products();
470 481
471 // Search for an existing usagestats value for any product. 482 // Search for an existing usagestats value for any product.
472 for (Products::const_iterator scan = products.begin(), end = products.end(); 483 for (Products::const_iterator scan = products.begin(), end = products.end();
473 !value_found && scan != end; ++scan) { 484 !value_found && scan != end; ++scan) {
485 if ((*scan)->is_chrome_binaries())
486 continue;
474 BrowserDistribution* dist = (*scan)->distribution(); 487 BrowserDistribution* dist = (*scan)->distribution();
475 const ProductState* product_state = 488 const ProductState* product_state =
476 original_state.GetNonVersionedProductState( 489 original_state.GetNonVersionedProductState(
477 installer_state.system_install(), dist->GetType()); 490 installer_state.system_install(), dist->GetType());
478 value_found = product_state->GetUsageStats(&usagestats); 491 value_found = product_state->GetUsageStats(&usagestats);
479 } 492 }
480 493
481 // If a value was found, write it in the appropriate location for the 494 // If a value was found, write it in the appropriate location for the
482 // binaries and remove all values from the products. 495 // binaries and remove all values from the products.
483 if (value_found) { 496 if (value_found) {
484 std::wstring state_key( 497 std::wstring state_key(
485 installer_state.multi_package_binaries_distribution()->GetStateKey()); 498 installer_state.multi_package_binaries_distribution()->GetStateKey());
486 install_list->AddCreateRegKeyWorkItem(root_key, state_key); 499 install_list->AddCreateRegKeyWorkItem(root_key, state_key);
487 // Overwrite any existing value so that overinstalls (where Omaha writes a 500 // Overwrite any existing value so that overinstalls (where Omaha writes a
488 // new value into a product's state key) pick up the correct value. 501 // new value into a product's state key) pick up the correct value.
489 install_list->AddSetRegValueWorkItem(root_key, state_key, 502 install_list->AddSetRegValueWorkItem(root_key, state_key,
490 google_update::kRegUsageStatsField, 503 google_update::kRegUsageStatsField,
491 usagestats, true); 504 usagestats, true);
492 505
493 for (Products::const_iterator scan = products.begin(), end = products.end(); 506 for (Products::const_iterator scan = products.begin(), end = products.end();
494 scan != end; ++scan) { 507 scan != end; ++scan) {
508 if ((*scan)->is_chrome_binaries())
509 continue;
495 BrowserDistribution* dist = (*scan)->distribution(); 510 BrowserDistribution* dist = (*scan)->distribution();
496 if (installer_state.system_install()) { 511 if (installer_state.system_install()) {
497 install_list->AddDeleteRegValueWorkItem( 512 install_list->AddDeleteRegValueWorkItem(
498 root_key, dist->GetStateMediumKey(), 513 root_key, dist->GetStateMediumKey(),
499 google_update::kRegUsageStatsField); 514 google_update::kRegUsageStatsField);
500 // Previous versions of Chrome also wrote a value in HKCU even for 515 // Previous versions of Chrome also wrote a value in HKCU even for
501 // system-level installs, so clean that up. 516 // system-level installs, so clean that up.
502 install_list->AddDeleteRegValueWorkItem( 517 install_list->AddDeleteRegValueWorkItem(
503 HKEY_CURRENT_USER, dist->GetStateKey(), 518 HKEY_CURRENT_USER, dist->GetStateKey(),
504 google_update::kRegUsageStatsField); 519 google_update::kRegUsageStatsField);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 // do a few post install tasks: 574 // do a few post install tasks:
560 // - Handle the case of in-use-update by updating "opv" (old version) key or 575 // - Handle the case of in-use-update by updating "opv" (old version) key or
561 // deleting it if not required. 576 // deleting it if not required.
562 // - Register any new dlls and unregister old dlls. 577 // - Register any new dlls and unregister old dlls.
563 // - If this is an MSI install, ensures that the MSI marker is set, and sets 578 // - If this is an MSI install, ensures that the MSI marker is set, and sets
564 // it if not. 579 // it if not.
565 // If these operations are successful, the function returns true, otherwise 580 // If these operations are successful, the function returns true, otherwise
566 // false. 581 // false.
567 bool AppendPostInstallTasks(const InstallerState& installer_state, 582 bool AppendPostInstallTasks(const InstallerState& installer_state,
568 const FilePath& setup_path, 583 const FilePath& setup_path,
569 const FilePath& new_chrome_exe,
570 const Version* current_version, 584 const Version* current_version,
571 const Version& new_version, 585 const Version& new_version,
572 const FilePath& temp_path, 586 const FilePath& temp_path,
573 WorkItemList* post_install_task_list) { 587 WorkItemList* post_install_task_list) {
574 DCHECK(post_install_task_list); 588 DCHECK(post_install_task_list);
575 589
576 HKEY root = installer_state.root_key(); 590 HKEY root = installer_state.root_key();
577 const Products& products = installer_state.products(); 591 const Products& products = installer_state.products();
592 FilePath new_chrome_exe(
593 installer_state.target_path().Append(installer::kChromeNewExe));
578 594
579 // Append work items that will only be executed if this was an update. 595 // Append work items that will only be executed if this was an update.
580 // We update the 'opv' value with the current version that is active, 596 // We update the 'opv' value with the current version that is active,
581 // the 'cpv' value with the critical update version (if present), and the 597 // the 'cpv' value with the critical update version (if present), and the
582 // 'cmd' value with the rename command to run. 598 // 'cmd' value with the rename command to run.
583 { 599 {
584 scoped_ptr<WorkItemList> in_use_update_work_items( 600 scoped_ptr<WorkItemList> in_use_update_work_items(
585 WorkItem::CreateConditionalWorkItemList( 601 WorkItem::CreateConditionalWorkItemList(
586 new ConditionRunIfFileExists(new_chrome_exe))); 602 new ConditionRunIfFileExists(new_chrome_exe)));
587 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); 603 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList");
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 if (installer_state.is_multi_install()) { 724 if (installer_state.is_multi_install()) {
709 AddSetMsiMarkerWorkItem(installer_state, 725 AddSetMsiMarkerWorkItem(installer_state,
710 installer_state.multi_package_binaries_distribution(), true, 726 installer_state.multi_package_binaries_distribution(), true,
711 post_install_task_list); 727 post_install_task_list);
712 } 728 }
713 } 729 }
714 730
715 return true; 731 return true;
716 } 732 }
717 733
718 void AddInstallWorkItems(const InstallationState& original_state, 734 void AddChromeWorkItems(const InstallationState& original_state,
719 const InstallerState& installer_state, 735 const InstallerState& installer_state,
720 const FilePath& setup_path, 736 const FilePath& setup_path,
721 const FilePath& archive_path, 737 const FilePath& archive_path,
722 const FilePath& src_path, 738 const FilePath& src_path,
723 const FilePath& temp_path, 739 const FilePath& temp_path,
724 const Version& new_version, 740 const Version& new_version,
725 scoped_ptr<Version>* current_version, 741 scoped_ptr<Version>* current_version,
726 WorkItemList* install_list) { 742 WorkItemList* install_list) {
727 DCHECK(install_list);
728
729 const FilePath& target_path = installer_state.target_path(); 743 const FilePath& target_path = installer_state.target_path();
730 744
731 // A temp directory that work items need and the actual install directory.
732 install_list->AddCreateDirWorkItem(temp_path);
733 install_list->AddCreateDirWorkItem(target_path);
734
735 if (current_version != NULL && current_version->get() != NULL) { 745 if (current_version != NULL && current_version->get() != NULL) {
736 // Delete the archive from an existing install to save some disk space. We 746 // Delete the archive from an existing install to save some disk space. We
737 // make this an unconditional work item since there's no need to roll this 747 // make this an unconditional work item since there's no need to roll this
738 // back; if installation fails we'll be moved to the "-full" channel anyway. 748 // back; if installation fails we'll be moved to the "-full" channel anyway.
739 FilePath old_installer_dir( 749 FilePath old_installer_dir(
740 installer_state.GetInstallerDirectory(**current_version)); 750 installer_state.GetInstallerDirectory(**current_version));
741 FilePath old_archive(old_installer_dir.Append(archive_path.BaseName())); 751 FilePath old_archive(old_installer_dir.Append(installer::kChromeArchive));
742 install_list->AddDeleteTreeWorkItem(old_archive, temp_path) 752 // Don't delete the archive that we are actually installing from.
743 ->set_ignore_failure(true); 753 if (archive_path != old_archive) {
754 install_list->AddDeleteTreeWorkItem(old_archive, temp_path)
755 ->set_ignore_failure(true);
756 }
744 } 757 }
745 758
746 // Delete any new_chrome.exe if present (we will end up creating a new one 759 // Delete any new_chrome.exe if present (we will end up creating a new one
747 // if required) and then copy chrome.exe 760 // if required) and then copy chrome.exe
748 FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); 761 FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe));
749 762
750 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); 763 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path);
751 764
752 if (installer_state.IsChromeFrameRunning(original_state)) { 765 if (installer_state.IsChromeFrameRunning(original_state)) {
753 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe"; 766 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe";
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 // Delete any old_chrome.exe if present (ignore failure if it's in use). 849 // Delete any old_chrome.exe if present (ignore failure if it's in use).
837 install_list->AddDeleteTreeWorkItem( 850 install_list->AddDeleteTreeWorkItem(
838 target_path.Append(installer::kChromeOldExe), temp_path) 851 target_path.Append(installer::kChromeOldExe), temp_path)
839 ->set_ignore_failure(true); 852 ->set_ignore_failure(true);
840 853
841 // Copy installer in install directory and 854 // Copy installer in install directory and
842 // add shortcut in Control Panel->Add/Remove Programs. 855 // add shortcut in Control Panel->Add/Remove Programs.
843 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, 856 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path,
844 new_version, install_list); 857 new_version, install_list);
845 858
859 }
860
861 void AddInstallWorkItems(const InstallationState& original_state,
862 const InstallerState& installer_state,
863 const FilePath& setup_path,
864 const FilePath& archive_path,
865 const FilePath& src_path,
866 const FilePath& temp_path,
867 const Version& new_version,
868 scoped_ptr<Version>* current_version,
869 WorkItemList* install_list) {
870 DCHECK(install_list);
871
872 const FilePath& target_path = installer_state.target_path();
873
874 // A temp directory that work items need and the actual install directory.
875 install_list->AddCreateDirWorkItem(temp_path);
876 install_list->AddCreateDirWorkItem(target_path);
877
878 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER) ||
879 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) ||
880 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) {
881 AddChromeWorkItems(original_state,
882 installer_state,
883 setup_path,
884 archive_path,
885 src_path,
886 temp_path,
887 new_version,
888 current_version,
889 install_list);
890 }
891
892 if (installer_state.FindProduct(BrowserDistribution::CHROME_APP_HOST)) {
893 install_list->AddCopyTreeWorkItem(
894 src_path.Append(installer::kChromeAppHostExe).value(),
895 target_path.Append(installer::kChromeAppHostExe).value(),
896 temp_path.value(),
897 WorkItem::ALWAYS,
898 L"");
899 }
900
846 const HKEY root = installer_state.root_key(); 901 const HKEY root = installer_state.root_key();
847 // Only set "lang" for user-level installs since for system-level, the install 902 // Only set "lang" for user-level installs since for system-level, the install
848 // language may not be related to a given user's runtime language. 903 // language may not be related to a given user's runtime language.
849 const bool add_language_identifier = !installer_state.system_install(); 904 const bool add_language_identifier = !installer_state.system_install();
850 905
851 const Products& products = installer_state.products(); 906 const Products& products = installer_state.products();
852 for (size_t i = 0; i < products.size(); ++i) { 907 for (size_t i = 0; i < products.size(); ++i) {
853 const Product* product = products[i]; 908 const Product* product = products[i];
854 909
855 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, 910 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version,
856 install_list, *product); 911 install_list, *product);
857 912
858 AddVersionKeyWorkItems(root, product->distribution(), new_version, 913 AddVersionKeyWorkItems(root, product->distribution(), new_version,
859 add_language_identifier, install_list); 914 add_language_identifier, install_list);
860 915
861 AddDelegateExecuteWorkItems(installer_state, src_path, new_version, 916 AddDelegateExecuteWorkItems(installer_state, src_path, new_version,
862 *product, install_list); 917 *product, install_list);
863 918
864 AddActiveSetupWorkItems(installer_state, new_version, *product, 919 AddActiveSetupWorkItems(installer_state, new_version, *product,
865 install_list); 920 install_list);
866 } 921 }
867 922
868 if (installer_state.is_multi_install()) {
869 AddMultiUninstallWorkItems(installer_state, setup_path, new_version,
870 install_list);
871
872 AddVersionKeyWorkItems(root,
873 installer_state.multi_package_binaries_distribution(), new_version,
874 add_language_identifier, install_list);
875 }
876
877 // Add any remaining work items that involve special settings for 923 // Add any remaining work items that involve special settings for
878 // each product. 924 // each product.
879 AddProductSpecificWorkItems(original_state, installer_state, setup_path, 925 AddProductSpecificWorkItems(original_state, installer_state, setup_path,
880 new_version, install_list); 926 new_version, install_list);
881 927
882 // Copy over brand, usagestats, and other values. 928 // Copy over brand, usagestats, and other values.
883 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); 929 AddGoogleUpdateWorkItems(original_state, installer_state, install_list);
884 930
885 AddQuickEnableWorkItems(installer_state, original_state, &setup_path, 931 AddQuickEnableApplicationHostWorkItems(installer_state, original_state,
886 &new_version, install_list); 932 &setup_path, &new_version,
933 install_list);
934
935 AddQuickEnableChromeFrameWorkItems(installer_state, original_state,
936 &setup_path, &new_version, install_list);
887 937
888 // Append the tasks that run after the installation. 938 // Append the tasks that run after the installation.
889 AppendPostInstallTasks(installer_state, 939 AppendPostInstallTasks(installer_state,
890 setup_path, 940 setup_path,
891 new_chrome_exe,
892 current_version->get(), 941 current_version->get(),
893 new_version, 942 new_version,
894 temp_path, 943 temp_path,
895 install_list); 944 install_list);
896 } 945 }
897 946
898 void AddRegisterComDllWorkItems(const FilePath& dll_folder, 947 void AddRegisterComDllWorkItems(const FilePath& dll_folder,
899 const std::vector<FilePath>& dll_list, 948 const std::vector<FilePath>& dll_list,
900 bool system_level, 949 bool system_level,
901 bool do_register, 950 bool do_register,
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 } else { 1388 } else {
1340 VLOG(1) << kIERefreshPolicy << " not supported."; 1389 VLOG(1) << kIERefreshPolicy << " not supported.";
1341 } 1390 }
1342 1391
1343 FreeLibrary(ieframe); 1392 FreeLibrary(ieframe);
1344 } else { 1393 } else {
1345 VLOG(1) << "Cannot load " << kIEFrameDll; 1394 VLOG(1) << "Cannot load " << kIEFrameDll;
1346 } 1395 }
1347 } 1396 }
1348 1397
1349 void AddQuickEnableWorkItems(const InstallerState& installer_state, 1398 void AddGenericQuickEnableWorkItems(const InstallerState& installer_state,
1350 const InstallationState& machine_state, 1399 const InstallationState& machine_state,
1351 const FilePath* setup_path, 1400 const FilePath* setup_path,
1352 const Version* new_version, 1401 const Version* new_version,
1353 WorkItemList* work_item_list) { 1402 WorkItemList* work_item_list,
1403 bool have_child_product,
1404 const CommandLine& child_product_switches,
1405 const std::wstring& command_id) {
1354 DCHECK(setup_path || 1406 DCHECK(setup_path ||
1355 installer_state.operation() == InstallerState::UNINSTALL); 1407 installer_state.operation() == InstallerState::UNINSTALL);
1356 DCHECK(new_version || 1408 DCHECK(new_version ||
1357 installer_state.operation() == InstallerState::UNINSTALL); 1409 installer_state.operation() == InstallerState::UNINSTALL);
1358 DCHECK(work_item_list); 1410 DCHECK(work_item_list);
1359 1411
1360 const bool system_install = installer_state.system_install(); 1412 const bool system_install = installer_state.system_install();
1361 bool have_multi_chrome = false; 1413 bool have_chrome_binaries = false;
1362 bool have_chrome_frame = false;
1363 1414
1364 // STEP 1: Figure out the state of the machine before the operation. 1415 // STEP 1: Figure out the state of the machine before the operation.
1365 const ProductState* product_state = NULL; 1416 const ProductState* product_state = NULL;
1366 1417
1367 // Is multi-install Chrome already on the machine? 1418 // Are the Chrome Binaries already on the machine?
1368 product_state = 1419 product_state =
1369 machine_state.GetProductState(system_install, 1420 machine_state.GetProductState(system_install,
1370 BrowserDistribution::CHROME_BROWSER); 1421 BrowserDistribution::CHROME_BINARIES);
1371 if (product_state != NULL && product_state->is_multi_install()) 1422 if (product_state != NULL && product_state->is_multi_install())
1372 have_multi_chrome = true; 1423 have_chrome_binaries = true;
1373
1374 // Is Chrome Frame !ready-mode already on the machine?
1375 product_state =
1376 machine_state.GetProductState(system_install,
1377 BrowserDistribution::CHROME_FRAME);
1378 if (product_state != NULL &&
1379 !product_state->uninstall_command().HasSwitch(
1380 switches::kChromeFrameReadyMode))
1381 have_chrome_frame = true;
1382 1424
1383 // STEP 2: Now take into account the current operation. 1425 // STEP 2: Now take into account the current operation.
1384 const Product* product = NULL; 1426 const Product* product = NULL;
1385 1427
1386 if (installer_state.operation() == InstallerState::UNINSTALL) { 1428 if (installer_state.operation() == InstallerState::UNINSTALL) {
1387 // Forget about multi-install Chrome if it is being uninstalled. 1429 // Forget about multi-install Chrome if it is being uninstalled.
1388 product = 1430 product =
1389 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); 1431 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES);
1390 if (product != NULL && installer_state.is_multi_install()) 1432 if (product != NULL && installer_state.is_multi_install())
1391 have_multi_chrome = false; 1433 have_chrome_binaries = false;
1392
1393 // Forget about Chrome Frame if it is being uninstalled. Note that we don't
1394 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame
1395 // should have been false for that case in the first place. It's odd if it
1396 // wasn't, but the right thing to do in that case is to proceed with the
1397 // thought that CF will not be installed in any sense when we reach the
1398 // finish line.
1399 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL)
1400 have_chrome_frame = false;
1401 } else { 1434 } else {
1402 // Check if we're installing multi-install Chrome. 1435 // Check if we're installing Chrome Binaries
1403 product = 1436 product =
1404 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); 1437 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES);
1405 if (product != NULL && installer_state.is_multi_install()) 1438 if (product != NULL && installer_state.is_multi_install())
1406 have_multi_chrome = true; 1439 have_chrome_binaries = true;
1407
1408 // Check if we're installing Chrome Frame !ready-mode.
1409 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME);
1410 if (product != NULL && !product->HasOption(kOptionReadyMode))
1411 have_chrome_frame = true;
1412 } 1440 }
1413 1441
1414 // STEP 3: Decide what to do based on the final state of things. 1442 // STEP 3: Decide what to do based on the final state of things.
1415 enum QuickEnableOperation { 1443 enum QuickEnableOperation {
1416 DO_NOTHING, 1444 DO_NOTHING,
1417 ADD_COMMAND, 1445 ADD_COMMAND,
1418 REMOVE_COMMAND 1446 REMOVE_COMMAND
1419 } operation = DO_NOTHING; 1447 } operation = DO_NOTHING;
1420 FilePath binaries_setup_path; 1448 FilePath binaries_setup_path;
1421 1449
1422 if (have_chrome_frame) { 1450 if (have_child_product) {
1423 // Chrome Frame !ready-mode is or will be installed. Unconditionally remove 1451 // Child product is being uninstalled. Unconditionally remove the Quick
1424 // the quick-enable-cf command from the binaries. We do this even if 1452 // Enable command from the binaries. We do this even if multi-install Chrome
1425 // multi-install Chrome isn't installed since we don't want them left 1453 // isn't installed since we don't want them left behind in any case.
1426 // behind in any case.
1427 operation = REMOVE_COMMAND; 1454 operation = REMOVE_COMMAND;
1428 } else if (have_multi_chrome) { 1455 } else if (have_chrome_binaries) {
1429 // Chrome Frame isn't (to be) installed or is (to be) installed only in 1456 // Child product isn't (to be) installed while multi-install Chrome is (to
1430 // ready-mode, while multi-install Chrome is (to be) installed. Add the 1457 // be) installed. Add the Quick Enable command to the binaries.
1431 // quick-enable-cf command to the binaries.
1432 operation = ADD_COMMAND; 1458 operation = ADD_COMMAND;
1433 // The path to setup.exe contains the version of the Chrome binaries, so it 1459 // The path to setup.exe contains the version of the Chrome binaries, so it
1434 // takes a little work to get it right. 1460 // takes a little work to get it right.
1435 if (installer_state.operation() == InstallerState::UNINSTALL) { 1461 if (installer_state.operation() == InstallerState::UNINSTALL) {
1436 // Chrome Frame is being uninstalled. Use the path to the currently 1462 // One or more products are being uninstalled, but not the binaries. Use
1437 // installed Chrome setup.exe. 1463 // the path to the currently installed Chrome setup.exe.
1438 product_state = 1464 product_state =
1439 machine_state.GetProductState(system_install, 1465 machine_state.GetProductState(system_install,
1440 BrowserDistribution::CHROME_BROWSER); 1466 BrowserDistribution::CHROME_BINARIES);
1441 DCHECK(product_state); 1467 DCHECK(product_state);
1442 binaries_setup_path = product_state->uninstall_command().GetProgram(); 1468 binaries_setup_path = product_state->uninstall_command().GetProgram();
1443 } else { 1469 } else {
1444 // Chrome is being installed, updated, or otherwise being operated on. 1470 // Chrome Binaries are being installed, updated, or otherwise operated on.
1445 // Use the path to the given |setup_path| in the normal location of 1471 // Use the path to the given |setup_path| in the normal location of
1446 // multi-install Chrome of the given |version|. 1472 // multi-install Chrome Binaries of the given |version|.
1447 DCHECK(installer_state.is_multi_install()); 1473 DCHECK(installer_state.is_multi_install());
1448 binaries_setup_path = 1474 binaries_setup_path =
1449 installer_state.GetInstallerDirectory(*new_version).Append( 1475 installer_state.GetInstallerDirectory(*new_version).Append(
1450 setup_path->BaseName()); 1476 setup_path->BaseName());
1451 } 1477 }
1452 } 1478 }
1453 1479
1454 // STEP 4: Take action. 1480 // STEP 4: Take action.
1455 if (operation != DO_NOTHING) { 1481 if (operation != DO_NOTHING) {
1456 // Get the path to the quick-enable-cf command for the binaries. 1482 // Get the path to the quick-enable-cf command for the binaries.
1457 BrowserDistribution* binaries = 1483 BrowserDistribution* binaries =
1458 BrowserDistribution::GetSpecificDistribution( 1484 BrowserDistribution::GetSpecificDistribution(
1459 BrowserDistribution::CHROME_BINARIES); 1485 BrowserDistribution::CHROME_BINARIES);
1460 std::wstring cmd_key(binaries->GetVersionKey()); 1486 std::wstring cmd_key(binaries->GetVersionKey());
1461 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) 1487 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey)
1462 .append(1, L'\\').append(kCmdQuickEnableCf); 1488 .append(1, L'\\').append(command_id);
1463 1489
1464 if (operation == ADD_COMMAND) { 1490 if (operation == ADD_COMMAND) {
1465 DCHECK(!binaries_setup_path.empty()); 1491 DCHECK(!binaries_setup_path.empty());
1466 CommandLine cmd_line(binaries_setup_path); 1492 CommandLine cmd_line(binaries_setup_path);
1467 cmd_line.AppendSwitch(switches::kMultiInstall); 1493 cmd_line.AppendArguments(child_product_switches,
1468 if (installer_state.system_install()) 1494 false); // include_program
1469 cmd_line.AppendSwitch(switches::kSystemLevel);
1470 if (installer_state.verbose_logging()) 1495 if (installer_state.verbose_logging())
1471 cmd_line.AppendSwitch(switches::kVerboseLogging); 1496 cmd_line.AppendSwitch(switches::kVerboseLogging);
1472 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable);
1473 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); 1497 AppCommand cmd(cmd_line.GetCommandLineString(), true, true);
1474 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); 1498 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list);
1475 } else { 1499 } else {
1476 DCHECK(operation == REMOVE_COMMAND); 1500 DCHECK(operation == REMOVE_COMMAND);
1477 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), 1501 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(),
1478 cmd_key)->set_log_message( 1502 cmd_key)->set_log_message(
1479 "removing quick-enable-cf command"); 1503 "removing " + WideToASCII(command_id) + " command");
1480 } 1504 }
1481 } 1505 }
1482 } 1506 }
1483 1507
1508 void AddQuickEnableChromeFrameWorkItems(const InstallerState& installer_state,
1509 const InstallationState& machine_state,
1510 const FilePath* setup_path,
1511 const Version* new_version,
1512 WorkItemList* work_item_list) {
1513 DCHECK(setup_path ||
1514 installer_state.operation() == InstallerState::UNINSTALL);
1515 DCHECK(new_version ||
1516 installer_state.operation() == InstallerState::UNINSTALL);
1517 DCHECK(work_item_list);
1518
1519 const bool system_install = installer_state.system_install();
1520 bool have_chrome_frame = false;
1521
1522 // STEP 1: Figure out the state of the machine before the operation.
1523 const ProductState* product_state = NULL;
1524
1525 // Is Chrome Frame !ready-mode already on the machine?
1526 product_state =
1527 machine_state.GetProductState(system_install,
1528 BrowserDistribution::CHROME_FRAME);
1529 if (product_state != NULL &&
1530 !product_state->uninstall_command().HasSwitch(
1531 switches::kChromeFrameReadyMode))
1532 have_chrome_frame = true;
1533
1534 // STEP 2: Now take into account the current operation.
1535 const Product* product = NULL;
1536
1537 if (installer_state.operation() == InstallerState::UNINSTALL) {
1538 // Forget about Chrome Frame if it is being uninstalled. Note that we don't
1539 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame
1540 // should have been false for that case in the first place. It's odd if it
1541 // wasn't, but the right thing to do in that case is to proceed with the
1542 // thought that CF will not be installed in any sense when we reach the
1543 // finish line.
1544 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL)
1545 have_chrome_frame = false;
1546 } else {
1547 // Check if we're installing Chrome Frame !ready-mode.
1548 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME);
1549 if (product != NULL && !product->HasOption(kOptionReadyMode))
1550 have_chrome_frame = true;
1551 }
1552
1553 CommandLine cmd_line(CommandLine::NO_PROGRAM);
1554 cmd_line.AppendSwitch(switches::kMultiInstall);
1555 if (installer_state.system_install())
1556 cmd_line.AppendSwitch(switches::kSystemLevel);
1557 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable);
1558
1559 AddGenericQuickEnableWorkItems(installer_state,
1560 machine_state,
1561 setup_path,
1562 new_version,
1563 work_item_list,
1564 have_chrome_frame,
1565 cmd_line,
1566 kCmdQuickEnableCf);
1567 }
1568
1569 void AddQuickEnableApplicationHostWorkItems(
1570 const InstallerState& installer_state,
1571 const InstallationState& machine_state,
1572 const FilePath* setup_path,
1573 const Version* new_version,
1574 WorkItemList* work_item_list) {
1575 DCHECK(setup_path ||
1576 installer_state.operation() == InstallerState::UNINSTALL);
1577 DCHECK(new_version ||
1578 installer_state.operation() == InstallerState::UNINSTALL);
1579 DCHECK(work_item_list);
1580
1581 CommandLine cmd_line(CommandLine::NO_PROGRAM);
1582 cmd_line.AppendSwitch(switches::kMultiInstall);
1583 cmd_line.AppendSwitch(switches::kChromeAppHost);
1584
1585 // For system-level binaries there is no way to keep the command state in sync
1586 // with the installation/uninstallation of the Application Host (which is
1587 // always at user-level).
1588 // So we pass false for 'have_child_product' to cause this command to always
1589 // be installed if the Chrome Binaries are installed.
1590 AddGenericQuickEnableWorkItems(installer_state,
1591 machine_state,
1592 setup_path,
1593 new_version,
1594 work_item_list,
1595 false, // have_child_product
1596 cmd_line,
1597 kCmdQuickEnableApplicationHost);
1598 }
1599
1484 } // namespace installer 1600 } // namespace installer
OLDNEW
« no previous file with comments | « chrome/installer/setup/install_worker.h ('k') | chrome/installer/setup/install_worker_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698