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

Side by Side Diff: chrome/installer/util/product.cc

Issue 6288009: More installer refactoring in the interest of fixing some bugs and cleaning t... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 11 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
« no previous file with comments | « chrome/installer/util/product.h ('k') | chrome/installer/util/product_operations.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/installer/util/product.h" 5 #include "chrome/installer/util/product.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/process_util.h" 11 #include "base/process_util.h"
12 #include "base/win/registry.h" 12 #include "base/win/registry.h"
13 #include "chrome/installer/util/chrome_browser_operations.h"
14 #include "chrome/installer/util/chrome_browser_sxs_operations.h"
15 #include "chrome/installer/util/chrome_frame_operations.h"
13 #include "chrome/installer/util/google_update_constants.h" 16 #include "chrome/installer/util/google_update_constants.h"
14 #include "chrome/installer/util/helper.h" 17 #include "chrome/installer/util/helper.h"
15 #include "chrome/installer/util/install_util.h" 18 #include "chrome/installer/util/install_util.h"
16 #include "chrome/installer/util/master_preferences.h" 19 #include "chrome/installer/util/master_preferences.h"
17 #include "chrome/installer/util/master_preferences_constants.h" 20 #include "chrome/installer/util/master_preferences_constants.h"
18 #include "chrome/installer/util/package_properties.h" 21 #include "chrome/installer/util/product_operations.h"
19 22
20 using base::win::RegKey; 23 using base::win::RegKey;
21 using installer::MasterPreferences; 24 using installer::MasterPreferences;
22 25
23 namespace {
24 class ProductIsOfType {
25 public:
26 explicit ProductIsOfType(BrowserDistribution::Type type)
27 : type_(type) { }
28 bool operator()(
29 const scoped_refptr<const installer::Product>& pi) const {
30 return pi->distribution()->GetType() == type_;
31 }
32 private:
33 BrowserDistribution::Type type_;
34 }; // class ProductIsOfType
35 } // end namespace
36
37 namespace installer { 26 namespace installer {
38 27
39 const Product* FindProduct(const Products& products, 28 Product::Product(BrowserDistribution* distribution)
40 BrowserDistribution::Type type) { 29 : distribution_(distribution) {
41 Products::const_iterator i = 30 switch (distribution->GetType()) {
42 std::find_if(products.begin(), products.end(), ProductIsOfType(type)); 31 case BrowserDistribution::CHROME_BROWSER:
43 return i == products.end() ? NULL : *i; 32 operations_.reset(InstallUtil::IsChromeSxSProcess() ?
33 new ChromeBrowserSxSOperations() :
34 new ChromeBrowserOperations());
35 break;
36 case BrowserDistribution::CHROME_FRAME:
37 operations_.reset(new ChromeFrameOperations());
38 break;
39 default:
40 NOTREACHED() << "Unsupported BrowserDistribution::Type: "
41 << distribution->GetType();
42 }
44 } 43 }
45 44
46 //////////////////////////////////////////////////////////////////////////////// 45 Product::~Product() {
47
48 Product::Product(BrowserDistribution* distribution, Package* package)
49 : distribution_(distribution),
50 package_(package),
51 msi_(false),
52 cache_state_(0) {
53 package_->AssociateProduct(this);
54 } 46 }
55 47
56 const Package& Product::package() const { 48 void Product::InitializeFromPreferences(const MasterPreferences& prefs) {
57 return *package_.get(); 49 operations_->ReadOptions(prefs, &options_);
50 }
51
52 void Product::InitializeFromUninstallCommand(
53 const CommandLine& uninstall_command) {
54 operations_->ReadOptions(uninstall_command, &options_);
58 } 55 }
59 56
60 FilePath Product::GetUserDataPath() const { 57 FilePath Product::GetUserDataPath() const {
61 return GetChromeUserDataPath(distribution_); 58 return GetChromeUserDataPath(distribution_);
62 } 59 }
63 60
64 bool Product::LaunchChrome() const { 61 bool Product::LaunchChrome(const FilePath& application_path) const {
65 const FilePath& install_package = package_->path(); 62 bool success = !application_path.empty();
66 bool success = !install_package.empty();
67 if (success) { 63 if (success) {
68 CommandLine cmd(install_package.Append(installer::kChromeExe)); 64 CommandLine cmd(application_path.Append(installer::kChromeExe));
69 success = base::LaunchApp(cmd, false, false, NULL); 65 success = base::LaunchApp(cmd, false, false, NULL);
70 } 66 }
71 return success; 67 return success;
72 } 68 }
73 69
74 bool Product::LaunchChromeAndWait(const CommandLine& options, 70 bool Product::LaunchChromeAndWait(const FilePath& application_path,
71 const CommandLine& options,
75 int32* exit_code) const { 72 int32* exit_code) const {
76 const FilePath& install_package = package_->path(); 73 if (application_path.empty())
77 if (install_package.empty())
78 return false; 74 return false;
79 75
80 CommandLine cmd(install_package.Append(installer::kChromeExe)); 76 CommandLine cmd(application_path.Append(installer::kChromeExe));
81 cmd.AppendArguments(options, false); 77 cmd.AppendArguments(options, false);
82 78
83 bool success = false; 79 bool success = false;
84 STARTUPINFOW si = { sizeof(si) }; 80 STARTUPINFOW si = { sizeof(si) };
85 PROCESS_INFORMATION pi = {0}; 81 PROCESS_INFORMATION pi = {0};
86 // Cast away constness of the command_line_string() since CreateProcess 82 // Cast away constness of the command_line_string() since CreateProcess
87 // might modify the string (insert \0 to separate the program from the 83 // might modify the string (insert \0 to separate the program from the
88 // arguments). Since we're not using the cmd variable beyond this point 84 // arguments). Since we're not using the cmd variable beyond this point
89 // we don't care. 85 // we don't care.
90 if (!::CreateProcess(cmd.GetProgram().value().c_str(), 86 if (!::CreateProcess(cmd.GetProgram().value().c_str(),
(...skipping 15 matching lines...) Expand all
106 } else { 102 } else {
107 PLOG(ERROR) << "GetExitCodeProcess failed"; 103 PLOG(ERROR) << "GetExitCodeProcess failed";
108 } 104 }
109 105
110 ::CloseHandle(pi.hProcess); 106 ::CloseHandle(pi.hProcess);
111 } 107 }
112 108
113 return success; 109 return success;
114 } 110 }
115 111
116 bool Product::IsMsi() const { 112 bool Product::SetMsiMarker(bool system_install, bool set) const {
117 if ((cache_state_ & MSI_STATE) == 0) { 113 HKEY reg_root = system_install ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
118 msi_ = false; // Covers failure cases below.
119
120 const MasterPreferences& prefs = MasterPreferences::ForCurrentProcess();
121
122 bool is_msi = false;
123 prefs.GetBool(installer::master_preferences::kMsi, &is_msi);
124
125 if (!is_msi) {
126 // We didn't find it in the preferences, try looking in the registry.
127 HKEY reg_root = system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
128 RegKey key;
129 if (key.Open(reg_root, distribution_->GetStateKey().c_str(),
130 KEY_READ) == ERROR_SUCCESS) {
131 DWORD msi_value = 0;
132 key.ReadValueDW(google_update::kRegMSIField, &msi_value);
133 msi_ = msi_value != 0;
134 }
135 } else {
136 msi_ = true;
137 }
138 cache_state_ |= MSI_STATE;
139 }
140
141 return msi_;
142 }
143
144 bool Product::SetMsiMarker(bool set) const {
145 HKEY reg_root = system_level() ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER;
146 RegKey client_state_key; 114 RegKey client_state_key;
147 LONG result = client_state_key.Open(reg_root, 115 LONG result = client_state_key.Open(reg_root,
148 distribution_->GetStateKey().c_str(), KEY_READ | KEY_WRITE); 116 distribution_->GetStateKey().c_str(), KEY_READ | KEY_WRITE);
149 if (result == ERROR_SUCCESS) { 117 if (result == ERROR_SUCCESS) {
150 result = client_state_key.WriteValue(google_update::kRegMSIField, 118 result = client_state_key.WriteValue(google_update::kRegMSIField,
151 set ? 1 : 0); 119 set ? 1 : 0);
152 } 120 }
153 121
154 LOG_IF(ERROR, result != ERROR_SUCCESS) << "Failed to Open or Write MSI value" 122 LOG_IF(ERROR, result != ERROR_SUCCESS) << "Failed to Open or Write MSI value"
155 "to client state key. error: " << result; 123 "to client state key. error: " << result;
156 124
157 return (result == ERROR_SUCCESS); 125 return (result == ERROR_SUCCESS);
158 } 126 }
159 127
160 bool Product::ShouldCreateUninstallEntry() const { 128 bool Product::ShouldCreateUninstallEntry() const {
161 if (IsMsi()) { 129 return operations_->ShouldCreateUninstallEntry(options_);
162 // MSI installations will manage their own uninstall shortcuts.
163 return false;
164 }
165
166 return distribution_->ShouldCreateUninstallEntry();
167 } 130 }
168 131
169 /////////////////////////////////////////////////////////////////////////////// 132 void Product::AddKeyFiles(std::vector<FilePath>* key_files) const {
170 ProductPackageMapping::ProductPackageMapping(bool multi_install, 133 operations_->AddKeyFiles(options_, key_files);
171 bool system_level)
172 : package_properties_(new ActivePackageProperties()),
173 multi_install_(multi_install),
174 system_level_(system_level) {
175 } 134 }
176 135
177 const Packages& ProductPackageMapping::packages() const { 136 void Product::AddComDllList(std::vector<FilePath>* com_dll_list) const {
178 return packages_; 137 operations_->AddComDllList(options_, com_dll_list);
179 } 138 }
180 139
181 const Products& ProductPackageMapping::products() const { 140 void Product::AppendProductFlags(CommandLine* command_line) const {
182 return products_; 141 operations_->AppendProductFlags(options_, command_line);
183 } 142 }
184 143
185 bool ProductPackageMapping::AddDistribution(BrowserDistribution* distribution) { 144 bool Product::SetChannelFlags(bool set, ChannelInfo* channel_info) const {
186 DCHECK(distribution); 145 return operations_->SetChannelFlags(options_, set, channel_info);
187 // Each product type can be added exactly once.
188 DCHECK(FindProduct(products_, distribution->GetType()) == NULL);
189
190 FilePath install_package;
191 if (distribution->GetType() == BrowserDistribution::CHROME_BROWSER) {
192 install_package = GetChromeInstallPath(system_level_, distribution);
193 } else {
194 DCHECK_EQ(BrowserDistribution::CHROME_FRAME, distribution->GetType());
195 install_package = GetChromeFrameInstallPath(multi_install_, system_level_,
196 distribution);
197 }
198
199 if (install_package.empty()) {
200 LOG(ERROR) << "Got an empty installation path for "
201 << distribution->GetApplicationName()
202 << ". It's likely that there's a conflicting "
203 "installation present";
204 return false;
205 }
206
207 scoped_refptr<Package> target_package;
208 for (size_t i = 0; i < packages_.size(); ++i) {
209 if (packages_[i]->IsEqual(install_package)) {
210 // Use an existing Package.
211 target_package = packages_[i];
212 break;
213 }
214 }
215
216 if (!target_package.get()) {
217 DCHECK(packages_.empty()) << "Multiple packages per run unsupported.";
218 // create new one and add.
219 target_package = new Package(multi_install_, system_level_, install_package,
220 package_properties_.get());
221 packages_.push_back(target_package);
222 }
223
224 scoped_refptr<Product> product(new Product(distribution, target_package));
225 #ifndef NDEBUG
226 for (size_t i = 0; i < products_.size(); ++i) {
227 DCHECK_EQ(product->IsMsi(), products_[i]->IsMsi());
228 }
229 #endif
230 products_.push_back(product);
231
232 return true;
233 }
234
235 bool ProductPackageMapping::AddDistribution(
236 BrowserDistribution::Type type,
237 const MasterPreferences& prefs) {
238 BrowserDistribution* distribution =
239 BrowserDistribution::GetSpecificDistribution(type, prefs);
240 if (!distribution) {
241 NOTREACHED();
242 return false;
243 }
244
245 return AddDistribution(distribution);
246 } 146 }
247 147
248 } // namespace installer 148 } // namespace installer
249
OLDNEW
« no previous file with comments | « chrome/installer/util/product.h ('k') | chrome/installer/util/product_operations.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698