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