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/base/cmds/statsd/src/atom_field_options.pb.h" 28 29 namespace android { 30 namespace stats_log_api_gen { 31 32 using google::protobuf::Descriptor; 33 using google::protobuf::FieldDescriptor; 34 using std::map; 35 using std::set; 36 using std::shared_ptr; 37 using std::string; 38 using std::vector; 39 40 const int PULL_ATOM_START_ID = 10000; 41 42 const int FIRST_UID_IN_CHAIN_ID = 0; 43 44 enum AnnotationId : uint8_t { 45 ANNOTATION_ID_IS_UID = 1, 46 ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2, 47 ANNOTATION_ID_PRIMARY_FIELD = 3, 48 ANNOTATION_ID_EXCLUSIVE_STATE = 4, 49 ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5, 50 ANNOTATION_ID_DEFAULT_STATE = 6, 51 ANNOTATION_ID_TRIGGER_STATE_RESET = 7, 52 ANNOTATION_ID_STATE_NESTED = 8, 53 }; 54 55 const int ATOM_ID_FIELD_NUMBER = -1; 56 57 const string DEFAULT_MODULE_NAME = "DEFAULT"; 58 59 /** 60 * The types for atom parameters. 61 */ 62 typedef enum { 63 JAVA_TYPE_UNKNOWN = 0, 64 65 JAVA_TYPE_ATTRIBUTION_CHAIN = 1, 66 JAVA_TYPE_BOOLEAN = 2, 67 JAVA_TYPE_INT = 3, 68 JAVA_TYPE_LONG = 4, 69 JAVA_TYPE_FLOAT = 5, 70 JAVA_TYPE_DOUBLE = 6, 71 JAVA_TYPE_STRING = 7, 72 JAVA_TYPE_ENUM = 8, 73 JAVA_TYPE_KEY_VALUE_PAIR = 9, 74 75 JAVA_TYPE_OBJECT = -1, 76 JAVA_TYPE_BYTE_ARRAY = -2, 77 } java_type_t; 78 79 enum AnnotationType { 80 ANNOTATION_TYPE_UNKNOWN = 0, 81 ANNOTATION_TYPE_INT = 1, 82 ANNOTATION_TYPE_BOOL = 2, 83 }; 84 85 union AnnotationValue { 86 int intValue; 87 bool boolValue; 88 AnnotationValue(const int value)89 AnnotationValue(const int value) : intValue(value) { 90 } AnnotationValue(const bool value)91 AnnotationValue(const bool value) : boolValue(value) { 92 } 93 }; 94 95 struct Annotation { 96 const AnnotationId annotationId; 97 const int atomId; 98 AnnotationType type; 99 AnnotationValue value; 100 AnnotationAnnotation101 inline Annotation(AnnotationId annotationId, int atomId, AnnotationType type, 102 AnnotationValue value) 103 : annotationId(annotationId), atomId(atomId), type(type), value(value) { 104 } ~AnnotationAnnotation105 inline ~Annotation() { 106 } 107 108 inline bool operator<(const Annotation& that) const { 109 return atomId == that.atomId ? annotationId < that.annotationId : atomId < that.atomId; 110 } 111 }; 112 113 struct SharedComparator { 114 template <typename T> operatorSharedComparator115 inline bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const { 116 return (*lhs) < (*rhs); 117 } 118 }; 119 120 using AnnotationSet = set<shared_ptr<Annotation>, SharedComparator>; 121 122 using FieldNumberToAnnotations = map<int, AnnotationSet>; 123 124 /** 125 * The name and type for an atom field. 126 */ 127 struct AtomField { 128 string name; 129 java_type_t javaType; 130 131 // If the field is of type enum, the following map contains the list of enum 132 // values. 133 map<int /* numeric value */, string /* value name */> enumValues; 134 AtomFieldAtomField135 inline AtomField() : name(), javaType(JAVA_TYPE_UNKNOWN) { 136 } AtomFieldAtomField137 inline AtomField(const AtomField& that) 138 : name(that.name), javaType(that.javaType), enumValues(that.enumValues) { 139 } 140 AtomFieldAtomField141 inline AtomField(string n, java_type_t jt) : name(n), javaType(jt) { 142 } ~AtomFieldAtomField143 inline ~AtomField() { 144 } 145 }; 146 147 /** 148 * The name and code for an atom. 149 */ 150 struct AtomDecl { 151 int code; 152 string name; 153 154 string message; 155 vector<AtomField> fields; 156 157 FieldNumberToAnnotations fieldNumberToAnnotations; 158 159 vector<int> primaryFields; 160 int exclusiveField = 0; 161 int defaultState = INT_MAX; 162 int triggerStateReset = INT_MAX; 163 bool nested = true; 164 165 int uidField = 0; 166 167 AtomDecl(); 168 AtomDecl(const AtomDecl& that); 169 AtomDecl(int code, const string& name, const string& message); 170 ~AtomDecl(); 171 172 inline bool operator<(const AtomDecl& that) const { 173 return (code == that.code) ? (name < that.name) : (code < that.code); 174 } 175 }; 176 177 using AtomDeclSet = set<shared_ptr<AtomDecl>, SharedComparator>; 178 179 // Maps a field number to a set of atoms that have annotation(s) for their field with that field 180 // number. 181 using FieldNumberToAtomDeclSet = map<int, AtomDeclSet>; 182 183 using SignatureInfoMap = map<vector<java_type_t>, FieldNumberToAtomDeclSet>; 184 185 struct Atoms { 186 SignatureInfoMap signatureInfoMap; 187 AtomDeclSet decls; 188 AtomDeclSet non_chained_decls; 189 SignatureInfoMap nonChainedSignatureInfoMap; 190 }; 191 192 /** 193 * Gather the information about the atoms. Returns the number of errors. 194 */ 195 int collate_atoms(const Descriptor* descriptor, const string& moduleName, Atoms* atoms); 196 int collate_atom(const Descriptor* atom, AtomDecl* atomDecl, vector<java_type_t>* signature); 197 198 } // namespace stats_log_api_gen 199 } // namespace android 200 201 #endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H 202