Home | History | Annotate | Download | only in log
      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