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

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: Simplify comment 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,
grt (UTC plus 2) 2016/08/26 10:31:56 nit: "Lifts the bottle and drinks the beer." shoul
147 // and launch the SwReporter with those parameters. If anything goes wrong the
grt (UTC plus 2) 2016/08/26 10:31:56 nit: launches
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 // The experiment requires launch_params so if they aren't present just
154 // return. This isn't an error because the user could get into the experiment
155 // group before they've downloaded the experiment component.
156 base::Value* launch_params = nullptr;
157 if (!manifest->Get("launch_params", &launch_params))
158 return;
159
160 const base::ListValue* parameter_list = nullptr;
161 if (!launch_params->GetAsList(&parameter_list) || parameter_list->empty() ||
grt (UTC plus 2) 2016/08/26 10:31:56 replace the last two conditions with "parameter_li
162 // For future expansion, the manifest takes a list of invocation
grt (UTC plus 2) 2016/08/26 10:31:56 nit: i find a multi-line comment in the middle of
163 // parameters, but currently we only support a single invocation.
164 parameter_list->GetSize() > 1) {
165 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
166 return;
167 }
168
169 const base::DictionaryValue* invocation_params = nullptr;
170 if (!parameter_list->GetDictionary(0, &invocation_params)) {
171 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
172 return;
173 }
174
175 // Max length of the registry and histogram suffix. Fairly arbitrary: the
176 // Windows registry accepts much longer keys, but we need to display this
177 // string in histograms as well.
178 constexpr size_t kMaxSuffixLength = 80;
179
180 // The suffix must be an alphanumeric string. (Empty is fine as long as the
grt (UTC plus 2) 2016/08/26 10:31:56 nit: either make the parenthetical remark a part o
181 // "suffix" key is present.)
182 std::string suffix;
183 const base::Value* suffix_value = nullptr;
184 if (!invocation_params->Get("suffix", &suffix_value) ||
185 !suffix_value->GetAsString(&suffix) ||
grt (UTC plus 2) 2016/08/26 10:31:56 nix |suffix_value| and replace these two lines wit
186 (!suffix.empty() &&
grt (UTC plus 2) 2016/08/26 10:31:56 i agree that this check should be removed. it does
187 !ValidateString(suffix, std::string(), kMaxSuffixLength))) {
188 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
189 return;
190 }
191
192 // Build a command line for the reporter out of the executable path and the
193 // arguments from the manifest. (The "arguments" key must be present, but
194 // it's ok if it's an empty list or a list of empty strings.)
195 std::vector<base::string16> argv = {exe_path.value()};
196 const base::Value* arguments_value = nullptr;
197 const base::ListValue* arguments = nullptr;
198 if (!invocation_params->Get("arguments", &arguments_value) ||
grt (UTC plus 2) 2016/08/26 10:31:56 nix |arguments_value| and replace with: !invocat
199 !arguments_value->GetAsList(&arguments)) {
200 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
201 return;
202 }
203
204 for (const auto& value : *arguments) {
205 base::string16 argument;
206 if (!value->GetAsString(&argument)) {
207 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
208 return;
209 }
210 if (!argument.empty())
211 argv.push_back(argument);
212 }
213
214 base::CommandLine command_line(argv);
215
216 // Add the histogram suffix to the command-line as well, so that the
217 // reporter will add the same suffix to registry keys where it writes
218 // metrics.
219 if (!suffix.empty())
220 command_line.AppendSwitchASCII("registry-suffix", suffix);
221
222 auto invocation =
223 safe_browsing::SwReporterInvocation::FromCommandLine(command_line);
224 invocation.suffix = suffix;
225 invocation.is_experimental = true;
226
227 reporter_runner.Run(invocation, version);
228 }
229
120 } // namespace 230 } // namespace
121 231
122 SwReporterInstallerTraits::SwReporterInstallerTraits( 232 SwReporterInstallerTraits::SwReporterInstallerTraits(
123 const SwReporterRunner& reporter_runner) 233 const SwReporterRunner& reporter_runner,
124 : reporter_runner_(reporter_runner) {} 234 bool is_experimental_engine_supported)
235 : reporter_runner_(reporter_runner),
236 is_experimental_engine_supported_(is_experimental_engine_supported) {}
125 237
126 SwReporterInstallerTraits::~SwReporterInstallerTraits() {} 238 SwReporterInstallerTraits::~SwReporterInstallerTraits() {}
127 239
128 bool SwReporterInstallerTraits::VerifyInstallation( 240 bool SwReporterInstallerTraits::VerifyInstallation(
129 const base::DictionaryValue& manifest, 241 const base::DictionaryValue& manifest,
130 const base::FilePath& dir) const { 242 const base::FilePath& dir) const {
131 return base::PathExists(dir.Append(kSwReporterExeName)); 243 return base::PathExists(dir.Append(kSwReporterExeName));
132 } 244 }
133 245
134 bool SwReporterInstallerTraits::SupportsGroupPolicyEnabledComponentUpdates() 246 bool SwReporterInstallerTraits::SupportsGroupPolicyEnabledComponentUpdates()
(...skipping 10 matching lines...) Expand all
145 const base::FilePath& install_dir) { 257 const base::FilePath& install_dir) {
146 return true; 258 return true;
147 } 259 }
148 260
149 void SwReporterInstallerTraits::ComponentReady( 261 void SwReporterInstallerTraits::ComponentReady(
150 const base::Version& version, 262 const base::Version& version,
151 const base::FilePath& install_dir, 263 const base::FilePath& install_dir,
152 std::unique_ptr<base::DictionaryValue> manifest) { 264 std::unique_ptr<base::DictionaryValue> manifest) {
153 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 265 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
154 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName)); 266 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName));
155 reporter_runner_.Run( 267 if (IsExperimentalEngineEnabled()) {
156 safe_browsing::SwReporterInvocation::FromFilePath(exe_path), version); 268 RunExperimentalSwReporter(exe_path, version, std::move(manifest),
269 reporter_runner_);
270 } else {
271 reporter_runner_.Run(
272 safe_browsing::SwReporterInvocation::FromFilePath(exe_path), version);
273 }
157 } 274 }
158 275
159 base::FilePath SwReporterInstallerTraits::GetRelativeInstallDir() const { 276 base::FilePath SwReporterInstallerTraits::GetRelativeInstallDir() const {
160 return base::FilePath(FILE_PATH_LITERAL("SwReporter")); 277 return base::FilePath(FILE_PATH_LITERAL("SwReporter"));
161 } 278 }
162 279
163 void SwReporterInstallerTraits::GetHash(std::vector<uint8_t>* hash) const { 280 void SwReporterInstallerTraits::GetHash(std::vector<uint8_t>* hash) const {
164 DCHECK(hash); 281 DCHECK(hash);
165 hash->assign(kSha256Hash, kSha256Hash + sizeof(kSha256Hash)); 282 hash->assign(kSha256Hash, kSha256Hash + sizeof(kSha256Hash));
166 } 283 }
167 284
168 std::string SwReporterInstallerTraits::GetName() const { 285 std::string SwReporterInstallerTraits::GetName() const {
169 return "Software Reporter Tool"; 286 return "Software Reporter Tool";
170 } 287 }
171 288
172 update_client::InstallerAttributes 289 update_client::InstallerAttributes
173 SwReporterInstallerTraits::GetInstallerAttributes() const { 290 SwReporterInstallerTraits::GetInstallerAttributes() const {
174 return update_client::InstallerAttributes(); 291 update_client::InstallerAttributes attributes;
292 if (IsExperimentalEngineEnabled()) {
293 // Pass the "tag" parameter to the installer; it will be used to choose
294 // which binary is downloaded.
295 constexpr char kTagParam[] = "tag";
296 const std::string tag = variations::GetVariationParamValueByFeature(
297 kExperimentalEngineFeature, kTagParam);
298
299 // If the tag is not a valid attribute (see the regexp in
300 // ComponentInstallerTraits::InstallerAttributes), set it to a valid but
301 // unrecognized value so that nothing will be downloaded.
302 constexpr size_t kMaxAttributeLength = 256;
303 constexpr char kExtraAttributeChars[] = "-.,;+_=";
304 if (tag.empty() ||
305 !ValidateString(tag, kExtraAttributeChars, kMaxAttributeLength)) {
306 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_TAG);
307 attributes[kTagParam] = "missing_tag";
308 } else {
309 attributes[kTagParam] = tag;
310 }
311 }
312 return attributes;
175 } 313 }
176 314
177 std::vector<std::string> SwReporterInstallerTraits::GetMimeTypes() const { 315 std::vector<std::string> SwReporterInstallerTraits::GetMimeTypes() const {
178 return std::vector<std::string>(); 316 return std::vector<std::string>();
179 } 317 }
180 318
319 bool SwReporterInstallerTraits::IsExperimentalEngineEnabled() const {
320 return is_experimental_engine_supported_ &&
321 base::FeatureList::IsEnabled(kExperimentalEngineFeature);
322 }
323
181 void RegisterSwReporterComponent(ComponentUpdateService* cus) { 324 void RegisterSwReporterComponent(ComponentUpdateService* cus) {
182 if (!safe_browsing::IsSwReporterEnabled()) 325 if (!safe_browsing::IsSwReporterEnabled())
183 return; 326 return;
184 327
185 // Check if we have information from Cleaner and record UMA statistics. 328 // Check if we have information from Cleaner and record UMA statistics.
186 base::string16 cleaner_key_name( 329 base::string16 cleaner_key_name(
187 safe_browsing::kSoftwareRemovalToolRegistryKey); 330 safe_browsing::kSoftwareRemovalToolRegistryKey);
188 cleaner_key_name.append(1, L'\\').append(kCleanerSuffixRegistryKey); 331 cleaner_key_name.append(1, L'\\').append(kCleanerSuffixRegistryKey);
189 base::win::RegKey cleaner_key( 332 base::win::RegKey cleaner_key(
190 HKEY_CURRENT_USER, cleaner_key_name.c_str(), KEY_ALL_ACCESS); 333 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); 390 ReportUploadsWithUma(upload_results);
248 } 391 }
249 } else { 392 } else {
250 if (cleaner_key.HasValue(safe_browsing::kEndTimeValueName)) { 393 if (cleaner_key.HasValue(safe_browsing::kEndTimeValueName)) {
251 SRTHasCompleted(SRT_COMPLETED_LATER); 394 SRTHasCompleted(SRT_COMPLETED_LATER);
252 cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName); 395 cleaner_key.DeleteValue(safe_browsing::kEndTimeValueName);
253 } 396 }
254 } 397 }
255 } 398 }
256 399
400 // The experiment is only enabled on x86. There's no way to check this in the
401 // variations config so we'll hard-code it.
402 const bool is_experimental_engine_supported =
403 base::win::OSInfo::GetInstance()->architecture() ==
404 base::win::OSInfo::X86_ARCHITECTURE;
405
257 // Install the component. 406 // Install the component.
258 std::unique_ptr<ComponentInstallerTraits> traits( 407 std::unique_ptr<ComponentInstallerTraits> traits(
259 new SwReporterInstallerTraits(base::Bind(&RunSwReporterAfterStartup))); 408 new SwReporterInstallerTraits(base::Bind(&RunSwReporterAfterStartup),
409 is_experimental_engine_supported));
260 // |cus| will take ownership of |installer| during installer->Register(cus). 410 // |cus| will take ownership of |installer| during installer->Register(cus).
261 DefaultComponentInstaller* installer = 411 DefaultComponentInstaller* installer =
262 new DefaultComponentInstaller(std::move(traits)); 412 new DefaultComponentInstaller(std::move(traits));
263 installer->Register(cus, base::Closure()); 413 installer->Register(cus, base::Closure());
264 } 414 }
265 415
266 void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) { 416 void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) {
267 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeTriggered, 0); 417 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeTriggered, 0);
268 registry->RegisterIntegerPref(prefs::kSwReporterLastExitCode, -1); 418 registry->RegisterIntegerPref(prefs::kSwReporterLastExitCode, -1);
269 registry->RegisterBooleanPref(prefs::kSwReporterPendingPrompt, false); 419 registry->RegisterBooleanPref(prefs::kSwReporterPendingPrompt, false);
270 } 420 }
271 421
272 void RegisterProfilePrefsForSwReporter( 422 void RegisterProfilePrefsForSwReporter(
273 user_prefs::PrefRegistrySyncable* registry) { 423 user_prefs::PrefRegistrySyncable* registry) {
274 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, ""); 424 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, "");
275 425
276 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, ""); 426 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, "");
277 } 427 }
278 428
279 } // namespace component_updater 429 } // namespace component_updater
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698