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