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

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

Issue 10665002: Implement installation of the Chrome App Host. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix 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/string_util.h" 21 #include "base/string_util.h"
22 #include "base/utf_string_conversions.h" 22 #include "base/utf_string_conversions.h"
23 #include "base/version.h" 23 #include "base/version.h"
24 #include "base/win/registry.h" 24 #include "base/win/registry.h"
25 #include "base/win/windows_version.h" 25 #include "base/win/windows_version.h"
26 #include "chrome/common/chrome_constants.h" 26 #include "chrome/common/chrome_constants.h"
27 #include "chrome/common/chrome_switches.h"
27 #include "chrome/installer/setup/install.h" 28 #include "chrome/installer/setup/install.h"
28 #include "chrome/installer/setup/setup_constants.h" 29 #include "chrome/installer/setup/setup_constants.h"
29 #include "chrome/installer/util/conditional_work_item_list.h" 30 #include "chrome/installer/util/conditional_work_item_list.h"
30 #include "chrome/installer/util/create_reg_key_work_item.h" 31 #include "chrome/installer/util/create_reg_key_work_item.h"
31 #include "chrome/installer/util/google_update_constants.h" 32 #include "chrome/installer/util/google_update_constants.h"
32 #include "chrome/installer/util/helper.h" 33 #include "chrome/installer/util/helper.h"
33 #include "chrome/installer/util/installation_state.h" 34 #include "chrome/installer/util/installation_state.h"
34 #include "chrome/installer/util/installer_state.h" 35 #include "chrome/installer/util/installer_state.h"
35 #include "chrome/installer/util/install_util.h" 36 #include "chrome/installer/util/install_util.h"
36 #include "chrome/installer/util/l10n_string_util.h" 37 #include "chrome/installer/util/l10n_string_util.h"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 const FilePath& temp_path, 94 const FilePath& temp_path,
94 const Version& new_version, 95 const Version& new_version,
95 WorkItemList* install_list) { 96 WorkItemList* install_list) {
96 DCHECK(install_list); 97 DCHECK(install_list);
97 FilePath installer_dir(installer_state.GetInstallerDirectory(new_version)); 98 FilePath installer_dir(installer_state.GetInstallerDirectory(new_version));
98 install_list->AddCreateDirWorkItem(installer_dir); 99 install_list->AddCreateDirWorkItem(installer_dir);
99 100
100 FilePath exe_dst(installer_dir.Append(setup_path.BaseName())); 101 FilePath exe_dst(installer_dir.Append(setup_path.BaseName()));
101 FilePath archive_dst(installer_dir.Append(archive_path.BaseName())); 102 FilePath archive_dst(installer_dir.Append(archive_path.BaseName()));
102 103
103 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(), 104 if (exe_dst != setup_path) {
104 temp_path.value(), WorkItem::ALWAYS); 105 install_list->AddCopyTreeWorkItem(setup_path.value(), exe_dst.value(),
106 temp_path.value(), WorkItem::ALWAYS);
107 }
105 108
106 // In the past, we copied rather than moved for system level installs so that 109 if (archive_path != archive_dst) {
107 // the permissions of %ProgramFiles% would be picked up. Now that |temp_path| 110 // In the past, we copied rather than moved for system level installs so
108 // is in %ProgramFiles% for system level installs (and in %LOCALAPPDATA% 111 // that the permissions of %ProgramFiles% would be picked up. Now that
109 // otherwise), there is no need to do this for the archive. Setup.exe, on 112 // |temp_path| is in %ProgramFiles% for system level installs (and in
110 // the other hand, is created elsewhere so it must always be copied. 113 // %LOCALAPPDATA% otherwise), there is no need to do this for the archive.
111 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(), 114 // Setup.exe, on the other hand, is created elsewhere so it must always be
112 temp_path.value(), WorkItem::ALWAYS_MOVE); 115 // copied.
116 install_list->AddMoveTreeWorkItem(archive_path.value(), archive_dst.value(),
117 temp_path.value(), WorkItem::ALWAYS_MOVE);
118 }
113 } 119 }
114 120
115 // This method adds work items to create (or update) Chrome uninstall entry in 121 // This method adds work items to create (or update) Chrome uninstall entry in
116 // either the Control Panel->Add/Remove Programs list or in the Omaha client 122 // either the Control Panel->Add/Remove Programs list or in the Omaha client
117 // state key if running under an MSI installer. 123 // state key if running under an MSI installer.
118 void AddUninstallShortcutWorkItems(const InstallerState& installer_state, 124 void AddUninstallShortcutWorkItems(const InstallerState& installer_state,
119 const FilePath& setup_path, 125 const FilePath& setup_path,
120 const Version& new_version, 126 const Version& new_version,
121 WorkItemList* install_list, 127 WorkItemList* install_list,
122 const Product& product) { 128 const Product& product) {
(...skipping 10 matching lines...) Expand all
133 // locate the setup.exe instance used for binary patching. 139 // locate the setup.exe instance used for binary patching.
134 // Do not quote the command line for the MSI invocation. 140 // Do not quote the command line for the MSI invocation.
135 FilePath install_path(installer_state.target_path()); 141 FilePath install_path(installer_state.target_path());
136 FilePath installer_path(installer_state.GetInstallerDirectory(new_version)); 142 FilePath installer_path(installer_state.GetInstallerDirectory(new_version));
137 installer_path = installer_path.Append(setup_path.BaseName()); 143 installer_path = installer_path.Append(setup_path.BaseName());
138 144
139 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM); 145 CommandLine uninstall_arguments(CommandLine::NO_PROGRAM);
140 AppendUninstallCommandLineFlags(installer_state, product, 146 AppendUninstallCommandLineFlags(installer_state, product,
141 &uninstall_arguments); 147 &uninstall_arguments);
142 148
143 // The Chrome uninstallation command serves as the master uninstall command 149 // If Chrome Frame is installed in Ready Mode, add --chrome-frame to Chrome's
144 // for Chrome + all other products (i.e. Chrome Frame) that do not have an 150 // uninstall entry. We skip this processing in case of uninstall since this
145 // uninstall entry in the Add/Remove Programs dialog. We skip this processing 151 // means that Chrome Frame is being uninstalled, so there's no need to do any
146 // in case of uninstall since this means that Chrome Frame is being 152 // looping.
147 // uninstalled, so there's no need to do any looping.
148 if (product.is_chrome() && 153 if (product.is_chrome() &&
149 installer_state.operation() != InstallerState::UNINSTALL) { 154 installer_state.operation() != InstallerState::UNINSTALL) {
150 const Products& products = installer_state.products(); 155 const Product* chrome_frame =
151 for (size_t i = 0; i < products.size(); ++i) { 156 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME);
152 const Product& p = *products[i]; 157 if (chrome_frame && chrome_frame->HasOption(kOptionReadyMode))
153 if (!p.is_chrome() && !p.ShouldCreateUninstallEntry()) 158 chrome_frame->AppendProductFlags(&uninstall_arguments);
154 p.AppendProductFlags(&uninstall_arguments);
155 }
156 } 159 }
157 160
158 std::wstring update_state_key(browser_dist->GetStateKey()); 161 std::wstring update_state_key(browser_dist->GetStateKey());
159 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key); 162 install_list->AddCreateRegKeyWorkItem(reg_root, update_state_key);
160 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, 163 install_list->AddSetRegValueWorkItem(reg_root, update_state_key,
161 installer::kUninstallStringField, installer_path.value(), true); 164 installer::kUninstallStringField, installer_path.value(), true);
162 install_list->AddSetRegValueWorkItem(reg_root, update_state_key, 165 install_list->AddSetRegValueWorkItem(reg_root, update_state_key,
163 installer::kUninstallArgumentsField, 166 installer::kUninstallArgumentsField,
164 uninstall_arguments.GetCommandLineString(), true); 167 uninstall_arguments.GetCommandLineString(), true);
165 168
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 if (version_components.size() == 4) { 221 if (version_components.size() == 4) {
219 // Our version should be in major.minor.build.rev. 222 // Our version should be in major.minor.build.rev.
220 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, 223 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
221 L"VersionMajor", static_cast<DWORD>(version_components[2]), true); 224 L"VersionMajor", static_cast<DWORD>(version_components[2]), true);
222 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg, 225 install_list->AddSetRegValueWorkItem(reg_root, uninstall_reg,
223 L"VersionMinor", static_cast<DWORD>(version_components[3]), true); 226 L"VersionMinor", static_cast<DWORD>(version_components[3]), true);
224 } 227 }
225 } 228 }
226 } 229 }
227 230
228 // Add uninstall-related work items for multi-install scenarios.
229 void AddMultiUninstallWorkItems(const InstallerState& installer_state,
230 const FilePath& setup_path,
231 const Version& new_version,
232 WorkItemList* install_list) {
233 DCHECK(installer_state.is_multi_install());
234
235 // The mini_installer needs a reliable way to locate setup.exe for diff
236 // updates. For single-installs, the product's ClientState key is consulted
237 // (Chrome's or Chrome Frame's). For multi-installs, the binaries' key is
238 // used.
239 const HKEY reg_root = installer_state.root_key();
240 std::wstring binaries_state_key(
241 installer_state.multi_package_binaries_distribution()->GetStateKey());
242 FilePath installer_path(
243 installer_state.GetInstallerDirectory(new_version)
244 .Append(setup_path.BaseName()));
245 install_list->AddCreateRegKeyWorkItem(reg_root, binaries_state_key);
246 install_list->AddSetRegValueWorkItem(reg_root, binaries_state_key,
247 installer::kUninstallStringField, installer_path.value(), true);
248 }
249
250 // Create Version key for a product (if not already present) and sets the new 231 // Create Version key for a product (if not already present) and sets the new
251 // product version as the last step. 232 // product version as the last step.
252 void AddVersionKeyWorkItems(HKEY root, 233 void AddVersionKeyWorkItems(HKEY root,
253 BrowserDistribution* dist, 234 BrowserDistribution* dist,
254 const Version& new_version, 235 const Version& new_version,
255 bool add_language_identifier, 236 bool add_language_identifier,
256 WorkItemList* list) { 237 WorkItemList* list) {
257 // Create Version key for each distribution (if not already present) and set 238 // Create Version key for each distribution (if not already present) and set
258 // the new product version as the last step. 239 // the new product version as the last step.
259 std::wstring version_key(dist->GetVersionKey()); 240 std::wstring version_key(dist->GetVersionKey());
(...skipping 16 matching lines...) Expand all
276 list->AddSetRegValueWorkItem(root, version_key, 257 list->AddSetRegValueWorkItem(root, version_key,
277 google_update::kRegLangField, language, 258 google_update::kRegLangField, language,
278 false); // do not overwrite language 259 false); // do not overwrite language
279 } 260 }
280 list->AddSetRegValueWorkItem(root, version_key, 261 list->AddSetRegValueWorkItem(root, version_key,
281 google_update::kRegVersionField, 262 google_update::kRegVersionField,
282 ASCIIToWide(new_version.GetString()), 263 ASCIIToWide(new_version.GetString()),
283 true); // overwrite version 264 true); // overwrite version
284 } 265 }
285 266
267 void AddInstallAppCommandWorkItems(const InstallerState& installer_state,
268 const InstallationState& machine_state,
269 const FilePath* setup_path,
270 const Version* new_version,
271 const Product& product,
272 WorkItemList* work_item_list) {
273 DCHECK(product.is_chrome_app_host());
274
275 std::wstring cmd_key(product.distribution()->GetVersionKey());
276 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey)
277 .append(1, L'\\').append(kCmdInstallApp);
278
279 if (installer_state.operation() != InstallerState::UNINSTALL) {
280 FilePath target_path(installer_state.target_path());
281 CommandLine cmd_line(target_path.Append(installer::kChromeAppHostExe));
282 cmd_line.AppendSwitchASCII(::switches::kAppsInstallFromManifestURL, "%1");
283
284 AppCommand cmd(cmd_line.GetCommandLineString(), true, true);
285 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list);
286 } else {
287 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(),
288 cmd_key)->set_log_message(
289 "removing install-application command");
290 }
291 }
292
286 void AddProductSpecificWorkItems(const InstallationState& original_state, 293 void AddProductSpecificWorkItems(const InstallationState& original_state,
287 const InstallerState& installer_state, 294 const InstallerState& installer_state,
288 const FilePath& setup_path, 295 const FilePath& setup_path,
289 const Version& new_version, 296 const Version& new_version,
290 WorkItemList* list) { 297 WorkItemList* list) {
291 const Products& products = installer_state.products(); 298 const Products& products = installer_state.products();
292 for (size_t i = 0; i < products.size(); ++i) { 299 for (size_t i = 0; i < products.size(); ++i) {
293 const Product& p = *products[i]; 300 const Product& p = *products[i];
294 if (p.is_chrome_frame()) { 301 if (p.is_chrome_frame()) {
295 AddChromeFrameWorkItems(original_state, installer_state, setup_path, 302 AddChromeFrameWorkItems(original_state, installer_state, setup_path,
296 new_version, p, list); 303 new_version, p, list);
297 } 304 }
305 if (p.is_chrome_app_host()) {
306 AddInstallAppCommandWorkItems(installer_state, original_state,
307 &setup_path, &new_version, p, list);
308 }
298 } 309 }
299 } 310 }
300 311
301 // Mirror oeminstall the first time anything is installed multi. There is no 312 // Mirror oeminstall the first time anything is installed multi. There is no
302 // need to update the value on future install/update runs since this value never 313 // need to update the value on future install/update runs since this value never
303 // changes. Note that the value is removed by Google Update after EULA 314 // changes. Note that the value is removed by Google Update after EULA
304 // acceptance is processed. 315 // acceptance is processed.
305 void AddOemInstallWorkItems(const InstallationState& original_state, 316 void AddOemInstallWorkItems(const InstallationState& original_state,
306 const InstallerState& installer_state, 317 const InstallerState& installer_state,
307 WorkItemList* install_list) { 318 WorkItemList* install_list) {
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 // do a few post install tasks: 567 // do a few post install tasks:
557 // - Handle the case of in-use-update by updating "opv" (old version) key or 568 // - Handle the case of in-use-update by updating "opv" (old version) key or
558 // deleting it if not required. 569 // deleting it if not required.
559 // - Register any new dlls and unregister old dlls. 570 // - Register any new dlls and unregister old dlls.
560 // - If this is an MSI install, ensures that the MSI marker is set, and sets 571 // - If this is an MSI install, ensures that the MSI marker is set, and sets
561 // it if not. 572 // it if not.
562 // If these operations are successful, the function returns true, otherwise 573 // If these operations are successful, the function returns true, otherwise
563 // false. 574 // false.
564 bool AppendPostInstallTasks(const InstallerState& installer_state, 575 bool AppendPostInstallTasks(const InstallerState& installer_state,
565 const FilePath& setup_path, 576 const FilePath& setup_path,
566 const FilePath& new_chrome_exe,
567 const Version* current_version, 577 const Version* current_version,
568 const Version& new_version, 578 const Version& new_version,
569 const FilePath& temp_path, 579 const FilePath& temp_path,
570 WorkItemList* post_install_task_list) { 580 WorkItemList* post_install_task_list) {
571 DCHECK(post_install_task_list); 581 DCHECK(post_install_task_list);
572 582
573 HKEY root = installer_state.root_key(); 583 HKEY root = installer_state.root_key();
574 const Products& products = installer_state.products(); 584 const Products& products = installer_state.products();
585 FilePath new_chrome_exe(
586 installer_state.target_path().Append(installer::kChromeNewExe));
575 587
576 // Append work items that will only be executed if this was an update. 588 // Append work items that will only be executed if this was an update.
577 // We update the 'opv' value with the current version that is active, 589 // We update the 'opv' value with the current version that is active,
578 // the 'cpv' value with the critical update version (if present), and the 590 // the 'cpv' value with the critical update version (if present), and the
579 // 'cmd' value with the rename command to run. 591 // 'cmd' value with the rename command to run.
580 { 592 {
581 scoped_ptr<WorkItemList> in_use_update_work_items( 593 scoped_ptr<WorkItemList> in_use_update_work_items(
582 WorkItem::CreateConditionalWorkItemList( 594 WorkItem::CreateConditionalWorkItemList(
583 new ConditionRunIfFileExists(new_chrome_exe))); 595 new ConditionRunIfFileExists(new_chrome_exe)));
584 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList"); 596 in_use_update_work_items->set_log_message("InUseUpdateWorkItemList");
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 if (installer_state.is_multi_install()) { 717 if (installer_state.is_multi_install()) {
706 AddSetMsiMarkerWorkItem(installer_state, 718 AddSetMsiMarkerWorkItem(installer_state,
707 installer_state.multi_package_binaries_distribution(), true, 719 installer_state.multi_package_binaries_distribution(), true,
708 post_install_task_list); 720 post_install_task_list);
709 } 721 }
710 } 722 }
711 723
712 return true; 724 return true;
713 } 725 }
714 726
715 void AddInstallWorkItems(const InstallationState& original_state, 727 void AddChromeWorkItems(const InstallationState& original_state,
716 const InstallerState& installer_state, 728 const InstallerState& installer_state,
717 const FilePath& setup_path, 729 const FilePath& setup_path,
718 const FilePath& archive_path, 730 const FilePath& archive_path,
719 const FilePath& src_path, 731 const FilePath& src_path,
720 const FilePath& temp_path, 732 const FilePath& temp_path,
721 const Version& new_version, 733 const Version& new_version,
722 scoped_ptr<Version>* current_version, 734 scoped_ptr<Version>* current_version,
723 WorkItemList* install_list) { 735 WorkItemList* install_list) {
724 DCHECK(install_list);
725
726 const FilePath& target_path = installer_state.target_path(); 736 const FilePath& target_path = installer_state.target_path();
727 737
728 // A temp directory that work items need and the actual install directory.
729 install_list->AddCreateDirWorkItem(temp_path);
730 install_list->AddCreateDirWorkItem(target_path);
731
732 if (current_version != NULL && current_version->get() != NULL) { 738 if (current_version != NULL && current_version->get() != NULL) {
733 // Delete the archive from an existing install to save some disk space. We 739 // Delete the archive from an existing install to save some disk space. We
734 // make this an unconditional work item since there's no need to roll this 740 // make this an unconditional work item since there's no need to roll this
735 // back; if installation fails we'll be moved to the "-full" channel anyway. 741 // back; if installation fails we'll be moved to the "-full" channel anyway.
736 FilePath old_installer_dir( 742 FilePath old_installer_dir(
737 installer_state.GetInstallerDirectory(**current_version)); 743 installer_state.GetInstallerDirectory(**current_version));
738 FilePath old_archive(old_installer_dir.Append(archive_path.BaseName())); 744 FilePath old_archive(old_installer_dir.Append(installer::kChromeArchive));
739 install_list->AddDeleteTreeWorkItem(old_archive, temp_path) 745 // Don't delete the archive that we are actually installing from.
740 ->set_ignore_failure(true); 746 if (archive_path != old_archive) {
747 install_list->AddDeleteTreeWorkItem(old_archive, temp_path)
748 ->set_ignore_failure(true);
749 }
741 } 750 }
742 751
743 // Delete any new_chrome.exe if present (we will end up creating a new one 752 // Delete any new_chrome.exe if present (we will end up creating a new one
744 // if required) and then copy chrome.exe 753 // if required) and then copy chrome.exe
745 FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe)); 754 FilePath new_chrome_exe(target_path.Append(installer::kChromeNewExe));
746 755
747 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path); 756 install_list->AddDeleteTreeWorkItem(new_chrome_exe, temp_path);
748 757
749 if (installer_state.IsChromeFrameRunning(original_state)) { 758 if (installer_state.IsChromeFrameRunning(original_state)) {
750 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe"; 759 VLOG(1) << "Chrome Frame in use. Copying to new_chrome.exe";
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
833 // Delete any old_chrome.exe if present (ignore failure if it's in use). 842 // Delete any old_chrome.exe if present (ignore failure if it's in use).
834 install_list->AddDeleteTreeWorkItem( 843 install_list->AddDeleteTreeWorkItem(
835 target_path.Append(installer::kChromeOldExe), temp_path) 844 target_path.Append(installer::kChromeOldExe), temp_path)
836 ->set_ignore_failure(true); 845 ->set_ignore_failure(true);
837 846
838 // Copy installer in install directory and 847 // Copy installer in install directory and
839 // add shortcut in Control Panel->Add/Remove Programs. 848 // add shortcut in Control Panel->Add/Remove Programs.
840 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path, 849 AddInstallerCopyTasks(installer_state, setup_path, archive_path, temp_path,
841 new_version, install_list); 850 new_version, install_list);
842 851
852 }
853
854 void AddInstallWorkItems(const InstallationState& original_state,
855 const InstallerState& installer_state,
856 const FilePath& setup_path,
857 const FilePath& archive_path,
858 const FilePath& src_path,
859 const FilePath& temp_path,
860 const Version& new_version,
861 scoped_ptr<Version>* current_version,
862 WorkItemList* install_list) {
863 DCHECK(install_list);
864
865 const FilePath& target_path = installer_state.target_path();
866
867 // A temp directory that work items need and the actual install directory.
868 install_list->AddCreateDirWorkItem(temp_path);
869 install_list->AddCreateDirWorkItem(target_path);
870
871 if (installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER) ||
872 installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) ||
873 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES)) {
874 AddChromeWorkItems(original_state,
875 installer_state,
876 setup_path,
877 archive_path,
878 src_path,
879 temp_path,
880 new_version,
881 current_version,
882 install_list);
883 }
884
885 if (installer_state.FindProduct(BrowserDistribution::CHROME_APP_HOST)) {
886 install_list->AddCopyTreeWorkItem(
887 src_path.Append(installer::kChromeAppHostExe).value(),
888 target_path.Append(installer::kChromeAppHostExe).value(),
889 temp_path.value(),
890 WorkItem::ALWAYS,
891 L"");
892 }
893
843 const HKEY root = installer_state.root_key(); 894 const HKEY root = installer_state.root_key();
844 // Only set "lang" for user-level installs since for system-level, the install 895 // Only set "lang" for user-level installs since for system-level, the install
845 // language may not be related to a given user's runtime language. 896 // language may not be related to a given user's runtime language.
846 const bool add_language_identifier = !installer_state.system_install(); 897 const bool add_language_identifier = !installer_state.system_install();
847 898
848 const Products& products = installer_state.products(); 899 const Products& products = installer_state.products();
849 for (size_t i = 0; i < products.size(); ++i) { 900 for (size_t i = 0; i < products.size(); ++i) {
850 const Product* product = products[i]; 901 const Product* product = products[i];
851 902
852 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version, 903 AddUninstallShortcutWorkItems(installer_state, setup_path, new_version,
853 install_list, *product); 904 install_list, *product);
854 905
855 AddVersionKeyWorkItems(root, product->distribution(), new_version, 906 AddVersionKeyWorkItems(root, product->distribution(), new_version,
856 add_language_identifier, install_list); 907 add_language_identifier, install_list);
857 908
858 AddDelegateExecuteWorkItems(installer_state, src_path, new_version, 909 AddDelegateExecuteWorkItems(installer_state, src_path, new_version,
859 *product, install_list); 910 *product, install_list);
860 } 911 }
861 912
862 if (installer_state.is_multi_install()) {
863 AddMultiUninstallWorkItems(installer_state, setup_path, new_version,
864 install_list);
865
866 AddVersionKeyWorkItems(root,
867 installer_state.multi_package_binaries_distribution(), new_version,
868 add_language_identifier, install_list);
869 }
870
871 // Add any remaining work items that involve special settings for 913 // Add any remaining work items that involve special settings for
872 // each product. 914 // each product.
873 AddProductSpecificWorkItems(original_state, installer_state, setup_path, 915 AddProductSpecificWorkItems(original_state, installer_state, setup_path,
874 new_version, install_list); 916 new_version, install_list);
875 917
876 // Copy over brand, usagestats, and other values. 918 // Copy over brand, usagestats, and other values.
877 AddGoogleUpdateWorkItems(original_state, installer_state, install_list); 919 AddGoogleUpdateWorkItems(original_state, installer_state, install_list);
878 920
879 AddQuickEnableWorkItems(installer_state, original_state, &setup_path, 921 AddQuickEnableApplicationHostWorkItems(installer_state, original_state,
880 &new_version, install_list); 922 &setup_path, &new_version,
923 install_list);
924
925 AddQuickEnableChromeFrameWorkItems(installer_state, original_state,
926 &setup_path, &new_version, install_list);
881 927
882 // Append the tasks that run after the installation. 928 // Append the tasks that run after the installation.
883 AppendPostInstallTasks(installer_state, 929 AppendPostInstallTasks(installer_state,
884 setup_path, 930 setup_path,
885 new_chrome_exe,
886 current_version->get(), 931 current_version->get(),
887 new_version, 932 new_version,
888 temp_path, 933 temp_path,
889 install_list); 934 install_list);
890 } 935 }
891 936
892 void AddRegisterComDllWorkItems(const FilePath& dll_folder, 937 void AddRegisterComDllWorkItems(const FilePath& dll_folder,
893 const std::vector<FilePath>& dll_list, 938 const std::vector<FilePath>& dll_list,
894 bool system_level, 939 bool system_level,
895 bool do_register, 940 bool do_register,
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1289 } else { 1334 } else {
1290 VLOG(1) << kIERefreshPolicy << " not supported."; 1335 VLOG(1) << kIERefreshPolicy << " not supported.";
1291 } 1336 }
1292 1337
1293 FreeLibrary(ieframe); 1338 FreeLibrary(ieframe);
1294 } else { 1339 } else {
1295 VLOG(1) << "Cannot load " << kIEFrameDll; 1340 VLOG(1) << "Cannot load " << kIEFrameDll;
1296 } 1341 }
1297 } 1342 }
1298 1343
1299 void AddQuickEnableWorkItems(const InstallerState& installer_state, 1344 void AddGenericQuickEnableWorkItems(const InstallerState& installer_state,
1300 const InstallationState& machine_state, 1345 const InstallationState& machine_state,
1301 const FilePath* setup_path, 1346 const FilePath* setup_path,
1302 const Version* new_version, 1347 const Version* new_version,
1303 WorkItemList* work_item_list) { 1348 WorkItemList* work_item_list,
1349 bool have_child_product,
1350 const CommandLine& child_product_switches,
1351 const std::wstring& command_id) {
1304 DCHECK(setup_path || 1352 DCHECK(setup_path ||
1305 installer_state.operation() == InstallerState::UNINSTALL); 1353 installer_state.operation() == InstallerState::UNINSTALL);
1306 DCHECK(new_version || 1354 DCHECK(new_version ||
1307 installer_state.operation() == InstallerState::UNINSTALL); 1355 installer_state.operation() == InstallerState::UNINSTALL);
1308 DCHECK(work_item_list); 1356 DCHECK(work_item_list);
1309 1357
1310 const bool system_install = installer_state.system_install(); 1358 const bool system_install = installer_state.system_install();
1311 bool have_multi_chrome = false; 1359 bool have_chrome_binaries = false;
1312 bool have_chrome_frame = false;
1313 1360
1314 // STEP 1: Figure out the state of the machine before the operation. 1361 // STEP 1: Figure out the state of the machine before the operation.
1315 const ProductState* product_state = NULL; 1362 const ProductState* product_state = NULL;
1316 1363
1317 // Is multi-install Chrome already on the machine? 1364 // Are the Chrome Binaries already on the machine?
1318 product_state = 1365 product_state =
1319 machine_state.GetProductState(system_install, 1366 machine_state.GetProductState(system_install,
1320 BrowserDistribution::CHROME_BROWSER); 1367 BrowserDistribution::CHROME_BINARIES);
1321 if (product_state != NULL && product_state->is_multi_install()) 1368 if (product_state != NULL && product_state->is_multi_install())
1322 have_multi_chrome = true; 1369 have_chrome_binaries = true;
1323
1324 // Is Chrome Frame !ready-mode already on the machine?
1325 product_state =
1326 machine_state.GetProductState(system_install,
1327 BrowserDistribution::CHROME_FRAME);
1328 if (product_state != NULL &&
1329 !product_state->uninstall_command().HasSwitch(
1330 switches::kChromeFrameReadyMode))
1331 have_chrome_frame = true;
1332 1370
1333 // STEP 2: Now take into account the current operation. 1371 // STEP 2: Now take into account the current operation.
1334 const Product* product = NULL; 1372 const Product* product = NULL;
1335 1373
1336 if (installer_state.operation() == InstallerState::UNINSTALL) { 1374 if (installer_state.operation() == InstallerState::UNINSTALL) {
1337 // Forget about multi-install Chrome if it is being uninstalled. 1375 // Forget about multi-install Chrome if it is being uninstalled.
1338 product = 1376 product =
1339 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); 1377 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES);
1340 if (product != NULL && installer_state.is_multi_install()) 1378 if (product != NULL && installer_state.is_multi_install())
1341 have_multi_chrome = false; 1379 have_chrome_binaries = false;
1342
1343 // Forget about Chrome Frame if it is being uninstalled. Note that we don't
1344 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame
1345 // should have been false for that case in the first place. It's odd if it
1346 // wasn't, but the right thing to do in that case is to proceed with the
1347 // thought that CF will not be installed in any sense when we reach the
1348 // finish line.
1349 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL)
1350 have_chrome_frame = false;
1351 } else { 1380 } else {
1352 // Check if we're installing multi-install Chrome. 1381 // Check if we're installing Chrome Binaries
1353 product = 1382 product =
1354 installer_state.FindProduct(BrowserDistribution::CHROME_BROWSER); 1383 installer_state.FindProduct(BrowserDistribution::CHROME_BINARIES);
1355 if (product != NULL && installer_state.is_multi_install()) 1384 if (product != NULL && installer_state.is_multi_install())
1356 have_multi_chrome = true; 1385 have_chrome_binaries = true;
1357
1358 // Check if we're installing Chrome Frame !ready-mode.
1359 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME);
1360 if (product != NULL && !product->HasOption(kOptionReadyMode))
1361 have_chrome_frame = true;
1362 } 1386 }
1363 1387
1364 // STEP 3: Decide what to do based on the final state of things. 1388 // STEP 3: Decide what to do based on the final state of things.
1365 enum QuickEnableOperation { 1389 enum QuickEnableOperation {
1366 DO_NOTHING, 1390 DO_NOTHING,
1367 ADD_COMMAND, 1391 ADD_COMMAND,
1368 REMOVE_COMMAND 1392 REMOVE_COMMAND
1369 } operation = DO_NOTHING; 1393 } operation = DO_NOTHING;
1370 FilePath binaries_setup_path; 1394 FilePath binaries_setup_path;
1371 1395
1372 if (have_chrome_frame) { 1396 if (have_child_product) {
1373 // Chrome Frame !ready-mode is or will be installed. Unconditionally remove 1397 // Child product is being uninstalled. Unconditionally remove the Quick
1374 // the quick-enable-cf command from the binaries. We do this even if 1398 // Enable command from the binaries. We do this even if multi-install Chrome
1375 // multi-install Chrome isn't installed since we don't want them left 1399 // isn't installed since we don't want them left behind in any case.
1376 // behind in any case.
1377 operation = REMOVE_COMMAND; 1400 operation = REMOVE_COMMAND;
1378 } else if (have_multi_chrome) { 1401 } else if (have_chrome_binaries) {
1379 // Chrome Frame isn't (to be) installed or is (to be) installed only in 1402 // Child product isn't (to be) installed while multi-install Chrome is (to
1380 // ready-mode, while multi-install Chrome is (to be) installed. Add the 1403 // be) installed. Add the Quick Enable command to the binaries.
1381 // quick-enable-cf command to the binaries.
1382 operation = ADD_COMMAND; 1404 operation = ADD_COMMAND;
1383 // The path to setup.exe contains the version of the Chrome binaries, so it 1405 // The path to setup.exe contains the version of the Chrome binaries, so it
1384 // takes a little work to get it right. 1406 // takes a little work to get it right.
1385 if (installer_state.operation() == InstallerState::UNINSTALL) { 1407 if (installer_state.operation() == InstallerState::UNINSTALL) {
1386 // Chrome Frame is being uninstalled. Use the path to the currently 1408 // One or more products are being uninstalled, but not the binaries. Use
1387 // installed Chrome setup.exe. 1409 // the path to the currently installed Chrome setup.exe.
1388 product_state = 1410 product_state =
1389 machine_state.GetProductState(system_install, 1411 machine_state.GetProductState(system_install,
1390 BrowserDistribution::CHROME_BROWSER); 1412 BrowserDistribution::CHROME_BINARIES);
1391 DCHECK(product_state); 1413 DCHECK(product_state);
1392 binaries_setup_path = product_state->uninstall_command().GetProgram(); 1414 binaries_setup_path = product_state->uninstall_command().GetProgram();
1393 } else { 1415 } else {
1394 // Chrome is being installed, updated, or otherwise being operated on. 1416 // Chrome Binaries are being installed, updated, or otherwise operated on.
1395 // Use the path to the given |setup_path| in the normal location of 1417 // Use the path to the given |setup_path| in the normal location of
1396 // multi-install Chrome of the given |version|. 1418 // multi-install Chrome Binaries of the given |version|.
1397 DCHECK(installer_state.is_multi_install()); 1419 DCHECK(installer_state.is_multi_install());
1398 binaries_setup_path = 1420 binaries_setup_path =
1399 installer_state.GetInstallerDirectory(*new_version).Append( 1421 installer_state.GetInstallerDirectory(*new_version).Append(
1400 setup_path->BaseName()); 1422 setup_path->BaseName());
1401 } 1423 }
1402 } 1424 }
1403 1425
1404 // STEP 4: Take action. 1426 // STEP 4: Take action.
1405 if (operation != DO_NOTHING) { 1427 if (operation != DO_NOTHING) {
1406 // Get the path to the quick-enable-cf command for the binaries. 1428 // Get the path to the quick-enable-cf command for the binaries.
1407 BrowserDistribution* binaries = 1429 BrowserDistribution* binaries =
1408 BrowserDistribution::GetSpecificDistribution( 1430 BrowserDistribution::GetSpecificDistribution(
1409 BrowserDistribution::CHROME_BINARIES); 1431 BrowserDistribution::CHROME_BINARIES);
1410 std::wstring cmd_key(binaries->GetVersionKey()); 1432 std::wstring cmd_key(binaries->GetVersionKey());
1411 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey) 1433 cmd_key.append(1, L'\\').append(google_update::kRegCommandsKey)
1412 .append(1, L'\\').append(kCmdQuickEnableCf); 1434 .append(1, L'\\').append(command_id);
1413 1435
1414 if (operation == ADD_COMMAND) { 1436 if (operation == ADD_COMMAND) {
1415 DCHECK(!binaries_setup_path.empty()); 1437 DCHECK(!binaries_setup_path.empty());
1416 CommandLine cmd_line(binaries_setup_path); 1438 CommandLine cmd_line(binaries_setup_path);
1417 cmd_line.AppendSwitch(switches::kMultiInstall); 1439 cmd_line.AppendArguments(child_product_switches,
1418 if (installer_state.system_install()) 1440 false); // include_program
1419 cmd_line.AppendSwitch(switches::kSystemLevel);
1420 if (installer_state.verbose_logging()) 1441 if (installer_state.verbose_logging())
1421 cmd_line.AppendSwitch(switches::kVerboseLogging); 1442 cmd_line.AppendSwitch(switches::kVerboseLogging);
1422 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable);
1423 AppCommand cmd(cmd_line.GetCommandLineString(), true, true); 1443 AppCommand cmd(cmd_line.GetCommandLineString(), true, true);
1424 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list); 1444 cmd.AddWorkItems(installer_state.root_key(), cmd_key, work_item_list);
1425 } else { 1445 } else {
1426 DCHECK(operation == REMOVE_COMMAND); 1446 DCHECK(operation == REMOVE_COMMAND);
1427 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(), 1447 work_item_list->AddDeleteRegKeyWorkItem(installer_state.root_key(),
1428 cmd_key)->set_log_message( 1448 cmd_key)->set_log_message(
1429 "removing quick-enable-cf command"); 1449 "removing " + WideToASCII(command_id) + " command");
1430 } 1450 }
1431 } 1451 }
1432 } 1452 }
1433 1453
1454 void AddQuickEnableChromeFrameWorkItems(const InstallerState& installer_state,
1455 const InstallationState& machine_state,
1456 const FilePath* setup_path,
1457 const Version* new_version,
1458 WorkItemList* work_item_list) {
1459 DCHECK(setup_path ||
1460 installer_state.operation() == InstallerState::UNINSTALL);
1461 DCHECK(new_version ||
1462 installer_state.operation() == InstallerState::UNINSTALL);
1463 DCHECK(work_item_list);
1464
1465 const bool system_install = installer_state.system_install();
1466 bool have_chrome_frame = false;
1467
1468 // STEP 1: Figure out the state of the machine before the operation.
1469 const ProductState* product_state = NULL;
1470
1471 // Is Chrome Frame !ready-mode already on the machine?
1472 product_state =
1473 machine_state.GetProductState(system_install,
1474 BrowserDistribution::CHROME_FRAME);
1475 if (product_state != NULL &&
1476 !product_state->uninstall_command().HasSwitch(
1477 switches::kChromeFrameReadyMode))
1478 have_chrome_frame = true;
1479
1480 // STEP 2: Now take into account the current operation.
1481 const Product* product = NULL;
1482
1483 if (installer_state.operation() == InstallerState::UNINSTALL) {
1484 // Forget about Chrome Frame if it is being uninstalled. Note that we don't
1485 // bother to check !HasOption(kOptionReadyMode) since have_chrome_frame
1486 // should have been false for that case in the first place. It's odd if it
1487 // wasn't, but the right thing to do in that case is to proceed with the
1488 // thought that CF will not be installed in any sense when we reach the
1489 // finish line.
1490 if (installer_state.FindProduct(BrowserDistribution::CHROME_FRAME) != NULL)
1491 have_chrome_frame = false;
1492 } else {
1493 // Check if we're installing Chrome Frame !ready-mode.
1494 product = installer_state.FindProduct(BrowserDistribution::CHROME_FRAME);
1495 if (product != NULL && !product->HasOption(kOptionReadyMode))
1496 have_chrome_frame = true;
1497 }
1498
1499 CommandLine cmd_line(CommandLine::NO_PROGRAM);
1500 cmd_line.AppendSwitch(switches::kMultiInstall);
1501 if (installer_state.system_install())
1502 cmd_line.AppendSwitch(switches::kSystemLevel);
1503 cmd_line.AppendSwitch(switches::kChromeFrameQuickEnable);
1504
1505 AddGenericQuickEnableWorkItems(installer_state,
1506 machine_state,
1507 setup_path,
1508 new_version,
1509 work_item_list,
1510 have_chrome_frame,
1511 cmd_line,
1512 kCmdQuickEnableCf);
1513 }
1514
1515 void AddQuickEnableApplicationHostWorkItems(
1516 const InstallerState& installer_state,
1517 const InstallationState& machine_state,
1518 const FilePath* setup_path,
1519 const Version* new_version,
1520 WorkItemList* work_item_list) {
1521 DCHECK(setup_path ||
1522 installer_state.operation() == InstallerState::UNINSTALL);
1523 DCHECK(new_version ||
1524 installer_state.operation() == InstallerState::UNINSTALL);
1525 DCHECK(work_item_list);
1526
1527 CommandLine cmd_line(CommandLine::NO_PROGRAM);
1528 cmd_line.AppendSwitch(switches::kMultiInstall);
1529 cmd_line.AppendSwitch(switches::kChromeAppHost);
1530
1531 // For system-level binaries there is no way to keep the command state in sync
1532 // with the installation/uninstallation of the Application Host (which is
1533 // always at user-level).
1534 // So we pass false for 'have_child_product' to cause this command to always
1535 // be installed if the Chrome Binaries are installed.
1536 AddGenericQuickEnableWorkItems(installer_state,
1537 machine_state,
1538 setup_path,
1539 new_version,
1540 work_item_list,
1541 false, // have_child_product
1542 cmd_line,
1543 kCmdQuickEnableApplicationHost);
1544 }
1545
1434 } // namespace installer 1546 } // namespace installer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698