1 /*
2  * Copyright (C) 2019 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 ANDROID_STATS_LOG_STATS_EVENT_H
18 #define ANDROID_STATS_LOG_STATS_EVENT_H
19 
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 /*
25  * Functionality to build and store the buffer sent over the statsd socket.
26  * This code defines and encapsulates the socket protocol.
27  *
28  * Usage:
29  *      AStatsEvent* event = AStatsEvent_obtain();
30  *
31  *      AStatsEvent_setAtomId(event, atomId);
32  *      AStatsEvent_addBoolAnnotation(event, 5, false); // atom-level annotation
33  *      AStatsEvent_writeInt32(event, 24);
34  *      AStatsEvent_addBoolAnnotation(event, 1, true); // annotation for preceding atom field
35  *      AStatsEvent_addInt32Annotation(event, 2, 128);
36  *      AStatsEvent_writeFloat(event, 2.0);
37  *
38  *      AStatsEvent_write(event);
39  *      AStatsEvent_release(event);
40  *
41  * Note that calls to add atom fields and annotations should be made in the
42  * order that they are defined in the atom.
43  */
44 
45 #ifndef __ANDROID_API_T__
46 #define __ANDROID_API_T__ 33
47 #endif
48 
49 #ifndef __INTRODUCED_IN
50 #define __INTRODUCED_IN(api_level)
51 #endif
52 
53 #ifdef __cplusplus
54 extern "C" {
55 #endif  // __CPLUSPLUS
56 
57 /**
58  * Opaque struct use to represent a StatsEvent. It builds and stores the data that is sent to
59  * statsd.
60  */
61 struct AStatsEvent;
62 typedef struct AStatsEvent AStatsEvent;
63 
64 /**
65  * Returns a new AStatsEvent. If you call this function, you must call AStatsEvent_release to free
66  * the allocated memory.
67  */
68 AStatsEvent* AStatsEvent_obtain();
69 
70 /**
71  * Builds and finalizes the AStatsEvent for a pulled event.
72  * This should only be called for pulled AStatsEvents.
73  *
74  * After this function, the StatsEvent must not be modified in any way other than calling release or
75  * write.
76  *
77  * Build can be called multiple times without error.
78  * If the event has been built before, this function is a no-op.
79  */
80 void AStatsEvent_build(AStatsEvent* event);
81 
82 /**
83  * Writes the StatsEvent to the stats log.
84  * For all UIDs except system server:
85  * - Returns number of bytes written into the socket, or socket error code.
86  * For the system_server the write is done via intermediate queue:
87  * - Returns 1 if event was added into the queue, 0 otherwise.
88  *
89  * After calling this, AStatsEvent_release must be called,
90  * and is the only function that can be safely called.
91  */
92 int AStatsEvent_write(AStatsEvent* event);
93 
94 /**
95  * Frees the memory held by this StatsEvent.
96  *
97  * After calling this, the StatsEvent must not be used or modified in any way.
98  */
99 void AStatsEvent_release(AStatsEvent* event);
100 
101 /**
102  * Sets the atom id for this StatsEvent.
103  *
104  * This function should be called immediately after AStatsEvent_obtain. It may
105  * be called additional times as well, but subsequent calls will have no effect.
106  **/
107 void AStatsEvent_setAtomId(AStatsEvent* event, uint32_t atomId);
108 
109 /**
110  * Writes an int32_t field to this StatsEvent.
111  **/
112 void AStatsEvent_writeInt32(AStatsEvent* event, int32_t value);
113 
114 /**
115  * Writes an int64_t field to this StatsEvent.
116  **/
117 void AStatsEvent_writeInt64(AStatsEvent* event, int64_t value);
118 
119 /**
120  * Writes a float field to this StatsEvent.
121  **/
122 void AStatsEvent_writeFloat(AStatsEvent* event, float value);
123 
124 /**
125  * Write a bool field to this StatsEvent.
126  **/
127 void AStatsEvent_writeBool(AStatsEvent* event, bool value);
128 
129 /**
130  * Write a byte array field to this StatsEvent.
131  **/
132 void AStatsEvent_writeByteArray(AStatsEvent* event, const uint8_t* buf, size_t numBytes);
133 
134 /**
135  * Write a string field to this StatsEvent.
136  *
137  * The string must be null-terminated.
138  **/
139 void AStatsEvent_writeString(AStatsEvent* event, const char* value);
140 
141 /**
142  * Write an attribution chain field to this StatsEvent.
143  *
144  * The sizes of uids and tags must be equal. The AttributionNode at position i is
145  * made up of uids[i] and tags[i].
146  *
147  * \param uids array of uids in the attribution chain.
148  * \param tags array of tags in the attribution chain. Each tag must be null-terminated.
149  * \param numNodes the number of AttributionNodes in the attribution chain. This is the length of
150  *                 the uids and the tags.
151  **/
152 void AStatsEvent_writeAttributionChain(AStatsEvent* event, const uint32_t* uids,
153                                        const char* const* tags, uint8_t numNodes);
154 
155 /**
156  * Write a int32 array field to this StatsEvent.
157  *
158  * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
159  * to StatsEvent.
160  **/
161 void AStatsEvent_writeInt32Array(AStatsEvent* event, const int32_t* elements, size_t numElements);
162 
163 /**
164  * Write a int64 array field to this StatsEvent.
165  *
166  * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
167  * to StatsEvent.
168  **/
169 void AStatsEvent_writeInt64Array(AStatsEvent* event, const int64_t* elements, size_t numElements);
170 
171 /**
172  * Write a float array field to this StatsEvent.
173  *
174  * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
175  * to StatsEvent.
176  **/
177 void AStatsEvent_writeFloatArray(AStatsEvent* event, const float* elements, size_t numElements);
178 
179 /**
180  * Write a bool array field to this StatsEvent.
181  *
182  * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
183  * to StatsEvent.
184  **/
185 void AStatsEvent_writeBoolArray(AStatsEvent* event, const bool* elements, size_t numElements);
186 
187 /**
188  * Write a string array field to this StatsEvent.
189  *
190  * String array encoding is UTF8.
191  *
192  * Strings must be null terminated. Max size of array is 127. If exceeded, array is not written and
193  * ERROR_LIST_TOO_LONG is appended to StatsEvent.
194  **/
195 void AStatsEvent_writeStringArray(AStatsEvent* event, const char* const* elements,
196                                   size_t numElements);
197 
198 /**
199  * Write a bool annotation for the previous field written.
200  **/
201 void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, bool value);
202 
203 /**
204  * Write an integer annotation for the previous field written.
205  **/
206 void AStatsEvent_addInt32Annotation(AStatsEvent* event, uint8_t annotationId, int32_t value);
207 
208 // Internal/test APIs. Should not be exposed outside of the APEX.
209 void AStatsEvent_overwriteTimestamp(AStatsEvent* event, uint64_t timestampNs);
210 uint32_t AStatsEvent_getAtomId(AStatsEvent* event);
211 // Size is an output parameter.
212 uint8_t* AStatsEvent_getBuffer(AStatsEvent* event, size_t* size);
213 uint32_t AStatsEvent_getErrors(AStatsEvent* event);
214 
215 #ifdef __cplusplus
216 }
217 #endif  // __CPLUSPLUS
218 
219 #endif  // ANDROID_STATS_LOG_STATS_EVENT_H
220