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::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 /** 45 * The types of oneof atoms. 46 * 47 * `OneofDescriptor::name()` returns the name of the oneof. 48 */ 49 const char ONEOF_PUSHED_ATOM_NAME[] = "pushed"; 50 const char ONEOF_PULLED_ATOM_NAME[] = "pulled"; 51 52 enum AtomType { ATOM_TYPE_PUSHED, ATOM_TYPE_PULLED }; 53 54 enum AnnotationId : uint8_t { 55 ANNOTATION_ID_IS_UID = 1, 56 ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2, 57 ANNOTATION_ID_PRIMARY_FIELD = 3, 58 ANNOTATION_ID_EXCLUSIVE_STATE = 4, 59 ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5, 60 ANNOTATION_ID_DEFAULT_STATE = 6, 61 ANNOTATION_ID_TRIGGER_STATE_RESET = 7, 62 ANNOTATION_ID_STATE_NESTED = 8, 63 ANNOTATION_ID_RESTRICTION_CATEGORY = 9, 64 ANNOTATION_ID_FIELD_RESTRICTION_PERIPHERAL_DEVICE_INFO = 10, 65 ANNOTATION_ID_FIELD_RESTRICTION_APP_USAGE = 11, 66 ANNOTATION_ID_FIELD_RESTRICTION_APP_ACTIVITY = 12, 67 ANNOTATION_ID_FIELD_RESTRICTION_HEALTH_CONNECT = 13, 68 ANNOTATION_ID_FIELD_RESTRICTION_ACCESSIBILITY = 14, 69 ANNOTATION_ID_FIELD_RESTRICTION_SYSTEM_SEARCH = 15, 70 ANNOTATION_ID_FIELD_RESTRICTION_USER_ENGAGEMENT = 16, 71 ANNOTATION_ID_FIELD_RESTRICTION_AMBIENT_SENSING = 17, 72 ANNOTATION_ID_FIELD_RESTRICTION_DEMOGRAPHIC_CLASSIFICATION = 18, 73 }; 74 75 const int ATOM_ID_FIELD_NUMBER = -1; 76 77 const char DEFAULT_MODULE_NAME[] = "DEFAULT"; 78 79 const std::string UINT_ATOM_ALLOWLIST[22] = { 80 "AppDied", 81 "DevicePolicyEvent", 82 "NfcErrorOccurred", 83 "NfcHceTransactionOccurred", 84 "ScreenTimeoutExtensionReported", 85 "ThreadnetworkTelemetryDataReported", 86 "ThreadnetworkTopoEntryRepeated", 87 "SubsystemSleepState", 88 "BluetoothActivityInfo", 89 "CpuTimePerFreq", 90 "CpuTimePerUid", 91 "CpuTimePerUidFreq", 92 "WifiActivityInfo", 93 "ModemActivityInfo", 94 "SystemElapsedRealtime", 95 "SystemUptime", 96 "CpuActiveTime", 97 "CpuClusterTime", 98 "DiskSpace", 99 "OnDevicePowerMeasurement", 100 "GeneralExternalStorageAccessStats", 101 "CpuTimePerClusterFreq", 102 }; 103 104 /** 105 * The types for atom parameters. 106 */ 107 typedef enum { 108 JAVA_TYPE_UNKNOWN_OR_INVALID = 0, 109 110 JAVA_TYPE_ATTRIBUTION_CHAIN = 1, 111 JAVA_TYPE_BOOLEAN = 2, 112 JAVA_TYPE_INT = 3, 113 JAVA_TYPE_LONG = 4, 114 JAVA_TYPE_FLOAT = 5, 115 JAVA_TYPE_DOUBLE = 6, 116 JAVA_TYPE_STRING = 7, 117 JAVA_TYPE_ENUM = 8, 118 JAVA_TYPE_BOOLEAN_ARRAY = 10, 119 JAVA_TYPE_INT_ARRAY = 11, 120 JAVA_TYPE_LONG_ARRAY = 12, 121 JAVA_TYPE_FLOAT_ARRAY = 13, 122 JAVA_TYPE_DOUBLE_ARRAY = 14, 123 JAVA_TYPE_STRING_ARRAY = 15, 124 JAVA_TYPE_ENUM_ARRAY = 16, 125 126 JAVA_TYPE_OBJECT = -1, 127 JAVA_TYPE_BYTE_ARRAY = -2, 128 } java_type_t; 129 130 enum AnnotationType { 131 ANNOTATION_TYPE_UNKNOWN = 0, 132 ANNOTATION_TYPE_INT = 1, 133 ANNOTATION_TYPE_BOOL = 2, 134 }; 135 136 union AnnotationValue { 137 int intValue; 138 bool boolValue; 139 AnnotationValue(const int value)140 explicit AnnotationValue(const int value) : intValue(value) { 141 } AnnotationValue(const bool value)142 explicit AnnotationValue(const bool value) : boolValue(value) { 143 } 144 }; 145 146 struct Annotation { 147 const AnnotationId annotationId; 148 const int atomId; 149 AnnotationType type; 150 AnnotationValue value; 151 AnnotationAnnotation152 inline Annotation(AnnotationId annotationId, int atomId, AnnotationType type, 153 AnnotationValue value) 154 : annotationId(annotationId), atomId(atomId), type(type), value(value) { 155 } ~AnnotationAnnotation156 inline ~Annotation() { 157 } 158 159 inline bool operator<(const Annotation& that) const { 160 return atomId == that.atomId ? annotationId < that.annotationId : atomId < that.atomId; 161 } 162 }; 163 164 struct SharedComparator { 165 template <typename T> operatorSharedComparator166 inline bool operator()(const shared_ptr<T>& lhs, const shared_ptr<T>& rhs) const { 167 return (*lhs) < (*rhs); 168 } 169 }; 170 171 using AnnotationSet = set<shared_ptr<Annotation>, SharedComparator>; 172 173 using FieldNumberToAnnotations = map<int, AnnotationSet>; 174 175 using FieldNameToHistogramBinOption = map<std::string, os::statsd::HistogramBinOption>; 176 177 /** 178 * The name and type for an atom field. 179 */ 180 struct AtomField { 181 string name; 182 java_type_t javaType; 183 184 // If the field is of type enum, the following map contains the list of enum 185 // values. 186 map<int /* numeric value */, string /* value name */> enumValues; 187 // If the field is of type enum, the following field contains enum type name 188 string enumTypeName; 189 AtomFieldAtomField190 inline AtomField() : name(), javaType(JAVA_TYPE_UNKNOWN_OR_INVALID) { 191 } AtomFieldAtomField192 inline AtomField(const AtomField& that) 193 : name(that.name), 194 javaType(that.javaType), 195 enumValues(that.enumValues), 196 enumTypeName(that.enumTypeName) { 197 } 198 AtomFieldAtomField199 inline AtomField(string n, java_type_t jt) : name(n), javaType(jt) { 200 } ~AtomFieldAtomField201 inline ~AtomField() { 202 } 203 }; 204 205 /** 206 * The name and code for an atom. 207 */ 208 struct AtomDecl { 209 int code; 210 string name; 211 212 string message; 213 vector<AtomField> fields; 214 215 AtomType atomType; 216 217 FieldNumberToAnnotations fieldNumberToAnnotations; 218 FieldNameToHistogramBinOption fieldNameToHistBinOption; 219 220 vector<int> primaryFields; 221 int exclusiveField = 0; 222 int defaultState = INT_MAX; 223 int triggerStateReset = INT_MAX; 224 bool nested = true; 225 bool restricted = false; 226 227 AtomDecl(); 228 AtomDecl(const AtomDecl& that); 229 AtomDecl(int code, const string& name, const string& message, AtomType atomType); 230 ~AtomDecl(); 231 232 inline bool operator<(const AtomDecl& that) const { 233 return (code == that.code) ? (name < that.name) : (code < that.code); 234 } 235 }; 236 237 using AtomDeclSet = set<shared_ptr<AtomDecl>, SharedComparator>; 238 239 // Maps a field number to a set of atoms that have annotation(s) for their field with that field 240 // number. 241 using FieldNumberToAtomDeclSet = map<int, AtomDeclSet>; 242 243 using SignatureInfoMap = map<vector<java_type_t>, FieldNumberToAtomDeclSet>; 244 245 struct Atoms { 246 SignatureInfoMap signatureInfoMap; 247 SignatureInfoMap pulledAtomsSignatureInfoMap; 248 AtomDeclSet decls; 249 AtomDeclSet non_chained_decls; 250 SignatureInfoMap nonChainedSignatureInfoMap; 251 }; 252 253 /** 254 * Gather the information about the atoms. Returns the number of errors. 255 */ 256 int collate_atoms(const Descriptor& descriptor, const string& moduleName, Atoms& atoms); 257 int collate_atom(const Descriptor& atom, AtomDecl& atomDecl, vector<java_type_t>& signature); 258 259 } // namespace stats_log_api_gen 260 } // namespace android 261 262 #endif // ANDROID_STATS_LOG_API_GEN_COLLATION_H 263