1// Copyright 2014 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/mac/mac_startup_profiler.h"
6
7#include "base/logging.h"
8#include "base/metrics/histogram.h"
9#include "components/startup_metric_utils/startup_metric_utils.h"
10
11// static
12MacStartupProfiler* MacStartupProfiler::GetInstance() {
13  return Singleton<MacStartupProfiler>::get();
14}
15
16MacStartupProfiler::MacStartupProfiler() : recorded_metrics_(false) {
17}
18
19MacStartupProfiler::~MacStartupProfiler() {
20}
21
22void MacStartupProfiler::Profile(Location location) {
23  profiled_times_[location] = base::Time::Now();
24}
25
26void MacStartupProfiler::RecordMetrics() {
27  const base::Time* main_entry_time =
28      startup_metric_utils::MainEntryPointTime();
29  DCHECK(main_entry_time);
30  DCHECK(!recorded_metrics_);
31
32  recorded_metrics_ = true;
33
34  for (std::map<Location, base::Time>::const_iterator it =
35           profiled_times_.begin();
36       it != profiled_times_.end();
37       ++it) {
38    const base::Time& location_time = it->second;
39    base::TimeDelta delta = location_time - *main_entry_time;
40    RecordHistogram(it->first, delta);
41  }
42}
43
44const std::string MacStartupProfiler::HistogramName(Location location) {
45  std::string prefix("Startup.OSX.");
46  switch (location) {
47    case PRE_MAIN_MESSAGE_LOOP_START:
48      return prefix + "PreMainMessageLoopStart";
49    case AWAKE_FROM_NIB:
50      return prefix + "AwakeFromNib";
51    case POST_MAIN_MESSAGE_LOOP_START:
52      return prefix + "PostMainMessageLoopStart";
53    case PRE_PROFILE_INIT:
54      return prefix + "PreProfileInit";
55    case POST_PROFILE_INIT:
56      return prefix + "PostProfileInit";
57    case WILL_FINISH_LAUNCHING:
58      return prefix + "WillFinishLaunching";
59    case DID_FINISH_LAUNCHING:
60      return prefix + "DockIconWillFinishBouncing";
61  }
62}
63
64void MacStartupProfiler::RecordHistogram(Location location,
65                                         const base::TimeDelta& delta) {
66  const std::string name(HistogramName(location));
67  base::TimeDelta min = base::TimeDelta::FromMilliseconds(10);
68  base::TimeDelta max = base::TimeDelta::FromMinutes(1);
69  int bucket_count = 100;
70
71  // No need to cache the histogram pointers, since each invocation of this
72  // method will be the first and only usage of a histogram with that given
73  // name.
74  base::HistogramBase* histogram = base::Histogram::FactoryTimeGet(
75      name,
76      min,
77      max,
78      bucket_count,
79      base::HistogramBase::kUmaTargetedHistogramFlag);
80  histogram->AddTime(delta);
81}
82