| OLD | NEW |
| 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) |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 169 | 170 |
| 170 /////////////////////////////////////////////////////////////////////////////// | 171 /////////////////////////////////////////////////////////////////////////////// |
| 171 // ShellIntegration::DefaultWebClientWorker | 172 // ShellIntegration::DefaultWebClientWorker |
| 172 // | 173 // |
| 173 | 174 |
| 174 ShellIntegration::DefaultWebClientWorker::DefaultWebClientWorker( | 175 ShellIntegration::DefaultWebClientWorker::DefaultWebClientWorker( |
| 175 DefaultWebClientObserver* observer) | 176 DefaultWebClientObserver* observer) |
| 176 : observer_(observer) {} | 177 : observer_(observer) {} |
| 177 | 178 |
| 178 void ShellIntegration::DefaultWebClientWorker::StartCheckIsDefault() { | 179 void ShellIntegration::DefaultWebClientWorker::StartCheckIsDefault() { |
| 179 if (observer_) { | 180 if (observer_) |
| 180 observer_->SetDefaultWebClientUIState(STATE_PROCESSING); | 181 observer_->SetDefaultWebClientUIState(STATE_PROCESSING); |
| 181 BrowserThread::PostTask( | 182 |
| 182 BrowserThread::FILE, FROM_HERE, | 183 BrowserThread::PostTask( |
| 183 base::Bind(&DefaultWebClientWorker::CheckIsDefault, this)); | 184 BrowserThread::FILE, FROM_HERE, |
| 184 } | 185 base::Bind(&DefaultWebClientWorker::CheckIsDefault, this)); |
| 185 } | 186 } |
| 186 | 187 |
| 187 void ShellIntegration::DefaultWebClientWorker::StartSetAsDefault() { | 188 void ShellIntegration::DefaultWebClientWorker::StartSetAsDefault() { |
| 188 // Cancel the already running process if another start is requested. | 189 // Cancel the already running process if another start is requested. |
| 189 if (set_as_default_in_progress_) { | 190 if (set_as_default_in_progress_) { |
| 190 if (set_as_default_initialized_) { | 191 if (set_as_default_initialized_) { |
| 191 FinalizeSetAsDefault(); | 192 FinalizeSetAsDefault(); |
| 192 set_as_default_initialized_ = false; | 193 set_as_default_initialized_ = false; |
| 193 } | 194 } |
| 194 | 195 |
| 195 ReportAttemptResult(AttemptResult::RETRY); | 196 ReportAttemptResult(AttemptResult::RETRY); |
| 196 } | 197 } |
| 197 | 198 |
| 198 set_as_default_in_progress_ = true; | 199 set_as_default_in_progress_ = true; |
| 199 bool interactive_permitted = false; | 200 bool interactive_permitted = true; |
| 200 if (observer_) { | 201 if (observer_) { |
| 201 observer_->SetDefaultWebClientUIState(STATE_PROCESSING); | 202 observer_->SetDefaultWebClientUIState(STATE_PROCESSING); |
| 202 interactive_permitted = observer_->IsInteractiveSetDefaultPermitted(); | 203 interactive_permitted = observer_->IsInteractiveSetDefaultPermitted(); |
| 204 } |
| 203 | 205 |
| 204 // The initialization is only useful when there is an observer. | 206 set_as_default_initialized_ = InitializeSetAsDefault(); |
| 205 set_as_default_initialized_ = InitializeSetAsDefault(); | |
| 206 } | |
| 207 | 207 |
| 208 // Remember the start time. | 208 // Remember the start time. |
| 209 start_time_ = base::TimeTicks::Now(); | 209 start_time_ = base::TimeTicks::Now(); |
| 210 | 210 |
| 211 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, | 211 BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, |
| 212 base::Bind(&DefaultWebClientWorker::SetAsDefault, | 212 base::Bind(&DefaultWebClientWorker::SetAsDefault, |
| 213 this, interactive_permitted)); | 213 this, interactive_permitted)); |
| 214 } | 214 } |
| 215 | 215 |
| 216 void ShellIntegration::DefaultWebClientWorker::ObserverDestroyed() { | 216 void ShellIntegration::DefaultWebClientWorker::ObserverDestroyed() { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 230 | 230 |
| 231 /////////////////////////////////////////////////////////////////////////////// | 231 /////////////////////////////////////////////////////////////////////////////// |
| 232 // DefaultWebClientWorker, private: | 232 // DefaultWebClientWorker, private: |
| 233 | 233 |
| 234 ShellIntegration::DefaultWebClientWorker::~DefaultWebClientWorker() {} | 234 ShellIntegration::DefaultWebClientWorker::~DefaultWebClientWorker() {} |
| 235 | 235 |
| 236 void ShellIntegration::DefaultWebClientWorker::OnCheckIsDefaultComplete( | 236 void ShellIntegration::DefaultWebClientWorker::OnCheckIsDefaultComplete( |
| 237 DefaultWebClientState state) { | 237 DefaultWebClientState state) { |
| 238 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 238 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 239 UpdateUI(state); | 239 UpdateUI(state); |
| 240 |
| 241 if (check_default_should_report_success_) { |
| 242 check_default_should_report_success_ = false; |
| 243 |
| 244 ReportAttemptResult(state == DefaultWebClientState::IS_DEFAULT |
| 245 ? AttemptResult::SUCCESS |
| 246 : AttemptResult::NO_ERRORS_NOT_DEFAULT); |
| 247 } |
| 248 |
| 240 // The worker has finished everything it needs to do, so free the observer | 249 // The worker has finished everything it needs to do, so free the observer |
| 241 // if we own it. | 250 // if we own it. |
| 242 if (observer_ && observer_->IsOwnedByWorker()) { | 251 if (observer_ && observer_->IsOwnedByWorker()) { |
| 243 delete observer_; | 252 delete observer_; |
| 244 observer_ = nullptr; | 253 observer_ = nullptr; |
| 245 } | 254 } |
| 246 } | 255 } |
| 247 | 256 |
| 248 void ShellIntegration::DefaultWebClientWorker::OnSetAsDefaultAttemptComplete( | 257 void ShellIntegration::DefaultWebClientWorker::OnSetAsDefaultAttemptComplete( |
| 249 AttemptResult result) { | 258 AttemptResult result) { |
| 250 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 259 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 251 // Hold on to a reference because if this was called via the default browser | 260 // Hold on to a reference because if this was called via the default browser |
| 252 // callback in StartupBrowserCreator, clearing the callback in | 261 // callback in StartupBrowserCreator, clearing the callback in |
| 253 // FinalizeSetAsDefault would otherwise remove the last reference and delete | 262 // FinalizeSetAsDefault() would otherwise remove the last reference and delete |
| 254 // us in the middle of this function. | 263 // us in the middle of this function. |
| 255 scoped_refptr<DefaultWebClientWorker> scoped_ref(this); | 264 scoped_refptr<DefaultWebClientWorker> scoped_ref(this); |
| 256 | 265 |
| 257 if (set_as_default_in_progress_) { | 266 if (set_as_default_in_progress_) { |
| 258 set_as_default_in_progress_ = false; | 267 set_as_default_in_progress_ = false; |
| 259 | 268 |
| 260 if (set_as_default_initialized_) { | 269 if (set_as_default_initialized_) { |
| 261 FinalizeSetAsDefault(); | 270 FinalizeSetAsDefault(); |
| 262 set_as_default_initialized_ = false; | 271 set_as_default_initialized_ = false; |
| 263 } | 272 } |
| 264 if (observer_) { | 273 if (observer_) { |
| 265 bool succeeded = result == AttemptResult::SUCCESS || | 274 bool succeeded = result == AttemptResult::SUCCESS || |
| 266 result == AttemptResult::ALREADY_DEFAULT; | 275 result == AttemptResult::ALREADY_DEFAULT; |
| 267 observer_->OnSetAsDefaultConcluded(succeeded); | 276 observer_->OnSetAsDefaultConcluded(succeeded); |
| 268 } | 277 } |
| 269 | 278 |
| 270 ReportAttemptResult(result); | 279 // Report failures here. Successes are reported in |
| 280 // OnCheckIsDefaultComplete() after checking that the change is verified. |
| 281 check_default_should_report_success_ = result == AttemptResult::SUCCESS; |
| 282 if (!check_default_should_report_success_) |
| 283 ReportAttemptResult(result); |
| 271 | 284 |
| 272 // Start the default browser check which will notify the observer as to | 285 // Start the default browser check which will notify the observer as to |
| 273 // whether Chrome is really the default browser. This is needed because | 286 // whether Chrome is really the default browser. This is needed because |
| 274 // detecting that the process was successful is not 100% sure. | 287 // detecting that the process was successful is not 100% sure. |
| 275 // For example, on Windows 10+, the user might have unchecked the "Always | 288 // For example, on Windows 10+, the user might have unchecked the "Always |
| 276 // use this app" checkbox which can't be detected. | 289 // use this app" checkbox which can't be detected. |
| 277 StartCheckIsDefault(); | 290 StartCheckIsDefault(); |
| 278 } | 291 } |
| 279 } | 292 } |
| 280 | 293 |
| 281 void ShellIntegration::DefaultWebClientWorker::ReportAttemptResult( | 294 void ShellIntegration::DefaultWebClientWorker::ReportAttemptResult( |
| 282 AttemptResult result) { | 295 AttemptResult result) { |
| 283 if (!ShouldReportAttemptResults()) | 296 const char* histogram_prefix = GetHistogramPrefix(); |
| 284 return; | |
| 285 | 297 |
| 286 UMA_HISTOGRAM_ENUMERATION("DefaultBrowser.AsyncSetAsDefault.Result", result, | 298 // Report result. |
| 287 AttemptResult::NUM_ATTEMPT_RESULT_TYPES); | 299 base::LinearHistogram::FactoryGet( |
| 300 base::StringPrintf("%s.SetDefaultResult", histogram_prefix), 1, |
| 301 AttemptResult::NUM_ATTEMPT_RESULT_TYPES, |
| 302 AttemptResult::NUM_ATTEMPT_RESULT_TYPES + 1, |
| 303 base::HistogramBase::kUmaTargetedHistogramFlag) |
| 304 ->Add(result); |
| 288 | 305 |
| 289 switch (result) { | 306 // Report asynchronous duration. |
| 290 case SUCCESS: | 307 if (IsSetAsDefaultAsynchronous() && ShouldReportDurationForResult(result)) { |
| 291 UMA_HISTOGRAM_MEDIUM_TIMES( | 308 base::Histogram::FactoryTimeGet( |
| 292 "DefaultBrowser.AsyncSetAsDefault.Duration_Success", | 309 base::StringPrintf("%s.SetDefaultAsyncDuration_%s", histogram_prefix, |
| 293 base::TimeTicks::Now() - start_time_); | 310 AttemptResultToString(result)), |
| 294 break; | 311 base::TimeDelta::FromMilliseconds(10), base::TimeDelta::FromMinutes(3), |
| 295 case FAILURE: | 312 50, base::HistogramBase::kUmaTargetedHistogramFlag) |
| 296 UMA_HISTOGRAM_MEDIUM_TIMES( | 313 ->AddTime(base::TimeTicks::Now() - start_time_); |
| 297 "DefaultBrowser.AsyncSetAsDefault.Duration_Failure", | |
| 298 base::TimeTicks::Now() - start_time_); | |
| 299 break; | |
| 300 case ABANDONED: | |
| 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 } | 314 } |
| 313 } | 315 } |
| 314 | 316 |
| 315 bool ShellIntegration::DefaultWebClientWorker::InitializeSetAsDefault() { | 317 bool ShellIntegration::DefaultWebClientWorker::InitializeSetAsDefault() { |
| 316 return true; | 318 return true; |
| 317 } | 319 } |
| 318 | 320 |
| 319 void ShellIntegration::DefaultWebClientWorker::FinalizeSetAsDefault() {} | 321 void ShellIntegration::DefaultWebClientWorker::FinalizeSetAsDefault() {} |
| 320 | 322 |
| 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( | 323 void ShellIntegration::DefaultWebClientWorker::UpdateUI( |
| 329 DefaultWebClientState state) { | 324 DefaultWebClientState state) { |
| 330 if (observer_) { | 325 if (observer_) { |
| 331 switch (state) { | 326 switch (state) { |
| 332 case NOT_DEFAULT: | 327 case NOT_DEFAULT: |
| 333 observer_->SetDefaultWebClientUIState(STATE_NOT_DEFAULT); | 328 observer_->SetDefaultWebClientUIState(STATE_NOT_DEFAULT); |
| 334 break; | 329 break; |
| 335 case IS_DEFAULT: | 330 case IS_DEFAULT: |
| 336 observer_->SetDefaultWebClientUIState(STATE_IS_DEFAULT); | 331 observer_->SetDefaultWebClientUIState(STATE_IS_DEFAULT); |
| 337 break; | 332 break; |
| 338 case UNKNOWN_DEFAULT: | 333 case UNKNOWN_DEFAULT: |
| 339 observer_->SetDefaultWebClientUIState(STATE_UNKNOWN); | 334 observer_->SetDefaultWebClientUIState(STATE_UNKNOWN); |
| 340 break; | 335 break; |
| 341 default: | 336 default: |
| 342 break; | 337 break; |
| 343 } | 338 } |
| 344 } | 339 } |
| 345 } | 340 } |
| 346 | 341 |
| 342 // static |
| 343 bool ShellIntegration::DefaultWebClientWorker::ShouldReportDurationForResult( |
| 344 AttemptResult result) { |
| 345 return result == SUCCESS || result == FAILURE || result == ABANDONED || |
| 346 result == RETRY; |
| 347 } |
| 348 |
| 349 // static |
| 350 const char* ShellIntegration::DefaultWebClientWorker::AttemptResultToString( |
| 351 AttemptResult result) { |
| 352 switch (result) { |
| 353 case SUCCESS: |
| 354 return "Success"; |
| 355 case ALREADY_DEFAULT: |
| 356 return "AlreadyDefault"; |
| 357 case FAILURE: |
| 358 return "Failure"; |
| 359 case ABANDONED: |
| 360 return "Abandoned"; |
| 361 case LAUNCH_FAILURE: |
| 362 return "LaunchFailure"; |
| 363 case OTHER_WORKER: |
| 364 return "OtherWorker"; |
| 365 case RETRY: |
| 366 return "Retry"; |
| 367 case NO_ERRORS_NOT_DEFAULT: |
| 368 return "NoErrorsNotDefault"; |
| 369 case NUM_ATTEMPT_RESULT_TYPES: |
| 370 break; |
| 371 } |
| 372 NOTREACHED(); |
| 373 return ""; |
| 374 } |
| 375 |
| 347 /////////////////////////////////////////////////////////////////////////////// | 376 /////////////////////////////////////////////////////////////////////////////// |
| 348 // ShellIntegration::DefaultBrowserWorker | 377 // ShellIntegration::DefaultBrowserWorker |
| 349 // | 378 // |
| 350 | 379 |
| 351 ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker( | 380 ShellIntegration::DefaultBrowserWorker::DefaultBrowserWorker( |
| 352 DefaultWebClientObserver* observer) | 381 DefaultWebClientObserver* observer) |
| 353 : DefaultWebClientWorker(observer) { | 382 : DefaultWebClientWorker(observer) { |
| 354 } | 383 } |
| 355 | 384 |
| 356 ShellIntegration::DefaultBrowserWorker::~DefaultBrowserWorker() {} | 385 ShellIntegration::DefaultBrowserWorker::~DefaultBrowserWorker() {} |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 401 NOTREACHED(); | 430 NOTREACHED(); |
| 402 break; | 431 break; |
| 403 #endif | 432 #endif |
| 404 } | 433 } |
| 405 BrowserThread::PostTask( | 434 BrowserThread::PostTask( |
| 406 BrowserThread::UI, FROM_HERE, | 435 BrowserThread::UI, FROM_HERE, |
| 407 base::Bind(&DefaultBrowserWorker::OnSetAsDefaultAttemptComplete, this, | 436 base::Bind(&DefaultBrowserWorker::OnSetAsDefaultAttemptComplete, this, |
| 408 result)); | 437 result)); |
| 409 } | 438 } |
| 410 | 439 |
| 440 const char* ShellIntegration::DefaultBrowserWorker::GetHistogramPrefix() { |
| 441 return "DefaultBrowser"; |
| 442 } |
| 443 |
| 411 /////////////////////////////////////////////////////////////////////////////// | 444 /////////////////////////////////////////////////////////////////////////////// |
| 412 // ShellIntegration::DefaultProtocolClientWorker | 445 // ShellIntegration::DefaultProtocolClientWorker |
| 413 // | 446 // |
| 414 | 447 |
| 415 ShellIntegration::DefaultProtocolClientWorker::DefaultProtocolClientWorker( | 448 ShellIntegration::DefaultProtocolClientWorker::DefaultProtocolClientWorker( |
| 416 DefaultWebClientObserver* observer, const std::string& protocol) | 449 DefaultWebClientObserver* observer, const std::string& protocol) |
| 417 : DefaultWebClientWorker(observer), | 450 : DefaultWebClientWorker(observer), |
| 418 protocol_(protocol) { | 451 protocol_(protocol) { |
| 419 } | 452 } |
| 420 | 453 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 450 break; | 483 break; |
| 451 case SET_DEFAULT_ASYNCHRONOUS: | 484 case SET_DEFAULT_ASYNCHRONOUS: |
| 452 NOTREACHED(); | 485 NOTREACHED(); |
| 453 break; | 486 break; |
| 454 } | 487 } |
| 455 BrowserThread::PostTask( | 488 BrowserThread::PostTask( |
| 456 BrowserThread::UI, FROM_HERE, | 489 BrowserThread::UI, FROM_HERE, |
| 457 base::Bind(&DefaultProtocolClientWorker::OnSetAsDefaultAttemptComplete, | 490 base::Bind(&DefaultProtocolClientWorker::OnSetAsDefaultAttemptComplete, |
| 458 this, result)); | 491 this, result)); |
| 459 } | 492 } |
| 493 |
| 494 const char* |
| 495 ShellIntegration::DefaultProtocolClientWorker::GetHistogramPrefix() { |
| 496 return "DefaultProtocolClient"; |
| 497 } |
| OLD | NEW |