1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_PUBLIC_CONSUMER_API_H_
18 #define INCLUDE_PERFETTO_PUBLIC_CONSUMER_API_H_
19 
20 #include <stddef.h>
21 #include <stdint.h>
22 
23 // Public API for perfetto consumer, exposed to the rest of the Android tree.
24 
25 namespace perfetto {
26 namespace consumer {
27 
28 // State diagram (without error states):
29 // +-------------+
30 // | kConnecting |----------------------------+
31 // +-------------+                            | Create(deferred_start:true)
32 //        |  Create(deferred_start:false)     V
33 //        |                            +-------------+
34 //        |                            | kConfigured |
35 //        |                            +-------------+
36 //        |                                   |
37 //        V                                   | StartTracing()
38 //   +----------+                             |
39 //   | kTracing |<----------------------------+
40 //   +----------+
41 //        |
42 //        | [after TraceConfig.duration_ms]
43 //        V
44 // +-------------+
45 // | kTraceEnded |
46 // +-------------+
47 enum class State {
48   // The trace session failed (e.g. the trace config is malformed or mmap
49   // failed). Look at logcat -s perfetto to find out more.
50   // This state is final and unrecoverable. The sessions needs to be destroyed
51   // and recreated if this error happens.
52   kTraceFailed = -3,
53 
54   // Failed to connect to the traced daemon.
55   // This state is final and unrecoverable. The sessions needs to be destroyed
56   // and recreated if this error happens.
57   kConnectionError = -2,
58 
59   // Not really a state. This is only returned when an invalid handle is passed
60   // to PollState().
61   kSessionNotFound = -1,
62 
63   // Idle state.
64   // This state is transitional an internal-only. Client will never see it.
65   kIdle = 0,
66 
67   // Establishing the connection to the traced daemon.
68   // This state is transitional. It is set soon after the Create() call and
69   // transitions automatically to:
70   // - kConfigured, if |deferred_start| == true in the trace config.
71   // - kTracing, if |deferred_start| == false.
72   // - An error state, e.g. if cannot reach the traced daemon.
73   kConnecting = 1,
74 
75   // Tracing configured (buffers allocated) but not started.
76   // This state is reached only when setting |deferred_start| == true and is
77   // held until the client calls StartTracing().
78   kConfigured = 2,
79 
80   // Tracing is active.
81   // This state lasts for the whole duration of the trace session (i.e.
82   // |duration_ms| in the trace config), after which the session transitions
83   // either to the kTraceEnded state (if successful) or an error state.
84   kTracing = 3,
85 
86   // Tracing ended succesfully. The trace buffer can now be retrieved through
87   // the ReadTrace() call.
88   // This state is final.
89   kTraceEnded = 4,
90 };
91 
92 using Handle = int64_t;
93 constexpr Handle kInvalidHandle = -1;
94 
95 // Signature for callback function provided by the embedder to get notified
96 // about state changes.
97 using OnStateChangedCb = void (*)(Handle, State, void* /*callback_arg*/);
98 
99 // None of the calls below are blocking, unless otherwise specified.
100 
101 // Enables tracing with the given TraceConfig. If the trace config has the
102 // |deferred_start| flag set (see trace_config.proto) tracing is initialized
103 // but not started. An explicit call to StartTracing() must be issued in order
104 // to start the capture.
105 // Args:
106 //   [trace_config_proto, trace_config_len] point to a binary-encoded proto
107 //     containing the trace config. See //external/perfetto/docs/trace-config.md
108 //     for more details.
109 //   callback: a user-defined callback that will be invoked upon state changes.
110 //     The callback will be invoked on an internal thread and must not block.
111 //   callback_arg: an optional user-define argument that will be passed back to
112 //     all callback invocations.
113 // Return value:
114 //    Returns a handle that can be used to retrieve the trace or kInvalidHandle
115 //    in case of failure (e.g., the trace config is malformed).
116 Handle Create(const void* config_proto,
117               size_t config_len,
118               OnStateChangedCb callback,
119               void* callback_arg);
120 
121 // Starts recording the trace. Can be used only when setting the
122 // |deferred_start| flag in the trace config passed to Create().
123 // If the session is in the kConfigured state it transitions it to the kTracing
124 // state, starting the trace. In any other state, instead, it does nothing other
125 // than logging an error message. Hence, this method can be called only once.
126 // The estimated end-to-end (this call to ftrace enabling) latency is 2-3 ms
127 // on a Pixel 2.
128 // TODO(primiano): relax this and allow to recycle handles without
129 // re-configuring the trace session.
130 void StartTracing(Handle);
131 
132 struct TraceBuffer {
133   char* begin;
134   size_t size;
135 };
136 
137 // Retrieves the whole trace buffer. It avoids extra copies by directly mmaping
138 // the tmp fd passed to the traced daemon.
139 // Return value:
140 //   If the trace is ended (state == kTraceEnded) returns a buffer containing
141 //   the whole trace. This buffer can be parsed directly with libprotobuf.
142 //   The buffer lifetime is tied to the tracing session and is valid until the
143 //   Destroy() call.
144 //   If called before the session reaches the kTraceEnded state, a null buffer
145 //   is returned.
146 TraceBuffer ReadTrace(Handle);
147 
148 // Destroys all the resources associated to the tracing session (connection to
149 // traced and trace buffer). The handle must not be used after this point.
150 // It's safe to call this regardless of the handle's current state and validity.
151 void Destroy(Handle);
152 
153 // Returns the state of the tracing session (for debugging).
154 // Return value:
155 //   Returns the state of the session, if the handle is valid, otherwise returns
156 //   kSessionNotFound.
157 State PollState(Handle);
158 
159 }  // namespace consumer
160 }  // namespace perfetto
161 
162 #endif  // INCLUDE_PERFETTO_PUBLIC_CONSUMER_API_H_
163