1 /* 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 20 #include <errno.h> 21 #include <stdint.h> 22 23 #if (defined(__cplusplus) && defined(_USING_LIBCXX)) 24 extern "C++" { 25 #include <string> 26 } 27 #endif 28 29 #include <log/log.h> 30 31 #ifdef __cplusplus 32 extern "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 56 typedef 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 64 typedef struct { 65 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; 74 } 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 */ 81 android_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 */ 89 int android_log_write_list_begin(android_log_context ctx); 90 int android_log_write_list_end(android_log_context ctx); 91 92 int android_log_write_int32(android_log_context ctx, int32_t value); 93 int android_log_write_int64(android_log_context ctx, int64_t value); 94 int android_log_write_string8(android_log_context ctx, const char* value); 95 int android_log_write_string8_len(android_log_context ctx, const char* value, 96 size_t maxlen); 97 int 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 */ 101 int 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 */ 106 android_log_context create_android_log_parser(const char* msg, size_t len); 107 108 android_log_list_element android_log_read_next(android_log_context ctx); 109 android_log_list_element android_log_peek_next(android_log_context ctx); 110 111 /* Finished with reader or writer context */ 112 int 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 */ 118 extern "C++" { 119 class android_log_event_list { 120 friend class __android_log_event_list; 121 122 private: 123 android_log_context ctx; 124 int ret; 125 126 android_log_event_list(const android_log_event_list&) = delete; 127 void operator=(const android_log_event_list&) = delete; 128 129 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 } 140 141 int close() { 142 int retval = android_log_destroy(&ctx); 143 if (retval < 0) ret = retval; 144 return retval; 145 } 146 147 /* To allow above C calls to use this class as parameter */ 148 operator android_log_context() const { 149 return ctx; 150 } 151 152 /* return errors or transmit status */ 153 int status() const { 154 return ret; 155 } 156 157 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 } 167 168 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 } 173 174 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 } 179 180 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 186 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 } 191 192 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 } 197 198 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 } 203 204 #if defined(_USING_LIBCXX) 205 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 } 211 #endif 212 213 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 } 218 219 int write(log_id_t id = LOG_ID_EVENTS) { 220 /* facilitate -EBUSY retry */ 221 if ((ret == -EBUSY) || (ret > 0)) ret = 0; 222 int retval = android_log_write_list(ctx, id); 223 /* existing errors trump transmission errors */ 224 if (!ret) ret = retval; 225 return ret; 226 } 227 228 int operator<<(log_id_t id) { 229 write(id); 230 android_log_destroy(&ctx); 231 return ret; 232 } 233 234 /* 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 */ 240 241 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 } 246 247 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 } 252 253 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 } 258 259 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 } 264 265 #if defined(_USING_LIBCXX) 266 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 } 272 273 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 } 279 #endif 280 281 bool AppendFloat(float value) { 282 int retval = android_log_write_float32(ctx, value); 283 if (retval < 0) ret = retval; 284 return ret >= 0; 285 } 286 287 template <typename Tvalue> 288 bool Append(Tvalue value) { 289 *this << value; 290 return ret >= 0; 291 } 292 293 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 } 298 299 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 } 305 }; 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 */ 317