1 /* 2 * Copyright (C) 2017, 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_API_GEN_COLLATION_H 18 #define ANDROID_STATS_LOG_API_GEN_COLLATION_H 19 20 #include <google/protobuf/descriptor.h> 21 #include <stdint.h> 22 23 #include <map> 24 #include <set> 25 #include <vector> 26 27 #include "frameworks/proto_logging/stats/atom_field_options.pb.h" 28 29 namespace android { 30 namespace stats_log_api_gen { 31 32 using google::protobuf::OneofDescriptor; 33 using google::protobuf::Descriptor; 34 using google::protobuf::FieldDescriptor; 35 using std::map; 36 using std::set; 37 using std::shared_ptr; 38 using std::string; 39 using std::vector; 40 41 const int PULL_ATOM_START_ID = 10000; 42 43 const int FIRST_UID_IN_CHAIN_ID = 0; 44 45 /** 46 * The types of oneof atoms. 47 * 48 * `OneofDescriptor::name()` returns the name of the oneof. 49 */ 50 const char ONEOF_PUSHED_ATOM_NAME[] = "pushed"; 51 const char ONEOF_PULLED_ATOM_NAME[] = "pulled"; 52 53 enum AtomType { 54 ATOM_TYPE_PUSHED, 55 ATOM_TYPE_PULLED 56 }; 57 58 enum AnnotationId : uint8_t { 59 ANNOTATION_ID_IS_UID = 1, 60 ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2, 61 ANNOTATION_ID_PRIMARY_FIELD = 3, 62 ANNOTATION_ID_EXCLUSIVE_STATE = 4, 63 ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5, 64 ANNOTATION_ID_DEFAULT_STATE = 6, 65 ANNOTATION_ID_TRIGGER_STATE_RESET = 7, 66 ANNOTATION_ID_STATE_NESTED = 8, 67 }; 68 69 const int ATOM_ID_FIELD_NUMBER = -1; 70 71 const char DEFAULT_MODULE_NAME[] = "DEFAULT"; 72 73 /** 74 * The types for atom parameters. 75 */ 76 typedef enum { 77 JAVA_TYPE_UNKNOWN_OR_INVALID = 0, 78 79 JAVA_TYPE_ATTRIBUTION_CHAIN = 1, 80 JAVA_TYPE_BOOLEAN = 2, 81 JAVA_TYPE_INT = 3, 82 JAVA_TYPE_LONG = 4, 83 JAVA_TYPE_FLOAT = 5, 84 JAVA_TYPE_DOUBLE = 6, 85 JAVA_TYPE_STRING = 7, 86 JAVA_TYPE_ENUM = 8, 87 JAVA_TYPE_BOOLEAN_ARRAY = 10, 88 JAVA_TYPE_INT_ARRAY = 11, 89 JAVA_TYPE_LONG_ARRAY = 12, 90 JAVA_TYPE_FLOAT_ARRAY = 13, 91 JAVA_TYPE_DOUBLE_ARRAY = 14, 92 JAVA_TYPE_STRING_ARRAY = 15, 93 JAVA_TYPE_ENUM_ARRAY = 16, 94 95 JAVA_TYPE_OBJECT = -1, 96 JAVA_TYPE_BYTE_ARRAY = -2, 97 } java_type_t; 98 99 enum AnnotationType { 100 ANNOTATION_TYPE_UNKNOWN = 0, 101 ANNOTATION_TYPE_INT = 1, 102 ANNOTATION_TYPE_BOOL = 2, 103 }; 104 105 union AnnotationValue { 106 int intValue; 107 bool boolValue; 108 AnnotationValue(const int value)109 explicit AnnotationValue(const int value) : intValue(value) { 110 } AnnotationValue(const bool value)111 explicit AnnotationValue(const bool value) : boolValue(value) { 112 } 113 }; 114 115 struct Annotation { 116 const AnnotationId annotationId; 117 const int atomId; 118 AnnotationType type; 119 AnnotationValue value; 120 AnnotationAnnotation121 inline Annotation(AnnotationId annotationId, int atomId, AnnotationType type, 122 AnnotationValue value) 123 : annotationId(annotationId), atomId(atomId), type(type), value(value) { 124 } ~AnnotationAnnotation125 inline ~Annotation() { 126 } 127 128 inline bool operator<(const Annotation& that) const { 129 return atomId == that.atomId ? annotationId < that.annotationId : atomId < that.atomId; 130 } 131 }; 132 133 struct SharedComparator { 134 template <typename T> operatorSharedComparator135 inline bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const { 136 return (*lhs) < (*rhs); 137 } 138 }; 139 140 using AnnotationSet = set<shared_ptr<Annotation>, SharedComparator>; 141 142 using FieldNumberToAnnotations = map<int, AnnotationSet>; 143 144 /** 145 * The name and type for an atom field. 146 */ 147 struct AtomField { 148 string name; 149 java_type_t javaType; 150 151 // If the field is of type enum, the following map contains the list of enum 152 // values. 153 map<int /* numeric value */, string /* value name */> enumValues; 154 AtomFieldAtomField155 inline AtomField() : name(), javaType(JAVA_TYPE_UNKNOWN_OR_INVALID) { 156 } AtomFieldAtomField157 inline AtomField(const AtomField& that) 158 : name(that.name), javaType(that.javaType), enumValues(that.enumValues) { 159 } 160 AtomFieldAtomField161 inline AtomField(string n, java_type_t jt) : name(n), javaType(jt) { 162 } ~AtomFieldAtomField163 inline ~AtomField() { 164 } 165 }; 166 167 /** 168 * The name and code for an atom. 169 */ 170 struct AtomDecl { 171 int code; 172 string name; 173 174 string message; 175 vector<AtomField> fields; 176 177 AtomType atomType; 178 179 FieldNumberToAnnotations fieldNumberToAnnotations; 180 181 vector<int> primaryFields; 182 int exclusiveField = 0; 183 int defaultState = INT_MAX; 184 int triggerStateReset = INT_MAX; 185 bool nested = true; 186 187 AtomDecl(); 188 AtomDecl(const AtomDecl& that); 189 AtomDecl(int code, const string& name, const string& message, AtomType atomType); 190 ~AtomDecl(); 191 192 inline bool operator<(const AtomDecl& that) const { 193 return (code == that.code) ? (name < that.name) : (code < that.code); 194 } 195 }; 196 197 using AtomDeclSet = set<shared_ptr<AtomDecl>, SharedComparator>; 198 199 // Maps a field number to a set of atoms that have annotation(s) for their field with that field 200 // number. 201 using FieldNumberToAtomDeclSet = map<int, AtomDeclSet>; 202 203 using SignatureInfoMap = map<vector<java_type_t>, FieldNumberToAtomDeclSet>; 204 205 struct Atoms { 206 SignatureInfoMap signatureInfoMap; 207 SignatureInfoMap pulledAtomsSignatureInfoMap; 208 AtomDeclSet decls; 209 AtomDeclSet non_chained_decls; 210 SignatureInfoMap nonChainedSignatureInfoMap; 211 }; 212 213 /** 214 * Gather the information about the atoms. Returns the number of errors. 215 */ 216 int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms); 217 int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature); 218 219 } // namespace stats_log_api_gen 220 } // namespace android 221 222 #endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H 223