1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/diagnostics/diagnostics_controller.h" 6 7#include <string> 8 9#include "base/command_line.h" 10#include "base/logging.h" 11#include "base/memory/scoped_ptr.h" 12#include "base/metrics/histogram.h" 13#include "base/time/time.h" 14#include "chrome/browser/diagnostics/diagnostics_model.h" 15#include "chrome/browser/diagnostics/diagnostics_test.h" 16#include "chrome/browser/diagnostics/diagnostics_writer.h" 17#include "chrome/common/chrome_switches.h" 18 19#if defined(OS_CHROMEOS) 20#include "chromeos/chromeos_switches.h" 21#endif 22 23namespace diagnostics { 24 25DiagnosticsController* DiagnosticsController::GetInstance() { 26 return Singleton<DiagnosticsController>::get(); 27} 28 29DiagnosticsController::DiagnosticsController() : writer_(NULL) {} 30 31DiagnosticsController::~DiagnosticsController() {} 32 33const DiagnosticsModel& DiagnosticsController::GetResults() const { 34 return *model_; 35} 36 37bool DiagnosticsController::HasResults() { 38 return (model_.get() && model_->GetTestRunCount() > 0); 39} 40 41void DiagnosticsController::ClearResults() { model_.reset(); } 42 43void DiagnosticsController::RecordRegularStartup() { 44#if defined(OS_CHROMEOS) // Only collecting UMA stats on ChromeOS 45 // Count the number of normal starts, so we can compare that with the number 46 // of recovery runs to get a percentage. 47 UMA_HISTOGRAM_ENUMERATION( 48 "Diagnostics.RecoveryRun", RECOVERY_NOT_RUN, RECOVERY_RUN_METRICS_COUNT); 49 50 // For each of the test types, record a normal start (no diagnostics run), so 51 // we have a common denominator. 52 for (int i = 0; i < DIAGNOSTICS_TEST_ID_COUNT; ++i) { 53 RecordUMARecoveryResult(static_cast<DiagnosticsTestId>(i), RESULT_NOT_RUN); 54 RecordUMATestResult(static_cast<DiagnosticsTestId>(i), RESULT_NOT_RUN); 55 } 56#endif 57} 58 59// This entry point is called from early in startup when very few things have 60// been initialized, so be careful what you use. 61int DiagnosticsController::Run(const CommandLine& command_line, 62 DiagnosticsWriter* writer) { 63 writer_ = writer; 64 65 model_.reset(MakeDiagnosticsModel(command_line)); 66 model_->RunAll(writer_); 67 68 return 0; 69} 70 71// This entry point is called from early in startup when very few things have 72// been initialized, so be careful what you use. 73int DiagnosticsController::RunRecovery(const CommandLine& command_line, 74 DiagnosticsWriter* writer) { 75// Separate out recoveries that we execute automatically as a result of a 76// crash from user-run recoveries. 77#if defined(OS_CHROMEOS) // Only collecting UMA stats on ChromeOS 78 if (command_line.HasSwitch(chromeos::switches::kLoginUser)) { 79 UMA_HISTOGRAM_ENUMERATION("Diagnostics.RecoveryRun", 80 diagnostics::RECOVERY_CRASH_RUN, 81 diagnostics::RECOVERY_RUN_METRICS_COUNT); 82 } else { 83 UMA_HISTOGRAM_ENUMERATION("Diagnostics.RecoveryRun", 84 diagnostics::RECOVERY_USER_RUN, 85 diagnostics::RECOVERY_RUN_METRICS_COUNT); 86 } 87#endif 88 89 if (!HasResults()) { 90 if (writer) { 91 writer->WriteInfoLine("No diagnostics have been run."); 92 writer->OnAllRecoveryDone(model_.get()); 93 } 94 return -1; 95 } 96 97 writer_ = writer; 98 99 model_->RecoverAll(writer_); 100 return 0; 101} 102 103} // namespace diagnostics 104