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

Side by Side Diff: chrome/browser/component_updater/sw_reporter_installer_win.cc

Issue 2278013002: Add support for the ExperimentalSwReporterEngine field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address csharp's review comments. Change handling of empty "suffix" and "arguments" manifest keys. Created 4 years, 3 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
OLDNEW
1 // Copyright (c) 2014 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2014 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/browser/component_updater/sw_reporter_installer_win.h" 5 #include "chrome/browser/component_updater/sw_reporter_installer_win.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm>
9 #include <map> 10 #include <map>
10 #include <memory> 11 #include <memory>
11 #include <string> 12 #include <string>
12 #include <utility> 13 #include <utility>
13 #include <vector> 14 #include <vector>
14 15
15 #include "base/base_paths.h" 16 #include "base/base_paths.h"
16 #include "base/bind.h" 17 #include "base/bind.h"
18 #include "base/command_line.h"
19 #include "base/feature_list.h"
17 #include "base/files/file_path.h" 20 #include "base/files/file_path.h"
18 #include "base/files/file_util.h" 21 #include "base/files/file_util.h"
19 #include "base/logging.h" 22 #include "base/logging.h"
20 #include "base/metrics/histogram.h" 23 #include "base/metrics/histogram.h"
21 #include "base/metrics/sparse_histogram.h" 24 #include "base/metrics/sparse_histogram.h"
22 #include "base/path_service.h" 25 #include "base/path_service.h"
23 #include "base/strings/string_tokenizer.h" 26 #include "base/strings/string_tokenizer.h"
27 #include "base/strings/string_util.h"
24 #include "base/threading/thread_task_runner_handle.h" 28 #include "base/threading/thread_task_runner_handle.h"
25 #include "base/threading/worker_pool.h" 29 #include "base/threading/worker_pool.h"
26 #include "base/time/time.h" 30 #include "base/time/time.h"
27 #include "base/win/registry.h" 31 #include "base/win/registry.h"
32 #include "base/win/windows_version.h"
28 #include "chrome/browser/browser_process.h" 33 #include "chrome/browser/browser_process.h"
29 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" 34 #include "chrome/browser/safe_browsing/srt_fetcher_win.h"
30 #include "chrome/browser/safe_browsing/srt_field_trial_win.h" 35 #include "chrome/browser/safe_browsing/srt_field_trial_win.h"
31 #include "components/component_updater/component_updater_paths.h" 36 #include "components/component_updater/component_updater_paths.h"
32 #include "components/component_updater/component_updater_service.h" 37 #include "components/component_updater/component_updater_service.h"
33 #include "components/component_updater/pref_names.h" 38 #include "components/component_updater/pref_names.h"
34 #include "components/pref_registry/pref_registry_syncable.h" 39 #include "components/pref_registry/pref_registry_syncable.h"
35 #include "components/prefs/pref_registry_simple.h" 40 #include "components/prefs/pref_registry_simple.h"
36 #include "components/update_client/update_client.h" 41 #include "components/update_client/update_client.h"
37 #include "components/update_client/utils.h" 42 #include "components/update_client/utils.h"
43 #include "components/variations/variations_associated_data.h"
38 #include "content/public/browser/browser_thread.h" 44 #include "content/public/browser/browser_thread.h"
39 45
40 namespace component_updater { 46 namespace component_updater {
41 47
42 namespace { 48 namespace {
43 49
44 // These two sets of values are used to send UMA information and are replicated 50 // These values are used to send UMA information and are replicated in the
45 // in the histograms.xml file, so the order MUST NOT CHANGE. 51 // histograms.xml file, so the order MUST NOT CHANGE.
46 enum SRTCompleted { 52 enum SRTCompleted {
47 SRT_COMPLETED_NOT_YET = 0, 53 SRT_COMPLETED_NOT_YET = 0,
48 SRT_COMPLETED_YES = 1, 54 SRT_COMPLETED_YES = 1,
49 SRT_COMPLETED_LATER = 2, 55 SRT_COMPLETED_LATER = 2,
50 SRT_COMPLETED_MAX, 56 SRT_COMPLETED_MAX,
51 }; 57 };
52 58
53 // CRX hash. The extension id is: gkmgaooipdjhmangpemjhigmamcehddo. The hash was 59 // CRX hash. The extension id is: gkmgaooipdjhmangpemjhigmamcehddo. The hash was
54 // generated in Python with something like this: 60 // generated in Python with something like this:
55 // hashlib.sha256().update(open("<file>.crx").read()[16:16+294]).digest(). 61 // hashlib.sha256().update(open("<file>.crx").read()[16:16+294]).digest().
56 const uint8_t kSha256Hash[] = {0x6a, 0xc6, 0x0e, 0xe8, 0xf3, 0x97, 0xc0, 0xd6, 62 const uint8_t kSha256Hash[] = {0x6a, 0xc6, 0x0e, 0xe8, 0xf3, 0x97, 0xc0, 0xd6,
57 0xf4, 0xc9, 0x78, 0x6c, 0x0c, 0x24, 0x73, 0x3e, 63 0xf4, 0xc9, 0x78, 0x6c, 0x0c, 0x24, 0x73, 0x3e,
58 0x05, 0xa5, 0x62, 0x4b, 0x2e, 0xc7, 0xb7, 0x1c, 64 0x05, 0xa5, 0x62, 0x4b, 0x2e, 0xc7, 0xb7, 0x1c,
59 0x5f, 0xea, 0xf0, 0x88, 0xf6, 0x97, 0x9b, 0xc7}; 65 0x5f, 0xea, 0xf0, 0x88, 0xf6, 0x97, 0x9b, 0xc7};
60 66
61 const base::FilePath::CharType kSwReporterExeName[] = 67 const base::FilePath::CharType kSwReporterExeName[] =
62 FILE_PATH_LITERAL("software_reporter_tool.exe"); 68 FILE_PATH_LITERAL("software_reporter_tool.exe");
63 69
64 // SRT registry keys and value names. 70 // SRT registry keys and value names.
65 const wchar_t kCleanerSuffixRegistryKey[] = L"Cleaner"; 71 const wchar_t kCleanerSuffixRegistryKey[] = L"Cleaner";
66 const wchar_t kExitCodeValueName[] = L"ExitCode"; 72 const wchar_t kExitCodeValueName[] = L"ExitCode";
67 const wchar_t kUploadResultsValueName[] = L"UploadResults"; 73 const wchar_t kUploadResultsValueName[] = L"UploadResults";
68 const wchar_t kVersionValueName[] = L"Version"; 74 const wchar_t kVersionValueName[] = L"Version";
69 75
76 constexpr base::Feature kExperimentalEngineFeature{
77 "ExperimentalSwReporterEngine", base::FEATURE_DISABLED_BY_DEFAULT};
78
70 void SRTHasCompleted(SRTCompleted value) { 79 void SRTHasCompleted(SRTCompleted value) {
71 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.Cleaner.HasCompleted", value, 80 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.Cleaner.HasCompleted", value,
72 SRT_COMPLETED_MAX); 81 SRT_COMPLETED_MAX);
73 } 82 }
74 83
75 void ReportUploadsWithUma(const base::string16& upload_results) { 84 void ReportUploadsWithUma(const base::string16& upload_results) {
76 base::WStringTokenizer tokenizer(upload_results, L";"); 85 base::WStringTokenizer tokenizer(upload_results, L";");
77 int failure_count = 0; 86 int failure_count = 0;
78 int success_count = 0; 87 int success_count = 0;
79 int longest_failure_run = 0; 88 int longest_failure_run = 0;
(...skipping 16 matching lines...) Expand all
96 105
97 UMA_HISTOGRAM_COUNTS_100("SoftwareReporter.UploadFailureCount", 106 UMA_HISTOGRAM_COUNTS_100("SoftwareReporter.UploadFailureCount",
98 failure_count); 107 failure_count);
99 UMA_HISTOGRAM_COUNTS_100("SoftwareReporter.UploadSuccessCount", 108 UMA_HISTOGRAM_COUNTS_100("SoftwareReporter.UploadSuccessCount",
100 success_count); 109 success_count);
101 UMA_HISTOGRAM_COUNTS_100("SoftwareReporter.UploadLongestFailureRun", 110 UMA_HISTOGRAM_COUNTS_100("SoftwareReporter.UploadLongestFailureRun",
102 longest_failure_run); 111 longest_failure_run);
103 UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.LastUploadResult", last_result); 112 UMA_HISTOGRAM_BOOLEAN("SoftwareReporter.LastUploadResult", last_result);
104 } 113 }
105 114
115 void ReportExperimentError(SwReporterExperimentError error) {
116 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.ExperimentErrors", error,
117 SW_REPORTER_EXPERIMENT_ERROR_MAX);
118 }
119
106 // Run the software reporter on the next Chrome startup after it's downloaded. 120 // Run the software reporter on the next Chrome startup after it's downloaded.
107 // (This is the default |reporter_runner| function passed to the 121 // (This is the default |reporter_runner| function passed to the
108 // |SwReporterInstallerTraits| constructor in |RegisterSwReporterComponent| 122 // |SwReporterInstallerTraits| constructor in |RegisterSwReporterComponent|
109 // below.) 123 // below.)
110 void RunSwReporterAfterStartup( 124 void RunSwReporterAfterStartup(
111 const safe_browsing::SwReporterInvocation& invocation, 125 const safe_browsing::SwReporterInvocation& invocation,
112 const base::Version& version) { 126 const base::Version& version) {
113 content::BrowserThread::PostAfterStartupTask( 127 content::BrowserThread::PostAfterStartupTask(
114 FROM_HERE, base::ThreadTaskRunnerHandle::Get(), 128 FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
115 base::Bind(&safe_browsing::RunSwReporter, invocation, version, 129 base::Bind(&safe_browsing::RunSwReporter, invocation, version,
116 base::ThreadTaskRunnerHandle::Get(), 130 base::ThreadTaskRunnerHandle::Get(),
117 base::WorkerPool::GetTaskRunner(true))); 131 base::WorkerPool::GetTaskRunner(true)));
118 } 132 }
119 133
134 // Ensures |str| contains only alphanumeric characters and characters from
135 // |extras|, and is not longer than |max_length|.
136 bool ValidateString(const std::string& str,
137 const std::string& extras,
138 size_t max_length) {
139 return str.size() <= max_length &&
140 std::all_of(str.cbegin(), str.cend(), [&extras](char c) {
141 return base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) ||
142 extras.find(c) != std::string::npos;
143 });
144 }
145
146 // Reads the command-line params and an UMA histogram suffix from the manifest,
147 // and launch the SwReporter with those parameters. If anything goes wrong the
148 // SwReporter should not be run at all, instead of falling back to the default.
149 void RunExperimentalSwReporter(const base::FilePath& exe_path,
150 const base::Version& version,
151 std::unique_ptr<base::DictionaryValue> manifest,
152 const SwReporterRunner& reporter_runner) {
153 // On the first startup after a user is enrolled in the field trial, they may
csharp 2016/08/25 22:28:14 They comment section is pretty big now, what about
Joe Mason 2016/08/25 23:17:00 Done.
154 // already have the non-experimental software reporter component installed.
155 // In that case, the component updater will first call |ComponentReady| with
156 // the manifest from the existing component, then download the new component,
157 // then call |ComponentReady| again with the new manifest.
158 //
159 // Only the experimental version of the reporter will have a launch_params
160 // section in the manifest. So if the section is entirely missing, just
161 // return. We don't want to log an error because this is a normal part of
162 // startup, but we also don't want to run the existing version - this user
163 // should wait for the experimental version to be ready.
164 base::Value* launch_params = nullptr;
165 if (!manifest->Get("launch_params", &launch_params))
166 return;
167
168 const base::ListValue* parameter_list = nullptr;
169 if (!launch_params->GetAsList(&parameter_list) || parameter_list->empty() ||
170 // For future expansion, the manifest takes a list of invocation
171 // parameters, but currently we only support a single invocation.
172 parameter_list->GetSize() > 1) {
173 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
174 return;
175 }
176
177 const base::DictionaryValue* invocation_params = nullptr;
178 if (!parameter_list->GetDictionary(0, &invocation_params)) {
179 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
180 return;
181 }
182
183 // Max length of the registry and histogram suffix. Fairly arbitrary: the
184 // Windows registry accepts much longer keys, but we need to display this
185 // string in histograms as well.
186 constexpr size_t kMaxSuffixLength = 80;
187
188 // The suffix must be an alphanumeric string. (Empty is fine as long as the
189 // "suffix" key is present.)
190 std::string suffix;
191 const base::Value* suffix_value = nullptr;
192 if (!invocation_params->Get("suffix", &suffix_value) ||
193 !suffix_value->GetAsString(&suffix) ||
194 (!suffix.empty() &&
csharp 2016/08/25 22:28:14 Is this needed? ValidateString is true for an empt
Joe Mason 2016/08/25 23:17:00 It's easy to miss that ValidateString implies acce
195 !ValidateString(suffix, std::string(), kMaxSuffixLength))) {
196 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
197 return;
198 }
199
200 // Build a command line for the reporter out of the executable path and the
201 // arguments from the manifest. (The "arguments" key must be present, but
202 // it's ok if it's an empty list or a list of empty strings.)
203 std::vector<base::string16> argv = {exe_path.value()};
204 const base::Value* arguments_value = nullptr;
205 const base::ListValue* arguments = nullptr;
206 if (!invocation_params->Get("arguments", &arguments_value) ||
207 !arguments_value->GetAsList(&arguments)) {
208 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
209 return;
210 }
211
212 for (const auto& value : *arguments) {
213 base::string16 argument;
214 if (!value->GetAsString(&argument)) {
215 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
216 return;
217 }
218 if (!argument.empty())
219 argv.push_back(argument);
220 }
221
222 base::CommandLine command_line(argv);
223
224 // Add the histogram suffix to the command-line as well, so that the
225 // reporter will add the same suffix to registry keys where it writes
226 // metrics.
227 if (!suffix.empty())
228 command_line.AppendSwitchASCII("registry-suffix", suffix);
229
230 auto invocation =
231 safe_browsing::SwReporterInvocation::FromCommandLine(command_line);
232 invocation.suffix = suffix;
233 invocation.is_experimental = true;
234
235 reporter_runner.Run(invocation, version);
236 }
237
120 } // namespace 238 } // namespace
121 239
122 SwReporterInstallerTraits::SwReporterInstallerTraits( 240 SwReporterInstallerTraits::SwReporterInstallerTraits(
123 const SwReporterRunner& reporter_runner) 241 const SwReporterRunner& reporter_runner,
124 : reporter_runner_(reporter_runner) {} 242 bool is_experimental_engine_supported)
243 : reporter_runner_(reporter_runner),
244 is_experimental_engine_supported_(is_experimental_engine_supported) {}
125 245
126 SwReporterInstallerTraits::~SwReporterInstallerTraits() {} 246 SwReporterInstallerTraits::~SwReporterInstallerTraits() {}
127 247
128 bool SwReporterInstallerTraits::VerifyInstallation( 248 bool SwReporterInstallerTraits::VerifyInstallation(
129 const base::DictionaryValue& manifest, 249 const base::DictionaryValue& manifest,
130 const base::FilePath& dir) const { 250 const base::FilePath& dir) const {
131 return base::PathExists(dir.Append(kSwReporterExeName)); 251 return base::PathExists(dir.Append(kSwReporterExeName));
132 } 252 }
133 253
134 bool SwReporterInstallerTraits::SupportsGroupPolicyEnabledComponentUpdates() 254 bool SwReporterInstallerTraits::SupportsGroupPolicyEnabledComponentUpdates()
(...skipping 10 matching lines...) Expand all
145 const base::FilePath& install_dir) { 265 const base::FilePath& install_dir) {
146 return true; 266 return true;
147 } 267 }
148 268
149 void SwReporterInstallerTraits::ComponentReady( 269 void SwReporterInstallerTraits::ComponentReady(
150 const base::Version& version, 270 const base::Version& version,
151 const base::FilePath& install_dir, 271 const base::FilePath& install_dir,
152 std::unique_ptr<base::DictionaryValue> manifest) { 272 std::unique_ptr<base::DictionaryValue> manifest) {
153 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 273 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
154 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName)); 274 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName));
155 reporter_runner_.Run( 275 if (IsExperimentalEngineEnabled()) {
156 safe_browsing::SwReporterInvocation::FromFilePath(exe_path), version); 276 RunExperimentalSwReporter(exe_path, version, std::move(manifest),
277 reporter_runner_);
278 } else {
279 reporter_runner_.Run(
280 safe_browsing::SwReporterInvocation::FromFilePath(exe_path), version);
281 }
157 } 282 }
158 283
159 base::FilePath SwReporterInstallerTraits::GetRelativeInstallDir() const { 284 base::FilePath SwReporterInstallerTraits::GetRelativeInstallDir() const {
160 return base::FilePath(FILE_PATH_LITERAL("SwReporter")); 285 return base::FilePath(FILE_PATH_LITERAL("SwReporter"));
161 } 286 }
162 287
163 void SwReporterInstallerTraits::GetHash(std::vector<uint8_t>* hash) const { 288 void SwReporterInstallerTraits::GetHash(std::vector<uint8_t>* hash) const {
164 DCHECK(hash); 289 DCHECK(hash);
165 hash->assign(kSha256Hash, kSha256Hash + sizeof(kSha256Hash)); 290 hash->assign(kSha256Hash, kSha256Hash + sizeof(kSha256Hash));
166 } 291 }
167 292
168 std::string SwReporterInstallerTraits::GetName() const { 293 std::string SwReporterInstallerTraits::GetName() const {
169 return "Software Reporter Tool"; 294 return "Software Reporter Tool";
170 } 295 }
171 296
172 update_client::InstallerAttributes 297 update_client::InstallerAttributes
173 SwReporterInstallerTraits::GetInstallerAttributes() const { 298 SwReporterInstallerTraits::GetInstallerAttributes() const {
174 return update_client::InstallerAttributes(); 299 update_client::InstallerAttributes attributes;
300 if (IsExperimentalEngineEnabled()) {
301 // Pass the "tag" parameter to the installer; it will be used to choose
302 // which binary is downloaded.
303 constexpr char kTagParam[] = "tag";
304 const std::string tag = variations::GetVariationParamValueByFeature(
305 kExperimentalEngineFeature, kTagParam);
306
307 // If the tag is not a valid attribute (see the regexp in
308 // ComponentInstallerTraits::InstallerAttributes), set it to a valid but
309 // unrecognized value so that nothing will be downloaded.
310 constexpr size_t kMaxAttributeLength = 256;
311 constexpr char kExtraAttributeChars[] = "-.,;+_=";
312 if (tag.empty() ||
313 !ValidateString(tag, kExtraAttributeChars, kMaxAttributeLength)) {
314 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_TAG);
315 attributes[kTagParam] = "missing_tag";
316 } else {
317 attributes[kTagParam] = tag;
318 }
319 }
320 return attributes;
175 } 321 }
176 322
177 std::vector<std::string> SwReporterInstallerTraits::GetMimeTypes() const { 323 std::vector<std::string> SwReporterInstallerTraits::GetMimeTypes() const {
178 return std::vector<std::string>(); 324 return std::vector<std::string>();
179 } 325 }
180 326
327 bool SwReporterInstallerTraits::IsExperimentalEngineEnabled() const {
328 return is_experimental_engine_supported_ &&
329 base::FeatureList::IsEnabled(kExperimentalEngineFeature);
330 }
331
181 void RegisterSwReporterComponent(ComponentUpdateService* cus) { 332 void RegisterSwReporterComponent(ComponentUpdateService* cus) {
182 if (!safe_browsing::IsSwReporterEnabled()) 333 if (!safe_browsing::IsSwReporterEnabled())
183 return; 334 return;
184 335
185 // Check if we have information from Cleaner and record UMA statistics. 336 // Check if we have information from Cleaner and record UMA statistics.
186 base::string16 cleaner_key_name( 337 base::string16 cleaner_key_name(
187 safe_browsing::kSoftwareRemovalToolRegistryKey); 338 safe_browsing::kSoftwareRemovalToolRegistryKey);
188 cleaner_key_name.append(1, L'\\').append(kCleanerSuffixRegistryKey); 339 cleaner_key_name.append(1, L'\\').append(kCleanerSuffixRegistryKey);
189 base::win::RegKey cleaner_key( 340 base::win::RegKey cleaner_key(
190 HKEY_CURRENT_USER, cleaner_key_name.c_str(), KEY_ALL_ACCESS); 341 HKEY_CURRENT_USER, cleaner_key_name.c_str(), KEY_ALL_ACCESS);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 ReportUploadsWithUma(upload_results); 398 ReportUploadsWithUma(upload_results);
248 } 399 }
249 } else { 400 } else {
250 if (cleaner_key.HasValue(safe_browsing::kEndTimeValueName)) { 401 if (cleaner_key.HasValue(safe_browsing::kEndTimeValueName)) {
251 SRTHasCompleted(SRT_COMPLETED_LATER); 402 SRTHasCompleted(SRT_COMPLETED_LATER);
252 cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName); 403 cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName);
253 } 404 }
254 } 405 }
255 } 406 }
256 407
408 // The experiment is only enabled on x86. There's no way to check this in the
409 // variations config so we'll hard-code it.
410 const bool is_experimental_engine_supported =
411 base::win::OSInfo::GetInstance()->architecture() ==
412 base::win::OSInfo::X86_ARCHITECTURE;
413
257 // Install the component. 414 // Install the component.
258 std::unique_ptr<ComponentInstallerTraits> traits( 415 std::unique_ptr<ComponentInstallerTraits> traits(
259 new SwReporterInstallerTraits(base::Bind(&RunSwReporterAfterStartup))); 416 new SwReporterInstallerTraits(base::Bind(&RunSwReporterAfterStartup),
417 is_experimental_engine_supported));
260 // |cus| will take ownership of |installer| during installer->Register(cus). 418 // |cus| will take ownership of |installer| during installer->Register(cus).
261 DefaultComponentInstaller* installer = 419 DefaultComponentInstaller* installer =
262 new DefaultComponentInstaller(std::move(traits)); 420 new DefaultComponentInstaller(std::move(traits));
263 installer->Register(cus, base::Closure()); 421 installer->Register(cus, base::Closure());
264 } 422 }
265 423
266 void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) { 424 void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) {
267 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeTriggered, 0); 425 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeTriggered, 0);
268 registry->RegisterIntegerPref(prefs::kSwReporterLastExitCode, -1); 426 registry->RegisterIntegerPref(prefs::kSwReporterLastExitCode, -1);
269 registry->RegisterBooleanPref(prefs::kSwReporterPendingPrompt, false); 427 registry->RegisterBooleanPref(prefs::kSwReporterPendingPrompt, false);
270 } 428 }
271 429
272 void RegisterProfilePrefsForSwReporter( 430 void RegisterProfilePrefsForSwReporter(
273 user_prefs::PrefRegistrySyncable* registry) { 431 user_prefs::PrefRegistrySyncable* registry) {
274 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, ""); 432 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, "");
275 433
276 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, ""); 434 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, "");
277 } 435 }
278 436
279 } // namespace component_updater 437 } // namespace component_updater
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698