Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / installer / util / product.cc
blobbd0b2687b9729c1cb54a5c9feb3f4641a9433194
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/installer/util/product.h"
7 #include <algorithm>
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/process/launch.h"
12 #include "base/win/registry.h"
13 #include "chrome/installer/util/chrome_binaries_operations.h"
14 #include "chrome/installer/util/chrome_browser_operations.h"
15 #include "chrome/installer/util/chrome_browser_sxs_operations.h"
16 #include "chrome/installer/util/chrome_frame_operations.h"
17 #include "chrome/installer/util/google_update_constants.h"
18 #include "chrome/installer/util/helper.h"
19 #include "chrome/installer/util/install_util.h"
20 #include "chrome/installer/util/master_preferences.h"
21 #include "chrome/installer/util/master_preferences_constants.h"
22 #include "chrome/installer/util/product_operations.h"
24 using base::win::RegKey;
25 using installer::MasterPreferences;
27 namespace installer {
29 Product::Product(BrowserDistribution* distribution)
30 : distribution_(distribution) {
31 switch (distribution->GetType()) {
32 case BrowserDistribution::CHROME_BROWSER:
33 operations_.reset(InstallUtil::IsChromeSxSProcess() ?
34 new ChromeBrowserSxSOperations() :
35 new ChromeBrowserOperations());
36 break;
37 case BrowserDistribution::CHROME_FRAME:
38 operations_.reset(new ChromeFrameOperations());
39 break;
40 case BrowserDistribution::CHROME_BINARIES:
41 operations_.reset(new ChromeBinariesOperations());
42 break;
43 default:
44 NOTREACHED() << "Unsupported BrowserDistribution::Type: "
45 << distribution->GetType();
49 Product::~Product() {
52 void Product::InitializeFromPreferences(const MasterPreferences& prefs) {
53 operations_->ReadOptions(prefs, &options_);
56 void Product::InitializeFromUninstallCommand(
57 const base::CommandLine& uninstall_command) {
58 operations_->ReadOptions(uninstall_command, &options_);
61 bool Product::LaunchChrome(const base::FilePath& application_path) const {
62 bool success = !application_path.empty();
63 if (success) {
64 base::CommandLine cmd(application_path.Append(installer::kChromeExe));
65 success = base::LaunchProcess(cmd, base::LaunchOptions()).IsValid();
67 return success;
70 bool Product::LaunchChromeAndWait(const base::FilePath& application_path,
71 const base::CommandLine& options,
72 int32* exit_code) const {
73 if (application_path.empty())
74 return false;
76 base::CommandLine cmd(application_path.Append(installer::kChromeExe));
77 cmd.AppendArguments(options, false);
79 bool success = false;
80 STARTUPINFOW si = { sizeof(si) };
81 PROCESS_INFORMATION pi = {0};
82 // Create a writable copy of the command line string, since CreateProcess may
83 // modify the string (insert \0 to separate the program from the arguments).
84 std::wstring writable_command_line_string(cmd.GetCommandLineString());
85 if (!::CreateProcess(cmd.GetProgram().value().c_str(),
86 &writable_command_line_string[0],
87 NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL,
88 &si, &pi)) {
89 PLOG(ERROR) << "Failed to launch: " << cmd.GetCommandLineString();
90 } else {
91 ::CloseHandle(pi.hThread);
93 DWORD ret = ::WaitForSingleObject(pi.hProcess, INFINITE);
94 DLOG_IF(ERROR, ret != WAIT_OBJECT_0)
95 << "Unexpected return value from WaitForSingleObject: " << ret;
96 if (::GetExitCodeProcess(pi.hProcess, &ret)) {
97 DCHECK(ret != STILL_ACTIVE);
98 success = true;
99 if (exit_code)
100 *exit_code = ret;
101 } else {
102 PLOG(ERROR) << "GetExitCodeProcess failed";
105 ::CloseHandle(pi.hProcess);
108 return success;
111 bool Product::SetMsiMarker(bool system_install, bool set) const {
112 HKEY reg_root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
113 RegKey client_state_key;
114 LONG result = client_state_key.Open(reg_root,
115 distribution_->GetStateKey().c_str(),
116 KEY_SET_VALUE | KEY_WOW64_32KEY);
117 if (result == ERROR_SUCCESS) {
118 result = client_state_key.WriteValue(google_update::kRegMSIField,
119 set ? 1 : 0);
121 if (result != ERROR_SUCCESS && result != ERROR_FILE_NOT_FOUND) {
122 LOG(ERROR)
123 << "Failed to Open or Write MSI value to client state key. error: "
124 << result;
125 return false;
127 return true;
130 bool Product::ShouldCreateUninstallEntry() const {
131 return operations_->ShouldCreateUninstallEntry(options_);
134 void Product::AddKeyFiles(std::vector<base::FilePath>* key_files) const {
135 operations_->AddKeyFiles(options_, key_files);
138 void Product::AddComDllList(std::vector<base::FilePath>* com_dll_list) const {
139 operations_->AddComDllList(options_, com_dll_list);
142 void Product::AppendProductFlags(base::CommandLine* command_line) const {
143 operations_->AppendProductFlags(options_, command_line);
146 void Product::AppendRenameFlags(base::CommandLine* command_line) const {
147 operations_->AppendRenameFlags(options_, command_line);
150 bool Product::SetChannelFlags(bool set, ChannelInfo* channel_info) const {
151 return operations_->SetChannelFlags(options_, set, channel_info);
154 void Product::AddDefaultShortcutProperties(
155 const base::FilePath& target_exe,
156 ShellUtil::ShortcutProperties* properties) const {
157 return operations_->AddDefaultShortcutProperties(
158 distribution_, target_exe, properties);
161 void Product::LaunchUserExperiment(const base::FilePath& setup_path,
162 InstallStatus status,
163 bool system_level) const {
164 if (distribution_->HasUserExperiments()) {
165 VLOG(1) << "LaunchUserExperiment status: " << status << " product: "
166 << distribution_->GetDisplayName()
167 << " system_level: " << system_level;
168 operations_->LaunchUserExperiment(
169 setup_path, options_, status, system_level);
173 } // namespace installer