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.
5 #include "mojo/services/tracing/tracing_app.h"
8 #include "base/message_loop/message_loop.h"
9 #include "mojo/application/public/cpp/application_connection.h"
10 #include "mojo/services/tracing/trace_data_sink.h"
14 class CollectorImpl
: public TraceDataCollector
{
16 CollectorImpl(mojo::InterfaceRequest
<TraceDataCollector
> request
,
18 : sink_(sink
), binding_(this, request
.Pass()) {}
20 ~CollectorImpl() override
{}
22 // tracing::TraceDataCollector implementation.
23 void DataCollected(const mojo::String
& json
) override
{
24 sink_
->AddChunk(json
.To
<std::string
>());
29 mojo::Binding
<TraceDataCollector
> binding_
;
31 DISALLOW_COPY_AND_ASSIGN(CollectorImpl
);
34 TracingApp::TracingApp() {}
36 TracingApp::~TracingApp() {}
38 bool TracingApp::ConfigureIncomingConnection(
39 mojo::ApplicationConnection
* connection
) {
40 connection
->AddService
<TraceCoordinator
>(this);
41 connection
->AddService
<StartupPerformanceDataCollector
>(this);
43 // If someone connects to us they may want to use the TraceCoordinator
44 // interface and/or they may want to expose themselves to be traced. Attempt
45 // to connect to the TraceController interface to see if the application
46 // connecting to us wants to be traced. They can refuse the connection or
47 // close the pipe if not.
48 TraceControllerPtr controller_ptr
;
49 connection
->ConnectToService(&controller_ptr
);
51 controller_ptrs_
.AddInterfacePtr(controller_ptr
.Pass());
55 void TracingApp::Create(
56 mojo::ApplicationConnection
* connection
,
57 mojo::InterfaceRequest
<TraceCoordinator
> request
) {
58 coordinator_bindings_
.AddBinding(this, request
.Pass());
61 void TracingApp::Create(
62 mojo::ApplicationConnection
* connection
,
63 mojo::InterfaceRequest
<StartupPerformanceDataCollector
> request
) {
64 startup_performance_data_collector_bindings_
.AddBinding(this, request
.Pass());
67 void TracingApp::Start(mojo::ScopedDataPipeProducerHandle stream
,
68 const mojo::String
& categories
) {
69 sink_
.reset(new TraceDataSink(stream
.Pass()));
70 controller_ptrs_
.ForAllPtrs(
71 [categories
, this](TraceController
* controller
) {
72 TraceDataCollectorPtr ptr
;
73 collector_impls_
.push_back(
74 new CollectorImpl(GetProxy(&ptr
), sink_
.get()));
75 controller
->StartTracing(categories
, ptr
.Pass());
79 void TracingApp::StopAndFlush() {
80 controller_ptrs_
.ForAllPtrs(
81 [](TraceController
* controller
) { controller
->StopTracing(); });
83 // TODO: We really should keep track of how many connections we have here
84 // and flush + reset the sink after we receive a EndTracing or a detect a
85 // pipe closure on all pipes.
86 base::MessageLoop::current()->PostDelayedTask(
88 base::Bind(&TracingApp::AllDataCollected
, base::Unretained(this)),
89 base::TimeDelta::FromSeconds(1));
92 void TracingApp::SetShellProcessCreationTime(int64 time
) {
93 if (startup_performance_times_
.shell_process_creation_time
== 0)
94 startup_performance_times_
.shell_process_creation_time
= time
;
97 void TracingApp::SetShellMainEntryPointTime(int64 time
) {
98 if (startup_performance_times_
.shell_main_entry_point_time
== 0)
99 startup_performance_times_
.shell_main_entry_point_time
= time
;
102 void TracingApp::SetBrowserMessageLoopStartTime(int64 time
) {
103 if (startup_performance_times_
.browser_message_loop_start_time
== 0)
104 startup_performance_times_
.browser_message_loop_start_time
= time
;
107 void TracingApp::SetBrowserWindowDisplayTime(int64 time
) {
108 if (startup_performance_times_
.browser_window_display_time
== 0)
109 startup_performance_times_
.browser_window_display_time
= time
;
112 void TracingApp::SetBrowserOpenTabsTimeDelta(int64 delta
) {
113 if (startup_performance_times_
.browser_open_tabs_time_delta
== 0)
114 startup_performance_times_
.browser_open_tabs_time_delta
= delta
;
117 void TracingApp::SetFirstWebContentsMainFrameLoadTime(int64 time
) {
118 if (startup_performance_times_
.first_web_contents_main_frame_load_time
== 0)
119 startup_performance_times_
.first_web_contents_main_frame_load_time
= time
;
122 void TracingApp::SetFirstVisuallyNonEmptyLayoutTime(int64 time
) {
123 if (startup_performance_times_
.first_visually_non_empty_layout_time
== 0)
124 startup_performance_times_
.first_visually_non_empty_layout_time
= time
;
127 void TracingApp::GetStartupPerformanceTimes(
128 const GetStartupPerformanceTimesCallback
& callback
) {
129 callback
.Run(startup_performance_times_
.Clone());
132 void TracingApp::AllDataCollected() {
133 collector_impls_
.clear();
137 } // namespace tracing