blob: bb1ce348520721bd4a6a6907956b0c37c833e649 [file] [log] [blame]
Vijay Venkatramane15a3b12017-01-25 18:52:17 +00001/*
2 * Copyright (C) 2005-2016 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 _LIBS_LOG_EVENT_LIST_H
18#define _LIBS_LOG_EVENT_LIST_H
19
Mark Salyzyn084d3922017-04-13 08:19:52 -070020#include <errno.h>
Vijay Venkatramane15a3b12017-01-25 18:52:17 +000021#include <stdint.h>
22
23#if (defined(__cplusplus) && defined(_USING_LIBCXX))
24extern "C++" {
25#include <string>
26}
27#endif
28
29#include <log/log.h>
30
31#ifdef __cplusplus
32extern "C" {
33#endif
34
35#ifndef __ANDROID_USE_LIBLOG_EVENT_INTERFACE
36#ifndef __ANDROID_API__
37#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1
38#elif __ANDROID_API__ > 23 /* > Marshmallow */
39#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1
40#else
41#define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 0
42#endif
43#endif
44
45#if __ANDROID_USE_LIBLOG_EVENT_INTERFACE
46
47/* For manipulating lists of events. */
48
49#define ANDROID_MAX_LIST_NEST_DEPTH 8
50
51/*
52 * The opaque context used to manipulate lists of events.
53 */
54#ifndef __android_log_context_defined
55#define __android_log_context_defined
56typedef struct android_log_context_internal* android_log_context;
57#endif
58
59/*
60 * Elements returned when reading a list of events.
61 */
62#ifndef __android_log_list_element_defined
63#define __android_log_list_element_defined
64typedef struct {
Mark Salyzyna2d59f82017-03-09 08:09:43 -080065 AndroidEventLogType type;
66 uint16_t complete;
67 uint16_t len;
68 union {
69 int32_t int32;
70 int64_t int64;
71 char* string;
72 float float32;
73 } data;
Vijay Venkatramane15a3b12017-01-25 18:52:17 +000074} android_log_list_element;
75#endif
76
77/*
78 * Creates a context associated with an event tag to write elements to
79 * the list of events.
80 */
81android_log_context create_android_logger(uint32_t tag);
82
83/* All lists must be braced by a begin and end call */
84/*
85 * NB: If the first level braces are missing when specifying multiple
86 * elements, we will manufacturer a list to embrace it for your API
87 * convenience. For a single element, it will remain solitary.
88 */
89int android_log_write_list_begin(android_log_context ctx);
90int android_log_write_list_end(android_log_context ctx);
91
92int android_log_write_int32(android_log_context ctx, int32_t value);
93int android_log_write_int64(android_log_context ctx, int64_t value);
94int android_log_write_string8(android_log_context ctx, const char* value);
Mark Salyzyna2d59f82017-03-09 08:09:43 -080095int android_log_write_string8_len(android_log_context ctx, const char* value,
96 size_t maxlen);
Vijay Venkatramane15a3b12017-01-25 18:52:17 +000097int android_log_write_float32(android_log_context ctx, float value);
98
99/* Submit the composed list context to the specified logger id */
100/* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */
101int android_log_write_list(android_log_context ctx, log_id_t id);
102
103/*
104 * Creates a context from a raw buffer representing a list of events to be read.
105 */
106android_log_context create_android_log_parser(const char* msg, size_t len);
107
108android_log_list_element android_log_read_next(android_log_context ctx);
109android_log_list_element android_log_peek_next(android_log_context ctx);
110
111/* Finished with reader or writer context */
112int android_log_destroy(android_log_context* ctx);
113
114#ifdef __cplusplus
115#ifndef __class_android_log_event_list_defined
116#define __class_android_log_event_list_defined
117/* android_log_list C++ helpers */
118extern "C++" {
119class android_log_event_list {
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800120 friend class __android_log_event_list;
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000121
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800122 private:
123 android_log_context ctx;
124 int ret;
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000125
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800126 android_log_event_list(const android_log_event_list&) = delete;
127 void operator=(const android_log_event_list&) = delete;
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000128
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800129 public:
130 explicit android_log_event_list(int tag) : ret(0) {
131 ctx = create_android_logger(static_cast<uint32_t>(tag));
132 }
133 explicit android_log_event_list(log_msg& log_msg) : ret(0) {
134 ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t),
135 log_msg.entry.len - sizeof(uint32_t));
136 }
137 ~android_log_event_list() {
138 android_log_destroy(&ctx);
139 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000140
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800141 int close() {
142 int retval = android_log_destroy(&ctx);
143 if (retval < 0) ret = retval;
144 return retval;
145 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000146
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800147 /* To allow above C calls to use this class as parameter */
148 operator android_log_context() const {
149 return ctx;
150 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000151
Mark Salyzyn084d3922017-04-13 08:19:52 -0700152 /* return errors or transmit status */
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800153 int status() const {
154 return ret;
155 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000156
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800157 int begin() {
158 int retval = android_log_write_list_begin(ctx);
159 if (retval < 0) ret = retval;
160 return ret;
161 }
162 int end() {
163 int retval = android_log_write_list_end(ctx);
164 if (retval < 0) ret = retval;
165 return ret;
166 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000167
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800168 android_log_event_list& operator<<(int32_t value) {
169 int retval = android_log_write_int32(ctx, value);
170 if (retval < 0) ret = retval;
171 return *this;
172 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000173
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800174 android_log_event_list& operator<<(uint32_t value) {
175 int retval = android_log_write_int32(ctx, static_cast<int32_t>(value));
176 if (retval < 0) ret = retval;
177 return *this;
178 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000179
Mark Salyzyn7ecb9e92017-06-05 07:47:29 -0700180 android_log_event_list& operator<<(bool value) {
181 int retval = android_log_write_int32(ctx, value ? 1 : 0);
182 if (retval < 0) ret = retval;
183 return *this;
184 }
185
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800186 android_log_event_list& operator<<(int64_t value) {
187 int retval = android_log_write_int64(ctx, value);
188 if (retval < 0) ret = retval;
189 return *this;
190 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000191
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800192 android_log_event_list& operator<<(uint64_t value) {
193 int retval = android_log_write_int64(ctx, static_cast<int64_t>(value));
194 if (retval < 0) ret = retval;
195 return *this;
196 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000197
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800198 android_log_event_list& operator<<(const char* value) {
199 int retval = android_log_write_string8(ctx, value);
200 if (retval < 0) ret = retval;
201 return *this;
202 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000203
204#if defined(_USING_LIBCXX)
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800205 android_log_event_list& operator<<(const std::string& value) {
206 int retval =
207 android_log_write_string8_len(ctx, value.data(), value.length());
208 if (retval < 0) ret = retval;
209 return *this;
210 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000211#endif
212
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800213 android_log_event_list& operator<<(float value) {
214 int retval = android_log_write_float32(ctx, value);
215 if (retval < 0) ret = retval;
216 return *this;
217 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000218
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800219 int write(log_id_t id = LOG_ID_EVENTS) {
Mark Salyzyn084d3922017-04-13 08:19:52 -0700220 /* facilitate -EBUSY retry */
221 if ((ret == -EBUSY) || (ret > 0)) ret = 0;
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800222 int retval = android_log_write_list(ctx, id);
Mark Salyzyn084d3922017-04-13 08:19:52 -0700223 /* existing errors trump transmission errors */
224 if (!ret) ret = retval;
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800225 return ret;
226 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000227
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800228 int operator<<(log_id_t id) {
Mark Salyzyn084d3922017-04-13 08:19:52 -0700229 write(id);
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800230 android_log_destroy(&ctx);
231 return ret;
232 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000233
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800234 /*
235 * Append<Type> methods removes any integer promotion
236 * confusion, and adds access to string with length.
237 * Append methods are also added for all types for
238 * convenience.
239 */
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000240
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800241 bool AppendInt(int32_t value) {
242 int retval = android_log_write_int32(ctx, value);
243 if (retval < 0) ret = retval;
244 return ret >= 0;
245 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000246
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800247 bool AppendLong(int64_t value) {
248 int retval = android_log_write_int64(ctx, value);
249 if (retval < 0) ret = retval;
250 return ret >= 0;
251 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000252
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800253 bool AppendString(const char* value) {
254 int retval = android_log_write_string8(ctx, value);
255 if (retval < 0) ret = retval;
256 return ret >= 0;
257 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000258
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800259 bool AppendString(const char* value, size_t len) {
260 int retval = android_log_write_string8_len(ctx, value, len);
261 if (retval < 0) ret = retval;
262 return ret >= 0;
263 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000264
265#if defined(_USING_LIBCXX)
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800266 bool AppendString(const std::string& value) {
267 int retval =
268 android_log_write_string8_len(ctx, value.data(), value.length());
269 if (retval < 0) ret = retval;
270 return ret;
271 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000272
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800273 bool Append(const std::string& value) {
274 int retval =
275 android_log_write_string8_len(ctx, value.data(), value.length());
276 if (retval < 0) ret = retval;
277 return ret;
278 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000279#endif
280
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800281 bool AppendFloat(float value) {
282 int retval = android_log_write_float32(ctx, value);
283 if (retval < 0) ret = retval;
284 return ret >= 0;
285 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000286
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800287 template <typename Tvalue>
288 bool Append(Tvalue value) {
289 *this << value;
290 return ret >= 0;
291 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000292
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800293 bool Append(const char* value, size_t len) {
294 int retval = android_log_write_string8_len(ctx, value, len);
295 if (retval < 0) ret = retval;
296 return ret >= 0;
297 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000298
Mark Salyzyna2d59f82017-03-09 08:09:43 -0800299 android_log_list_element read() {
300 return android_log_read_next(ctx);
301 }
302 android_log_list_element peek() {
303 return android_log_peek_next(ctx);
304 }
Vijay Venkatramane15a3b12017-01-25 18:52:17 +0000305};
306}
307#endif
308#endif
309
310#endif /* __ANDROID_USE_LIBLOG_EVENT_INTERFACE */
311
312#ifdef __cplusplus
313}
314#endif
315
316#endif /* _LIBS_LOG_EVENT_LIST_H */