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