OLD | NEW |
| (Empty) |
1 // Copyright 2015 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 "components/html_viewer/stats_collection_controller.h" | |
6 | |
7 #include <utility> | |
8 | |
9 #include "base/command_line.h" | |
10 #include "base/memory/scoped_ptr.h" | |
11 #include "base/metrics/histogram.h" | |
12 #include "base/metrics/statistics_recorder.h" | |
13 #include "base/time/time.h" | |
14 #include "components/startup_metric_utils/browser/startup_metric_utils.h" | |
15 #include "gin/handle.h" | |
16 #include "gin/object_template_builder.h" | |
17 #include "mojo/services/tracing/public/cpp/switches.h" | |
18 #include "mojo/shell/public/cpp/shell.h" | |
19 #include "third_party/WebKit/public/web/WebKit.h" | |
20 #include "third_party/WebKit/public/web/WebLocalFrame.h" | |
21 | |
22 namespace html_viewer { | |
23 | |
24 namespace { | |
25 | |
26 // Initialize the histogram data using the given startup performance times. | |
27 void GetStartupPerformanceTimesCallbackImpl( | |
28 tracing::StartupPerformanceTimesPtr times) { | |
29 base::StatisticsRecorder::Initialize(); | |
30 | |
31 startup_metric_utils::RecordStartupProcessCreationTime( | |
32 base::Time::FromInternalValue(times->shell_process_creation_time)); | |
33 | |
34 // TODO(msw): Record the MojoMain() entry point time of mojo:browser instead? | |
35 startup_metric_utils::RecordMainEntryPointTime( | |
36 base::Time::FromInternalValue(times->shell_main_entry_point_time)); | |
37 | |
38 // TODO(msw): Determine if this is the first run and provide a PrefService | |
39 // to generate stats that span multiple startups. | |
40 startup_metric_utils::RecordBrowserMainMessageLoopStart( | |
41 base::TimeTicks::FromInternalValue( | |
42 times->browser_message_loop_start_ticks), | |
43 false, nullptr); | |
44 | |
45 startup_metric_utils::RecordBrowserWindowDisplay( | |
46 base::TimeTicks::FromInternalValue(times->browser_window_display_ticks)); | |
47 | |
48 startup_metric_utils::RecordBrowserOpenTabsDelta( | |
49 base::TimeDelta::FromInternalValue(times->browser_open_tabs_time_delta)); | |
50 | |
51 startup_metric_utils::RecordFirstWebContentsMainFrameLoad( | |
52 base::TimeTicks::FromInternalValue( | |
53 times->first_web_contents_main_frame_load_ticks)); | |
54 | |
55 startup_metric_utils::RecordFirstWebContentsNonEmptyPaint( | |
56 base::TimeTicks::FromInternalValue( | |
57 times->first_visually_non_empty_layout_ticks)); | |
58 } | |
59 | |
60 } // namespace | |
61 | |
62 // static | |
63 gin::WrapperInfo StatsCollectionController::kWrapperInfo = { | |
64 gin::kEmbedderNativeGin}; | |
65 | |
66 // static | |
67 tracing::StartupPerformanceDataCollectorPtr StatsCollectionController::Install( | |
68 blink::WebFrame* frame, | |
69 mojo::Shell* shell) { | |
70 // Only make startup tracing available when running in the context of a test. | |
71 if (!shell || | |
72 !base::CommandLine::ForCurrentProcess()->HasSwitch( | |
73 tracing::kEnableStatsCollectionBindings)) { | |
74 return nullptr; | |
75 } | |
76 | |
77 v8::Isolate* isolate = blink::mainThreadIsolate(); | |
78 v8::HandleScope handle_scope(isolate); | |
79 v8::Local<v8::Context> context = frame->mainWorldScriptContext(); | |
80 if (context.IsEmpty()) | |
81 return nullptr; | |
82 | |
83 v8::Context::Scope context_scope(context); | |
84 | |
85 scoped_ptr<mojo::Connection> connection = shell->Connect("mojo:tracing"); | |
86 if (!connection) | |
87 return nullptr; | |
88 tracing::StartupPerformanceDataCollectorPtr collector_for_controller; | |
89 tracing::StartupPerformanceDataCollectorPtr collector_for_caller; | |
90 connection->ConnectToService(&collector_for_controller); | |
91 connection->ConnectToService(&collector_for_caller); | |
92 | |
93 gin::Handle<StatsCollectionController> controller = gin::CreateHandle( | |
94 isolate, | |
95 new StatsCollectionController(std::move(collector_for_controller))); | |
96 DCHECK(!controller.IsEmpty()); | |
97 v8::Local<v8::Object> global = context->Global(); | |
98 global->Set(gin::StringToV8(isolate, "statsCollectionController"), | |
99 controller.ToV8()); | |
100 return collector_for_caller; | |
101 } | |
102 | |
103 // static | |
104 tracing::StartupPerformanceDataCollectorPtr | |
105 StatsCollectionController::ConnectToDataCollector(mojo::Shell* shell) { | |
106 // Only make startup tracing available when running in the context of a test. | |
107 if (!shell || | |
108 !base::CommandLine::ForCurrentProcess()->HasSwitch( | |
109 tracing::kEnableStatsCollectionBindings)) { | |
110 return nullptr; | |
111 } | |
112 | |
113 tracing::StartupPerformanceDataCollectorPtr collector; | |
114 shell->ConnectToService("mojo:tracing", &collector); | |
115 return collector; | |
116 } | |
117 | |
118 StatsCollectionController::StatsCollectionController( | |
119 tracing::StartupPerformanceDataCollectorPtr collector) | |
120 : startup_performance_data_collector_(std::move(collector)) {} | |
121 | |
122 StatsCollectionController::~StatsCollectionController() {} | |
123 | |
124 gin::ObjectTemplateBuilder StatsCollectionController::GetObjectTemplateBuilder( | |
125 v8::Isolate* isolate) { | |
126 return gin::Wrappable<StatsCollectionController>::GetObjectTemplateBuilder( | |
127 isolate) | |
128 .SetMethod("getHistogram", &StatsCollectionController::GetHistogram) | |
129 .SetMethod("getBrowserHistogram", | |
130 &StatsCollectionController::GetBrowserHistogram); | |
131 } | |
132 | |
133 std::string StatsCollectionController::GetHistogram( | |
134 const std::string& histogram_name) { | |
135 DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | |
136 tracing::kEnableStatsCollectionBindings)); | |
137 | |
138 static bool startup_histogram_initialized = false; | |
139 if (!startup_histogram_initialized) { | |
140 // Get the startup performance times from the tracing service. | |
141 auto callback = base::Bind(&GetStartupPerformanceTimesCallbackImpl); | |
142 startup_performance_data_collector_->GetStartupPerformanceTimes(callback); | |
143 startup_performance_data_collector_.WaitForIncomingResponse(); | |
144 DCHECK(base::StatisticsRecorder::IsActive()); | |
145 startup_histogram_initialized = true; | |
146 } | |
147 | |
148 std::string histogram_json = "{}"; | |
149 base::HistogramBase* histogram = | |
150 base::StatisticsRecorder::FindHistogram(histogram_name); | |
151 if (histogram) | |
152 histogram->WriteJSON(&histogram_json); | |
153 return histogram_json; | |
154 } | |
155 | |
156 std::string StatsCollectionController::GetBrowserHistogram( | |
157 const std::string& histogram_name) { | |
158 return GetHistogram(histogram_name); | |
159 } | |
160 | |
161 } // namespace html_viewer | |
OLD | NEW |