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 <stdint.h> 21 22 #if (defined(__cplusplus) && defined(_USING_LIBCXX)) 23 extern "C++" { 24 #include <string> 25 } 26 #endif 27 28 #include <log/log.h> 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #ifndef __ANDROID_USE_LIBLOG_EVENT_INTERFACE 35 #ifndef __ANDROID_API__ 36 #define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1 37 #elif __ANDROID_API__ > 23 /* > Marshmallow */ 38 #define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 1 39 #else 40 #define __ANDROID_USE_LIBLOG_EVENT_INTERFACE 0 41 #endif 42 #endif 43 44 #if __ANDROID_USE_LIBLOG_EVENT_INTERFACE 45 46 /* For manipulating lists of events. */ 47 48 #define ANDROID_MAX_LIST_NEST_DEPTH 8 49 50 /* 51 * The opaque context used to manipulate lists of events. 52 */ 53 #ifndef __android_log_context_defined 54 #define __android_log_context_defined 55 typedef struct android_log_context_internal* android_log_context; 56 #endif 57 58 /* 59 * Elements returned when reading a list of events. 60 */ 61 #ifndef __android_log_list_element_defined 62 #define __android_log_list_element_defined 63 typedef struct { 64 AndroidEventLogType type; 65 uint16_t complete; 66 uint16_t len; 67 union { 68 int32_t int32; 69 int64_t int64; 70 char* string; 71 float float32; 72 } data; 73 } android_log_list_element; 74 #endif 75 76 /* 77 * Creates a context associated with an event tag to write elements to 78 * the list of events. 79 */ 80 android_log_context create_android_logger(uint32_t tag); 81 82 /* All lists must be braced by a begin and end call */ 83 /* 84 * NB: If the first level braces are missing when specifying multiple 85 * elements, we will manufacturer a list to embrace it for your API 86 * convenience. For a single element, it will remain solitary. 87 */ 88 int android_log_write_list_begin(android_log_context ctx); 89 int android_log_write_list_end(android_log_context ctx); 90 91 int android_log_write_int32(android_log_context ctx, int32_t value); 92 int android_log_write_int64(android_log_context ctx, int64_t value); 93 int android_log_write_string8(android_log_context ctx, const char* value); 94 int android_log_write_string8_len(android_log_context ctx, const char* value, 95 size_t maxlen); 96 int android_log_write_float32(android_log_context ctx, float value); 97 98 /* Submit the composed list context to the specified logger id */ 99 /* NB: LOG_ID_EVENTS and LOG_ID_SECURITY only valid binary buffers */ 100 int android_log_write_list(android_log_context ctx, log_id_t id); 101 102 /* 103 * Creates a context from a raw buffer representing a list of events to be read. 104 */ 105 android_log_context create_android_log_parser(const char* msg, size_t len); 106 107 android_log_list_element android_log_read_next(android_log_context ctx); 108 android_log_list_element android_log_peek_next(android_log_context ctx); 109 110 /* Finished with reader or writer context */ 111 int android_log_destroy(android_log_context* ctx); 112 113 #ifdef __cplusplus 114 #ifndef __class_android_log_event_list_defined 115 #define __class_android_log_event_list_defined 116 /* android_log_list C++ helpers */ 117 extern "C++" { 118 class android_log_event_list { 119 friend class __android_log_event_list; 120 121 private: 122 android_log_context ctx; 123 int ret; 124 125 android_log_event_list(const android_log_event_list&) = delete; 126 void operator=(const android_log_event_list&) = delete; 127 128 public: android_log_event_list(int tag)129 explicit android_log_event_list(int tag) : ret(0) { 130 ctx = create_android_logger(static_cast<uint32_t>(tag)); 131 } android_log_event_list(log_msg & log_msg)132 explicit android_log_event_list(log_msg& log_msg) : ret(0) { 133 ctx = create_android_log_parser(log_msg.msg() + sizeof(uint32_t), 134 log_msg.entry.len - sizeof(uint32_t)); 135 } ~android_log_event_list()136 ~android_log_event_list() { 137 android_log_destroy(&ctx); 138 } 139 close()140 int close() { 141 int retval = android_log_destroy(&ctx); 142 if (retval < 0) ret = retval; 143 return retval; 144 } 145 146 /* To allow above C calls to use this class as parameter */ android_log_context()147 operator android_log_context() const { 148 return ctx; 149 } 150 status()151 int status() const { 152 return ret; 153 } 154 begin()155 int begin() { 156 int retval = android_log_write_list_begin(ctx); 157 if (retval < 0) ret = retval; 158 return ret; 159 } end()160 int end() { 161 int retval = android_log_write_list_end(ctx); 162 if (retval < 0) ret = retval; 163 return ret; 164 } 165 166 android_log_event_list& operator<<(int32_t value) { 167 int retval = android_log_write_int32(ctx, value); 168 if (retval < 0) ret = retval; 169 return *this; 170 } 171 172 android_log_event_list& operator<<(uint32_t value) { 173 int retval = android_log_write_int32(ctx, static_cast<int32_t>(value)); 174 if (retval < 0) ret = retval; 175 return *this; 176 } 177 178 android_log_event_list& operator<<(int64_t value) { 179 int retval = android_log_write_int64(ctx, value); 180 if (retval < 0) ret = retval; 181 return *this; 182 } 183 184 android_log_event_list& operator<<(uint64_t value) { 185 int retval = android_log_write_int64(ctx, static_cast<int64_t>(value)); 186 if (retval < 0) ret = retval; 187 return *this; 188 } 189 190 android_log_event_list& operator<<(const char* value) { 191 int retval = android_log_write_string8(ctx, value); 192 if (retval < 0) ret = retval; 193 return *this; 194 } 195 196 #if defined(_USING_LIBCXX) 197 android_log_event_list& operator<<(const std::string& value) { 198 int retval = 199 android_log_write_string8_len(ctx, value.data(), value.length()); 200 if (retval < 0) ret = retval; 201 return *this; 202 } 203 #endif 204 205 android_log_event_list& operator<<(float value) { 206 int retval = android_log_write_float32(ctx, value); 207 if (retval < 0) ret = retval; 208 return *this; 209 } 210 211 int write(log_id_t id = LOG_ID_EVENTS) { 212 int retval = android_log_write_list(ctx, id); 213 if (retval < 0) ret = retval; 214 return ret; 215 } 216 217 int operator<<(log_id_t id) { 218 int retval = android_log_write_list(ctx, id); 219 if (retval < 0) ret = retval; 220 android_log_destroy(&ctx); 221 return ret; 222 } 223 224 /* 225 * Append<Type> methods removes any integer promotion 226 * confusion, and adds access to string with length. 227 * Append methods are also added for all types for 228 * convenience. 229 */ 230 AppendInt(int32_t value)231 bool AppendInt(int32_t value) { 232 int retval = android_log_write_int32(ctx, value); 233 if (retval < 0) ret = retval; 234 return ret >= 0; 235 } 236 AppendLong(int64_t value)237 bool AppendLong(int64_t value) { 238 int retval = android_log_write_int64(ctx, value); 239 if (retval < 0) ret = retval; 240 return ret >= 0; 241 } 242 AppendString(const char * value)243 bool AppendString(const char* value) { 244 int retval = android_log_write_string8(ctx, value); 245 if (retval < 0) ret = retval; 246 return ret >= 0; 247 } 248 AppendString(const char * value,size_t len)249 bool AppendString(const char* value, size_t len) { 250 int retval = android_log_write_string8_len(ctx, value, len); 251 if (retval < 0) ret = retval; 252 return ret >= 0; 253 } 254 255 #if defined(_USING_LIBCXX) AppendString(const std::string & value)256 bool AppendString(const std::string& value) { 257 int retval = 258 android_log_write_string8_len(ctx, value.data(), value.length()); 259 if (retval < 0) ret = retval; 260 return ret; 261 } 262 Append(const std::string & value)263 bool Append(const std::string& value) { 264 int retval = 265 android_log_write_string8_len(ctx, value.data(), value.length()); 266 if (retval < 0) ret = retval; 267 return ret; 268 } 269 #endif 270 AppendFloat(float value)271 bool AppendFloat(float value) { 272 int retval = android_log_write_float32(ctx, value); 273 if (retval < 0) ret = retval; 274 return ret >= 0; 275 } 276 277 template <typename Tvalue> Append(Tvalue value)278 bool Append(Tvalue value) { 279 *this << value; 280 return ret >= 0; 281 } 282 Append(const char * value,size_t len)283 bool Append(const char* value, size_t len) { 284 int retval = android_log_write_string8_len(ctx, value, len); 285 if (retval < 0) ret = retval; 286 return ret >= 0; 287 } 288 read()289 android_log_list_element read() { 290 return android_log_read_next(ctx); 291 } peek()292 android_log_list_element peek() { 293 return android_log_peek_next(ctx); 294 } 295 }; 296 } 297 #endif 298 #endif 299 300 #endif /* __ANDROID_USE_LIBLOG_EVENT_INTERFACE */ 301 302 #ifdef __cplusplus 303 } 304 #endif 305 306 #endif /* _LIBS_LOG_EVENT_LIST_H */ 307