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

Side by Side Diff: chrome/browser/shell_integration.cc

Issue 1426663005: Make the histograms for setting the default browser consistent (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comments Created 5 years, 1 month 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) 2012 The Chromium Authors. All rights reserved. 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 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/shell_integration.h" 5 #include "chrome/browser/shell_integration.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/files/file_util.h" 9 #include "base/files/file_util.h"
10 #include "base/metrics/histogram_macros.h" 10 #include "base/metrics/histogram_macros.h"
11 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
14 #include "base/threading/thread_restrictions.h" 15 #include "base/threading/thread_restrictions.h"
15 #include "base/timer/timer.h" 16 #include "base/timer/timer.h"
16 #include "chrome/browser/policy/policy_path_parser.h" 17 #include "chrome/browser/policy/policy_path_parser.h"
17 #include "chrome/common/chrome_paths.h" 18 #include "chrome/common/chrome_paths.h"
18 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
19 #include "components/version_info/version_info.h" 20 #include "components/version_info/version_info.h"
20 #include "content/public/browser/browser_thread.h" 21 #include "content/public/browser/browser_thread.h"
21 22
22 #if defined(OS_CHROMEOS) 23 #if defined(OS_CHROMEOS)
23 #include "chromeos/chromeos_switches.h" 24 #include "chromeos/chromeos_switches.h"
24 #endif 25 #endif
25 26
26 #if !defined(OS_WIN) 27 #if !defined(OS_WIN)
27 #include "chrome/common/channel_info.h" 28 #include "chrome/common/channel_info.h"
28 #include "chrome/grit/chromium_strings.h" 29 #include "chrome/grit/chromium_strings.h"
29 #include "ui/base/l10n/l10n_util.h" 30 #include "ui/base/l10n/l10n_util.h"
30 #endif 31 #endif
31 32
32 using content::BrowserThread; 33 using content::BrowserThread;
33 34
34 namespace { 35 namespace {
35 36
36 const struct ShellIntegration::AppModeInfo* gAppModeInfo = nullptr; 37 const struct ShellIntegration::AppModeInfo* gAppModeInfo = nullptr;
37 38
39 // Returns true if the duration should be reported to UMA for |result|.
40 bool ShouldReportDurationForResult(
41 ShellIntegration::DefaultWebClientWorker::AttemptResult result) {
42 using AttemptResult = ShellIntegration::DefaultWebClientWorker::AttemptResult;
43
44 return result == AttemptResult::SUCCESS || result == AttemptResult::FAILURE ||
45 result == AttemptResult::ABANDONED || result == AttemptResult::RETRY;
46 }
47
48 // Returns a string based on |result| used for UMA reports.
49 const char* AttemptResultToString(
50 ShellIntegration::DefaultWebClientWorker::AttemptResult result) {
51 using AttemptResult = ShellIntegration::DefaultWebClientWorker::AttemptResult;
52
53 switch (result) {
54 case AttemptResult::SUCCESS:
55 return "Success";
56 case AttemptResult::ALREADY_DEFAULT:
57 return "AlreadyDefault";
58 case AttemptResult::FAILURE:
59 return "Failure";
60 case AttemptResult::ABANDONED:
61 return "Abandoned";
62 case AttemptResult::LAUNCH_FAILURE:
63 return "LaunchFailure";
64 case AttemptResult::OTHER_WORKER:
65 return "OtherWorker";
66 case AttemptResult::RETRY:
67 return "Retry";
68 case AttemptResult::NO_ERRORS_NOT_DEFAULT:
69 return "NoErrorsNotDefault";
70 default:
grt (UTC plus 2) 2015/11/10 20:04:30 leave out the "default" case so that the compiler
Patrick Monette 2015/11/11 22:03:35 Done.
71 NOTREACHED();
72 return "";
73 }
74 }
75
38 } // namespace 76 } // namespace
39 77
40 #if !defined(OS_WIN) 78 #if !defined(OS_WIN)
41 // static 79 // static
42 bool ShellIntegration::SetAsDefaultBrowserInteractive() { 80 bool ShellIntegration::SetAsDefaultBrowserInteractive() {
43 return false; 81 return false;
44 } 82 }
45 83
46 // static 84 // static
47 bool ShellIntegration::IsSetAsDefaultAsynchronous() { 85 bool ShellIntegration::IsSetAsDefaultAsynchronous() {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 207
170 /////////////////////////////////////////////////////////////////////////////// 208 ///////////////////////////////////////////////////////////////////////////////
171 // ShellIntegration::DefaultWebClientWorker 209 // ShellIntegration::DefaultWebClientWorker
172 // 210 //
173 211
174 ShellIntegration::DefaultWebClientWorker::DefaultWebClientWorker( 212 ShellIntegration::DefaultWebClientWorker::DefaultWebClientWorker(
175 DefaultWebClientObserver* observer) 213 DefaultWebClientObserver* observer)
176 : observer_(observer) {} 214 : observer_(observer) {}
177 215
178 void ShellIntegration::DefaultWebClientWorker::StartCheckIsDefault() { 216 void ShellIntegration::DefaultWebClientWorker::StartCheckIsDefault() {
179 if (observer_) { 217 if (observer_)
180 observer_->SetDefaultWebClientUIState(STATE_PROCESSING); 218 observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
181 BrowserThread::PostTask( 219
182 BrowserThread::FILE, FROM_HERE, 220 BrowserThread::PostTask(
183 base::Bind(&DefaultWebClientWorker::CheckIsDefault, this)); 221 BrowserThread::FILE, FROM_HERE,
184 } 222 base::Bind(&DefaultWebClientWorker::CheckIsDefault, this));
185 } 223 }
186 224
187 void ShellIntegration::DefaultWebClientWorker::StartSetAsDefault() { 225 void ShellIntegration::DefaultWebClientWorker::StartSetAsDefault() {
188 // Cancel the already running process if another start is requested. 226 // Cancel the already running process if another start is requested.
189 if (set_as_default_in_progress_) { 227 if (set_as_default_in_progress_) {
190 if (set_as_default_initialized_) { 228 if (set_as_default_initialized_) {
191 FinalizeSetAsDefault(); 229 FinalizeSetAsDefault();
192 set_as_default_initialized_ = false; 230 set_as_default_initialized_ = false;
193 } 231 }
194 232
195 ReportAttemptResult(AttemptResult::RETRY); 233 ReportAttemptResult(AttemptResult::RETRY);
196 } 234 }
197 235
198 set_as_default_in_progress_ = true; 236 set_as_default_in_progress_ = true;
199 bool interactive_permitted = false; 237 bool interactive_permitted = true;
200 if (observer_) { 238 if (observer_) {
201 observer_->SetDefaultWebClientUIState(STATE_PROCESSING); 239 observer_->SetDefaultWebClientUIState(STATE_PROCESSING);
202 interactive_permitted = observer_->IsInteractiveSetDefaultPermitted(); 240 interactive_permitted = observer_->IsInteractiveSetDefaultPermitted();
241 }
203 242
204 // The initialization is only useful when there is an observer. 243 set_as_default_initialized_ = InitializeSetAsDefault();
205 set_as_default_initialized_ = InitializeSetAsDefault();
206 }
207 244
208 // Remember the start time. 245 // Remember the start time.
209 start_time_ = base::TimeTicks::Now(); 246 start_time_ = base::TimeTicks::Now();
210 247
211 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, 248 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
212 base::Bind(&DefaultWebClientWorker::SetAsDefault, 249 base::Bind(&DefaultWebClientWorker::SetAsDefault,
213 this, interactive_permitted)); 250 this, interactive_permitted));
214 } 251 }
215 252
216 void ShellIntegration::DefaultWebClientWorker::ObserverDestroyed() { 253 void ShellIntegration::DefaultWebClientWorker::ObserverDestroyed() {
(...skipping 13 matching lines...) Expand all
230 267
231 /////////////////////////////////////////////////////////////////////////////// 268 ///////////////////////////////////////////////////////////////////////////////
232 // DefaultWebClientWorker, private: 269 // DefaultWebClientWorker, private:
233 270
234 ShellIntegration::DefaultWebClientWorker::~DefaultWebClientWorker() {} 271 ShellIntegration::DefaultWebClientWorker::~DefaultWebClientWorker() {}
235 272
236 void ShellIntegration::DefaultWebClientWorker::OnCheckIsDefaultComplete( 273 void ShellIntegration::DefaultWebClientWorker::OnCheckIsDefaultComplete(
237 DefaultWebClientState state) { 274 DefaultWebClientState state) {
238 DCHECK_CURRENTLY_ON(BrowserThread::UI); 275 DCHECK_CURRENTLY_ON(BrowserThread::UI);
239 UpdateUI(state); 276 UpdateUI(state);
277
278 if (check_default_should_report_success_) {
279 check_default_should_report_success_ = false;
280
281 ReportAttemptResult(state == DefaultWebClientState::IS_DEFAULT
282 ? AttemptResult::SUCCESS
283 : AttemptResult::NO_ERRORS_NOT_DEFAULT);
284 }
285
240 // The worker has finished everything it needs to do, so free the observer 286 // The worker has finished everything it needs to do, so free the observer
241 // if we own it. 287 // if we own it.
242 if (observer_ && observer_->IsOwnedByWorker()) { 288 if (observer_ && observer_->IsOwnedByWorker()) {
243 delete observer_; 289 delete observer_;
244 observer_ = nullptr; 290 observer_ = nullptr;
245 } 291 }
246 } 292 }
247 293
248 void ShellIntegration::DefaultWebClientWorker::OnSetAsDefaultAttemptComplete( 294 void ShellIntegration::DefaultWebClientWorker::OnSetAsDefaultAttemptComplete(
249 AttemptResult result) { 295 AttemptResult result) {
250 DCHECK_CURRENTLY_ON(BrowserThread::UI); 296 DCHECK_CURRENTLY_ON(BrowserThread::UI);
251 // Hold on to a reference because if this was called via the default browser 297 // Hold on to a reference because if this was called via the default browser
252 // callback in StartupBrowserCreator, clearing the callback in 298 // callback in StartupBrowserCreator, clearing the callback in
253 // FinalizeSetAsDefault would otherwise remove the last reference and delete 299 // FinalizeSetAsDefault() would otherwise remove the last reference and delete
254 // us in the middle of this function. 300 // us in the middle of this function.
255 scoped_refptr<DefaultWebClientWorker> scoped_ref(this); 301 scoped_refptr<DefaultWebClientWorker> scoped_ref(this);
256 302
257 if (set_as_default_in_progress_) { 303 if (set_as_default_in_progress_) {
258 set_as_default_in_progress_ = false; 304 set_as_default_in_progress_ = false;
259 305
260 if (set_as_default_initialized_) { 306 if (set_as_default_initialized_) {
261 FinalizeSetAsDefault(); 307 FinalizeSetAsDefault();
262 set_as_default_initialized_ = false; 308 set_as_default_initialized_ = false;
263 } 309 }
264 if (observer_) { 310 if (observer_) {
265 bool succeeded = result == AttemptResult::SUCCESS || 311 bool succeeded = result == AttemptResult::SUCCESS ||
266 result == AttemptResult::ALREADY_DEFAULT; 312 result == AttemptResult::ALREADY_DEFAULT;
267 observer_->OnSetAsDefaultConcluded(succeeded); 313 observer_->OnSetAsDefaultConcluded(succeeded);
268 } 314 }
269 315
270 ReportAttemptResult(result); 316 // Report failures here. Successes are reported in
317 // OnCheckIsDefaultComplete() after checking that the change is verified.
318 check_default_should_report_success_ = result == AttemptResult::SUCCESS;
319 if (!check_default_should_report_success_)
320 ReportAttemptResult(result);
271 321
272 // Start the default browser check which will notify the observer as to 322 // Start the default browser check which will notify the observer as to
273 // whether Chrome is really the default browser. This is needed because 323 // whether Chrome is really the default browser. This is needed because
274 // detecting that the process was successful is not 100% sure. 324 // detecting that the process was successful is not 100% sure.
275 // For example, on Windows 10+, the user might have unchecked the "Always 325 // For example, on Windows 10+, the user might have unchecked the "Always
276 // use this app" checkbox which can't be detected. 326 // use this app" checkbox which can't be detected.
277 StartCheckIsDefault(); 327 StartCheckIsDefault();
278 } 328 }
279 } 329 }
280 330
281 void ShellIntegration::DefaultWebClientWorker::ReportAttemptResult( 331 void ShellIntegration::DefaultWebClientWorker::ReportAttemptResult(
282 AttemptResult result) { 332 AttemptResult result) {
283 if (!ShouldReportAttemptResults()) 333 const char* histogram_prefix = GetHistogramPrefix();
284 return;
285 334
286 UMA_HISTOGRAM_ENUMERATION("DefaultBrowser.AsyncSetAsDefault.Result", result, 335 // Report result.
287 AttemptResult::NUM_ATTEMPT_RESULT_TYPES); 336 base::HistogramBase* result_histogram = base::LinearHistogram::FactoryGet(
337 base::StringPrintf("%s.Result", histogram_prefix), 1,
338 AttemptResult::NUM_ATTEMPT_RESULT_TYPES,
339 AttemptResult::NUM_ATTEMPT_RESULT_TYPES + 1,
340 base::HistogramBase::kUmaTargetedHistogramFlag);
288 341
289 switch (result) { 342 result_histogram->Add(result);
grt (UTC plus 2) 2015/11/10 20:04:30 nit: do away with the local variable and move "->A
Patrick Monette 2015/11/11 22:03:35 Done.
290 case SUCCESS: 343
291 UMA_HISTOGRAM_MEDIUM_TIMES( 344 // Report asynchronous duration.
292 "DefaultBrowser.AsyncSetAsDefault.Duration_Success", 345 if (IsSetAsDefaultAsynchronous() && ShouldReportDurationForResult(result)) {
293 base::TimeTicks::Now() - start_time_); 346 base::HistogramBase* duration_histogram = base::Histogram::FactoryTimeGet(
294 break; 347 base::StringPrintf("%s.AsyncDuration_%s", histogram_prefix,
295 case FAILURE: 348 AttemptResultToString(result)),
296 UMA_HISTOGRAM_MEDIUM_TIMES( 349 base::TimeDelta::FromMilliseconds(10), base::TimeDelta::FromMinutes(3),
297 "DefaultBrowser.AsyncSetAsDefault.Duration_Failure", 350 50, base::HistogramBase::kUmaTargetedHistogramFlag);
298 base::TimeTicks::Now() - start_time_); 351
299 break; 352 const base::TimeDelta delta = base::TimeTicks::Now() - start_time_;
300 case ABANDONED: 353 duration_histogram->AddTime(delta);
grt (UTC plus 2) 2015/11/10 20:04:30 same comment here
Patrick Monette 2015/11/11 22:03:35 Done.
301 UMA_HISTOGRAM_MEDIUM_TIMES(
302 "DefaultBrowser.AsyncSetAsDefault.Duration_Abandoned",
303 base::TimeTicks::Now() - start_time_);
304 break;
305 case RETRY:
306 UMA_HISTOGRAM_MEDIUM_TIMES(
307 "DefaultBrowser.AsyncSetAsDefault.Duration_Retry",
308 base::TimeTicks::Now() - start_time_);
309 break;
310 default:
311 break;
312 } 354 }
313 } 355 }
314 356
315 bool ShellIntegration::DefaultWebClientWorker::InitializeSetAsDefault() { 357 bool ShellIntegration::DefaultWebClientWorker::InitializeSetAsDefault() {
316 return true; 358 return true;
317 } 359 }
318 360
319 void ShellIntegration::DefaultWebClientWorker::FinalizeSetAsDefault() {} 361 void ShellIntegration::DefaultWebClientWorker::FinalizeSetAsDefault() {}
320 362
321 #if !defined(OS_WIN)
322 // static
323 bool ShellIntegration::DefaultWebClientWorker::ShouldReportAttemptResults() {
324 return false;
325 }
326 #endif // !defined(OS_WIN)
327
328 void ShellIntegration::DefaultWebClientWorker::UpdateUI( 363 void ShellIntegration::DefaultWebClientWorker::UpdateUI(
329 DefaultWebClientState state) { 364 DefaultWebClientState state) {
330 if (observer_) { 365 if (observer_) {
331 switch (state) { 366 switch (state) {
332 case NOT_DEFAULT: 367 case NOT_DEFAULT:
333 observer_->SetDefaultWebClientUIState(STATE_NOT_DEFAULT); 368 observer_->SetDefaultWebClientUIState(STATE_NOT_DEFAULT);
334 break; 369 break;
335 case IS_DEFAULT: 370 case IS_DEFAULT:
336 observer_->SetDefaultWebClientUIState(STATE_IS_DEFAULT); 371 observer_->SetDefaultWebClientUIState(STATE_IS_DEFAULT);
337 break; 372 break;
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
450 break; 485 break;
451 case SET_DEFAULT_ASYNCHRONOUS: 486 case SET_DEFAULT_ASYNCHRONOUS:
452 NOTREACHED(); 487 NOTREACHED();
453 break; 488 break;
454 } 489 }
455 BrowserThread::PostTask( 490 BrowserThread::PostTask(
456 BrowserThread::UI, FROM_HERE, 491 BrowserThread::UI, FROM_HERE,
457 base::Bind(&DefaultProtocolClientWorker::OnSetAsDefaultAttemptComplete, 492 base::Bind(&DefaultProtocolClientWorker::OnSetAsDefaultAttemptComplete,
458 this, result)); 493 this, result));
459 } 494 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698