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

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

Issue 2226133005: Add support for the ExperimentalSwReporterEngine field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Set flags explicitly in srt_fetcher browsertest 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 <algorithm>
10 #include <map> 10 #include <map>
(...skipping 29 matching lines...) Expand all
40 #include "components/prefs/pref_registry_simple.h" 40 #include "components/prefs/pref_registry_simple.h"
41 #include "components/update_client/update_client.h" 41 #include "components/update_client/update_client.h"
42 #include "components/update_client/utils.h" 42 #include "components/update_client/utils.h"
43 #include "components/variations/variations_associated_data.h" 43 #include "components/variations/variations_associated_data.h"
44 #include "content/public/browser/browser_thread.h" 44 #include "content/public/browser/browser_thread.h"
45 45
46 namespace component_updater { 46 namespace component_updater {
47 47
48 namespace { 48 namespace {
49 49
50 using safe_browsing::SwReporterInvocation;
51
50 // These values are used to send UMA information and are replicated in the 52 // These values are used to send UMA information and are replicated in the
51 // histograms.xml file, so the order MUST NOT CHANGE. 53 // histograms.xml file, so the order MUST NOT CHANGE.
52 enum SRTCompleted { 54 enum SRTCompleted {
53 SRT_COMPLETED_NOT_YET = 0, 55 SRT_COMPLETED_NOT_YET = 0,
54 SRT_COMPLETED_YES = 1, 56 SRT_COMPLETED_YES = 1,
55 SRT_COMPLETED_LATER = 2, 57 SRT_COMPLETED_LATER = 2,
56 SRT_COMPLETED_MAX, 58 SRT_COMPLETED_MAX,
57 }; 59 };
58 60
59 // CRX hash. The extension id is: gkmgaooipdjhmangpemjhigmamcehddo. The hash was 61 // CRX hash. The extension id is: gkmgaooipdjhmangpemjhigmamcehddo. The hash was
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 116
115 void ReportExperimentError(SwReporterExperimentError error) { 117 void ReportExperimentError(SwReporterExperimentError error) {
116 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.ExperimentErrors", error, 118 UMA_HISTOGRAM_ENUMERATION("SoftwareReporter.ExperimentErrors", error,
117 SW_REPORTER_EXPERIMENT_ERROR_MAX); 119 SW_REPORTER_EXPERIMENT_ERROR_MAX);
118 } 120 }
119 121
120 // Run the software reporter on the next Chrome startup after it's downloaded. 122 // Run the software reporter on the next Chrome startup after it's downloaded.
121 // (This is the default |reporter_runner| function passed to the 123 // (This is the default |reporter_runner| function passed to the
122 // |SwReporterInstallerTraits| constructor in |RegisterSwReporterComponent| 124 // |SwReporterInstallerTraits| constructor in |RegisterSwReporterComponent|
123 // below.) 125 // below.)
124 void RunSwReporterAfterStartup( 126 void RunSwReportersAfterStartup(
125 const safe_browsing::SwReporterInvocation& invocation, 127 const safe_browsing::SwReporterQueue& invocations,
126 const base::Version& version) { 128 const base::Version& version) {
127 content::BrowserThread::PostAfterStartupTask( 129 content::BrowserThread::PostAfterStartupTask(
128 FROM_HERE, base::ThreadTaskRunnerHandle::Get(), 130 FROM_HERE, base::ThreadTaskRunnerHandle::Get(),
129 base::Bind(&safe_browsing::RunSwReporter, invocation, version, 131 base::Bind(&safe_browsing::RunSwReporters, invocations, version,
130 base::ThreadTaskRunnerHandle::Get(), 132 base::ThreadTaskRunnerHandle::Get(),
131 base::WorkerPool::GetTaskRunner(true))); 133 base::WorkerPool::GetTaskRunner(true)));
132 } 134 }
133 135
134 // Ensures |str| contains only alphanumeric characters and characters from 136 // Ensures |str| contains only alphanumeric characters and characters from
135 // |extras|, and is not longer than |max_length|. 137 // |extras|, and is not longer than |max_length|.
136 bool ValidateString(const std::string& str, 138 bool ValidateString(const std::string& str,
137 const std::string& extras, 139 const std::string& extras,
138 size_t max_length) { 140 size_t max_length) {
139 return str.size() <= max_length && 141 return str.size() <= max_length &&
140 std::all_of(str.cbegin(), str.cend(), [&extras](char c) { 142 std::all_of(str.cbegin(), str.cend(), [&extras](char c) {
141 return base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) || 143 return base::IsAsciiAlpha(c) || base::IsAsciiDigit(c) ||
142 extras.find(c) != std::string::npos; 144 extras.find(c) != std::string::npos;
143 }); 145 });
144 } 146 }
145 147
146 // Reads the command-line params and an UMA histogram suffix from the manifest, 148 // 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 149 // 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. 150 // SwReporter should not be run at all.
149 void RunExperimentalSwReporter(const base::FilePath& exe_path, 151 void RunExperimentalSwReporter(const base::FilePath& exe_path,
150 const base::Version& version, 152 const base::Version& version,
151 std::unique_ptr<base::DictionaryValue> manifest, 153 std::unique_ptr<base::DictionaryValue> manifest,
152 const SwReporterRunner& reporter_runner) { 154 const SwReporterRunner& reporter_runner) {
153 // The experiment requires launch_params so if they aren't present just 155 // 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 156 // return. This isn't an error because the user could get into the experiment
155 // group before they've downloaded the experiment component. 157 // group before they've downloaded the experiment component.
156 base::Value* launch_params = nullptr; 158 base::Value* launch_params = nullptr;
157 if (!manifest->Get("launch_params", &launch_params)) 159 if (!manifest->Get("launch_params", &launch_params))
158 return; 160 return;
159 161
160 const base::ListValue* parameter_list = nullptr; 162 const base::ListValue* parameter_list = nullptr;
161 if (!launch_params->GetAsList(&parameter_list) || parameter_list->empty() || 163 if (!launch_params->GetAsList(&parameter_list) || parameter_list->empty()) {
162 // For future expansion, the manifest takes a list of invocation
163 // parameters, but currently we only support a single invocation.
164 parameter_list->GetSize() > 1) {
165 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS); 164 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
166 return; 165 return;
167 } 166 }
168 167
169 const base::DictionaryValue* invocation_params = nullptr; 168 safe_browsing::SwReporterQueue invocations;
170 if (!parameter_list->GetDictionary(0, &invocation_params)) { 169 for (const auto& iter : *parameter_list) {
171 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS); 170 const base::DictionaryValue* invocation_params = nullptr;
172 return; 171 if (!iter->GetAsDictionary(&invocation_params)) {
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
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) ||
186 (!suffix.empty() &&
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) ||
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); 172 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
208 return; 173 return;
209 } 174 }
210 if (!argument.empty()) 175
211 argv.push_back(argument); 176 // Max length of the registry and histogram suffix. Fairly arbitrary: the
177 // Windows registry accepts much longer keys, but we need to display this
178 // string in histograms as well.
179 constexpr size_t kMaxSuffixLength = 80;
180
181 // The suffix must be an alphanumeric string. (Empty is fine as long as the
182 // "suffix" key is present.)
183 std::string suffix;
184 if (!invocation_params->GetString("suffix", &suffix) ||
185 !ValidateString(suffix, std::string(), kMaxSuffixLength)) {
186 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
187 return;
188 }
189
190 // Build a command line for the reporter out of the executable path and the
191 // arguments from the manifest. (The "arguments" key must be present, but
192 // it's ok if it's an empty list or a list of empty strings.)
193 const base::ListValue* arguments = nullptr;
194 if (!invocation_params->GetList("arguments", &arguments)) {
195 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
196 return;
197 }
198
199 std::vector<base::string16> argv = {exe_path.value()};
200 for (const auto& value : *arguments) {
201 base::string16 argument;
202 if (!value->GetAsString(&argument)) {
203 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
204 return;
205 }
206 if (!argument.empty())
207 argv.push_back(argument);
208 }
209
210 base::CommandLine command_line(argv);
211
212 // Add the histogram suffix to the command-line as well, so that the
213 // reporter will add the same suffix to registry keys where it writes
214 // metrics.
215 if (!suffix.empty())
216 command_line.AppendSwitchASCII("registry-suffix", suffix);
217
218 // "prompt" is optional, but if present must be a boolean.
219 SwReporterInvocation::Flags flags = 0;
220 const base::Value* prompt_value = nullptr;
221 if (invocation_params->Get("prompt", &prompt_value)) {
222 bool prompt = false;
223 if (!prompt_value->GetAsBoolean(&prompt)) {
224 ReportExperimentError(SW_REPORTER_EXPERIMENT_ERROR_BAD_PARAMS);
225 return;
226 }
227 if (prompt)
228 flags |= SwReporterInvocation::FLAG_TRIGGER_PROMPT;
229 }
230
231 auto invocation = SwReporterInvocation::FromCommandLine(command_line);
232 invocation.suffix = suffix;
233 invocation.flags = flags;
234 invocations.push(invocation);
212 } 235 }
213 236
214 base::CommandLine command_line(argv); 237 DCHECK(!invocations.empty());
215 238 reporter_runner.Run(invocations, version);
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 } 239 }
229 240
230 } // namespace 241 } // namespace
231 242
232 SwReporterInstallerTraits::SwReporterInstallerTraits( 243 SwReporterInstallerTraits::SwReporterInstallerTraits(
233 const SwReporterRunner& reporter_runner, 244 const SwReporterRunner& reporter_runner,
234 bool is_experimental_engine_supported) 245 bool is_experimental_engine_supported)
235 : reporter_runner_(reporter_runner), 246 : reporter_runner_(reporter_runner),
236 is_experimental_engine_supported_(is_experimental_engine_supported) {} 247 is_experimental_engine_supported_(is_experimental_engine_supported) {}
237 248
(...skipping 23 matching lines...) Expand all
261 void SwReporterInstallerTraits::ComponentReady( 272 void SwReporterInstallerTraits::ComponentReady(
262 const base::Version& version, 273 const base::Version& version,
263 const base::FilePath& install_dir, 274 const base::FilePath& install_dir,
264 std::unique_ptr<base::DictionaryValue> manifest) { 275 std::unique_ptr<base::DictionaryValue> manifest) {
265 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 276 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
266 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName)); 277 const base::FilePath exe_path(install_dir.Append(kSwReporterExeName));
267 if (IsExperimentalEngineEnabled()) { 278 if (IsExperimentalEngineEnabled()) {
268 RunExperimentalSwReporter(exe_path, version, std::move(manifest), 279 RunExperimentalSwReporter(exe_path, version, std::move(manifest),
269 reporter_runner_); 280 reporter_runner_);
270 } else { 281 } else {
271 reporter_runner_.Run( 282 auto invocation = SwReporterInvocation::FromFilePath(exe_path);
272 safe_browsing::SwReporterInvocation::FromFilePath(exe_path), version); 283 invocation.flags = SwReporterInvocation::FLAG_LOG_TO_RAPPOR |
284 SwReporterInvocation::FLAG_LOG_EXIT_CODE_TO_PREFS |
285 SwReporterInvocation::FLAG_TRIGGER_PROMPT |
286 SwReporterInvocation::FLAG_SEND_REPORTER_LOGS;
287
288 safe_browsing::SwReporterQueue invocations;
289 invocations.push(invocation);
290 reporter_runner_.Run(invocations, version);
273 } 291 }
274 } 292 }
275 293
276 base::FilePath SwReporterInstallerTraits::GetRelativeInstallDir() const { 294 base::FilePath SwReporterInstallerTraits::GetRelativeInstallDir() const {
277 return base::FilePath(FILE_PATH_LITERAL("SwReporter")); 295 return base::FilePath(FILE_PATH_LITERAL("SwReporter"));
278 } 296 }
279 297
280 void SwReporterInstallerTraits::GetHash(std::vector<uint8_t>* hash) const { 298 void SwReporterInstallerTraits::GetHash(std::vector<uint8_t>* hash) const {
281 DCHECK(hash); 299 DCHECK(hash);
282 hash->assign(kSha256Hash, kSha256Hash + sizeof(kSha256Hash)); 300 hash->assign(kSha256Hash, kSha256Hash + sizeof(kSha256Hash));
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 } 416 }
399 417
400 // The experiment is only enabled on x86. There's no way to check this in the 418 // 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. 419 // variations config so we'll hard-code it.
402 const bool is_experimental_engine_supported = 420 const bool is_experimental_engine_supported =
403 base::win::OSInfo::GetInstance()->architecture() == 421 base::win::OSInfo::GetInstance()->architecture() ==
404 base::win::OSInfo::X86_ARCHITECTURE; 422 base::win::OSInfo::X86_ARCHITECTURE;
405 423
406 // Install the component. 424 // Install the component.
407 std::unique_ptr<ComponentInstallerTraits> traits( 425 std::unique_ptr<ComponentInstallerTraits> traits(
408 new SwReporterInstallerTraits(base::Bind(&RunSwReporterAfterStartup), 426 new SwReporterInstallerTraits(base::Bind(&RunSwReportersAfterStartup),
409 is_experimental_engine_supported)); 427 is_experimental_engine_supported));
410 // |cus| will take ownership of |installer| during installer->Register(cus). 428 // |cus| will take ownership of |installer| during installer->Register(cus).
411 DefaultComponentInstaller* installer = 429 DefaultComponentInstaller* installer =
412 new DefaultComponentInstaller(std::move(traits)); 430 new DefaultComponentInstaller(std::move(traits));
413 installer->Register(cus, base::Closure()); 431 installer->Register(cus, base::Closure());
414 } 432 }
415 433
416 void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) { 434 void RegisterPrefsForSwReporter(PrefRegistrySimple* registry) {
417 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeTriggered, 0); 435 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeTriggered, 0);
418 registry->RegisterIntegerPref(prefs::kSwReporterLastExitCode, -1); 436 registry->RegisterIntegerPref(prefs::kSwReporterLastExitCode, -1);
419 registry->RegisterBooleanPref(prefs::kSwReporterPendingPrompt, false); 437 registry->RegisterBooleanPref(prefs::kSwReporterPendingPrompt, false);
420 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeSentReport, 0); 438 registry->RegisterInt64Pref(prefs::kSwReporterLastTimeSentReport, 0);
421 } 439 }
422 440
423 void RegisterProfilePrefsForSwReporter( 441 void RegisterProfilePrefsForSwReporter(
424 user_prefs::PrefRegistrySyncable* registry) { 442 user_prefs::PrefRegistrySyncable* registry) {
425 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, ""); 443 registry->RegisterStringPref(prefs::kSwReporterPromptVersion, "");
426 444
427 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, ""); 445 registry->RegisterStringPref(prefs::kSwReporterPromptSeed, "");
428 } 446 }
429 447
430 } // namespace component_updater 448 } // namespace component_updater
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698