blob: 8c1cb514fbb078bb67ad5085370bbffccaf263ee [file] [log] [blame]
ergb9210582015-05-09 03:52:16 +09001// 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 "mojo/services/tracing/tracing_app.h"
6
7#include "base/bind.h"
8#include "base/message_loop/message_loop.h"
9#include "mojo/services/tracing/trace_data_sink.h"
10#include "third_party/mojo/src/mojo/public/cpp/application/application_connection.h"
11
12namespace tracing {
13
14class CollectorImpl : public TraceDataCollector {
15 public:
16 CollectorImpl(mojo::InterfaceRequest<TraceDataCollector> request,
17 TraceDataSink* sink)
18 : sink_(sink), binding_(this, request.Pass()) {}
19
20 ~CollectorImpl() override {}
21
22 // tracing::TraceDataCollector implementation.
23 void DataCollected(const mojo::String& json) override {
24 sink_->AddChunk(json.To<std::string>());
25 }
26
27 private:
28 TraceDataSink* sink_;
29 mojo::Binding<TraceDataCollector> binding_;
30
31 DISALLOW_COPY_AND_ASSIGN(CollectorImpl);
32};
33
34TracingApp::TracingApp() {}
35
36TracingApp::~TracingApp() {}
37
38bool TracingApp::ConfigureIncomingConnection(
39 mojo::ApplicationConnection* connection) {
40 connection->AddService<TraceCoordinator>(this);
41
42 // If someone connects to us they may want to use the TraceCoordinator
43 // interface and/or they may want to expose themselves to be traced. Attempt
44 // to connect to the TraceController interface to see if the application
45 // connecting to us wants to be traced. They can refuse the connection or
46 // close the pipe if not.
47 TraceControllerPtr controller_ptr;
48 connection->ConnectToService(&controller_ptr);
49 controller_ptrs_.AddInterfacePtr(controller_ptr.Pass());
50 return true;
51}
52
53void TracingApp::Create(
54 mojo::ApplicationConnection* connection,
55 mojo::InterfaceRequest<TraceCoordinator> request) {
56 coordinator_bindings_.AddBinding(this, request.Pass());
57}
58
59void TracingApp::Start(mojo::ScopedDataPipeProducerHandle stream,
60 const mojo::String& categories) {
61 sink_.reset(new TraceDataSink(stream.Pass()));
62 controller_ptrs_.ForAllPtrs(
63 [categories, this](TraceController* controller) {
64 TraceDataCollectorPtr ptr;
65 collector_impls_.push_back(
66 new CollectorImpl(GetProxy(&ptr), sink_.get()));
67 controller->StartTracing(categories, ptr.Pass());
68 });
69}
70
71void TracingApp::StopAndFlush() {
72 controller_ptrs_.ForAllPtrs(
73 [](TraceController* controller) { controller->StopTracing(); });
74
75 // TODO: We really should keep track of how many connections we have here
76 // and flush + reset the sink after we receive a EndTracing or a detect a
77 // pipe closure on all pipes.
78 base::MessageLoop::current()->PostDelayedTask(
79 FROM_HERE,
80 base::Bind(&TracingApp::AllDataCollected, base::Unretained(this)),
81 base::TimeDelta::FromSeconds(1));
82}
83
84void TracingApp::AllDataCollected() {
85 collector_impls_.clear();
86 sink_->Flush();
87}
88
89} // namespace tracing