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 * struct stats_event* event = stats_event_obtain(); 30 * 31 * stats_event_set_atom_id(event, atomId); 32 * stats_event_write_int32(event, 24); 33 * stats_event_add_bool_annotation(event, 1, true); // annotations apply to the previous field 34 * stats_event_add_int32_annotation(event, 2, 128); 35 * stats_event_write_float(event, 2.0); 36 * 37 * stats_event_build(event); 38 * stats_event_write(event); 39 * stats_event_release(event); 40 * 41 * Notes: 42 * (a) write_<type>() and add_<type>_annotation() should be called in the order that fields 43 * and annotations are defined in the atom. 44 * (b) set_atom_id() can be called anytime before stats_event_write(). 45 * (c) add_<type>_annotation() calls apply to the previous field. 46 * (d) If errors occur, stats_event_write() will write a bitmask of the errors to the socket. 47 * (e) All strings should be encoded using UTF8. 48 */ 49 50 /* ERRORS */ 51 #define ERROR_NO_TIMESTAMP 0x1 52 #define ERROR_NO_ATOM_ID 0x2 53 #define ERROR_OVERFLOW 0x4 54 #define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8 55 #define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10 56 #define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20 57 #define ERROR_INVALID_ANNOTATION_ID 0x40 58 #define ERROR_ANNOTATION_ID_TOO_LARGE 0x80 59 #define ERROR_TOO_MANY_ANNOTATIONS 0x100 60 #define ERROR_TOO_MANY_FIELDS 0x200 61 #define ERROR_INVALID_VALUE_TYPE 0x400 62 #define ERROR_STRING_NOT_NULL_TERMINATED 0x800 63 64 /* TYPE IDS */ 65 #define INT32_TYPE 0x00 66 #define INT64_TYPE 0x01 67 #define STRING_TYPE 0x02 68 #define LIST_TYPE 0x03 69 #define FLOAT_TYPE 0x04 70 #define BOOL_TYPE 0x05 71 #define BYTE_ARRAY_TYPE 0x06 72 #define OBJECT_TYPE 0x07 73 #define KEY_VALUE_PAIRS_TYPE 0x08 74 #define ATTRIBUTION_CHAIN_TYPE 0x09 75 #define ERROR_TYPE 0x0F 76 77 #ifdef __cplusplus 78 extern "C" { 79 #endif // __CPLUSPLUS 80 81 struct stats_event; 82 83 /* SYSTEM API */ 84 struct stats_event* stats_event_obtain(); 85 // The build function can be called multiple times without error. If the event 86 // has been built before, this function is a no-op. 87 void stats_event_build(struct stats_event* event); 88 int stats_event_write(struct stats_event* event); 89 void stats_event_release(struct stats_event* event); 90 91 void stats_event_set_atom_id(struct stats_event* event, uint32_t atomId); 92 93 void stats_event_write_int32(struct stats_event* event, int32_t value); 94 void stats_event_write_int64(struct stats_event* event, int64_t value); 95 void stats_event_write_float(struct stats_event* event, float value); 96 void stats_event_write_bool(struct stats_event* event, bool value); 97 98 void stats_event_write_byte_array(struct stats_event* event, const uint8_t* buf, size_t numBytes); 99 100 // Buf must be null-terminated. 101 void stats_event_write_string8(struct stats_event* event, const char* value); 102 103 // Tags must be null-terminated. 104 void stats_event_write_attribution_chain(struct stats_event* event, const uint32_t* uids, 105 const char* const* tags, uint8_t numNodes); 106 107 /* key_value_pair struct can be constructed as follows: 108 * struct key_value_pair pair = {.key = key, .valueType = STRING_TYPE, 109 * .stringValue = buf}; 110 */ 111 struct key_value_pair { 112 int32_t key; 113 uint8_t valueType; // expected to be INT32_TYPE, INT64_TYPE, FLOAT_TYPE, or STRING_TYPE 114 union { 115 int32_t int32Value; 116 int64_t int64Value; 117 float floatValue; 118 const char* stringValue; // must be null terminated 119 }; 120 }; 121 122 void stats_event_write_key_value_pairs(struct stats_event* event, struct key_value_pair* pairs, 123 uint8_t numPairs); 124 125 void stats_event_add_bool_annotation(struct stats_event* event, uint8_t annotationId, bool value); 126 void stats_event_add_int32_annotation(struct stats_event* event, uint8_t annotationId, 127 int32_t value); 128 129 uint32_t stats_event_get_atom_id(struct stats_event* event); 130 // Size is an output parameter. 131 uint8_t* stats_event_get_buffer(struct stats_event* event, size_t* size); 132 uint32_t stats_event_get_errors(struct stats_event* event); 133 134 // This table is used by StatsEventCompat to access the stats_event API. 135 struct stats_event_api_table { 136 struct stats_event* (*obtain)(void); 137 void (*build)(struct stats_event*); 138 int (*write)(struct stats_event*); 139 void (*release)(struct stats_event*); 140 void (*set_atom_id)(struct stats_event*, uint32_t); 141 void (*write_int32)(struct stats_event*, int32_t); 142 void (*write_int64)(struct stats_event*, int64_t); 143 void (*write_float)(struct stats_event*, float); 144 void (*write_bool)(struct stats_event*, bool); 145 void (*write_byte_array)(struct stats_event*, const uint8_t*, size_t); 146 void (*write_string8)(struct stats_event*, const char*); 147 void (*write_attribution_chain)(struct stats_event*, const uint32_t*, const char* const*, 148 uint8_t); 149 void (*write_key_value_pairs)(struct stats_event*, struct key_value_pair*, uint8_t); 150 void (*add_bool_annotation)(struct stats_event*, uint8_t, bool); 151 void (*add_int32_annotation)(struct stats_event*, uint8_t, int32_t); 152 uint32_t (*get_atom_id)(struct stats_event*); 153 uint8_t* (*get_buffer)(struct stats_event*, size_t*); 154 uint32_t (*get_errors)(struct stats_event*); 155 }; 156 157 // exposed for benchmarking only 158 void stats_event_truncate_buffer(struct stats_event* event, bool truncate); 159 160 #ifdef __cplusplus 161 } 162 #endif // __CPLUSPLUS 163 164 #endif // ANDROID_STATS_LOG_STATS_EVENT_H 165