1 /*
2  * Copyright (C) 2018 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 #define DEBUG false
18 #include "Log.h"
19 #include "FieldValue.h"
20 #include "HashableDimensionKey.h"
21 
22 namespace android {
23 namespace os {
24 namespace statsd {
25 
getEncodedField(int32_t pos[],int32_t depth,bool includeDepth)26 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
27     int32_t field = 0;
28     for (int32_t i = 0; i <= depth; i++) {
29         int32_t shiftBits = 8 * (kMaxLogDepth - i);
30         field |= (pos[i] << shiftBits);
31     }
32 
33     if (includeDepth) {
34         field |= (depth << 24);
35     }
36     return field;
37 }
38 
encodeMatcherMask(int32_t mask[],int32_t depth)39 int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
40     return getEncodedField(mask, depth, false) | 0xff000000;
41 }
42 
matches(const Matcher & matcher) const43 bool Field::matches(const Matcher& matcher) const {
44     if (mTag != matcher.mMatcher.getTag()) {
45         return false;
46     }
47     if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
48         return true;
49     }
50 
51     if (matcher.hasAllPositionMatcher() &&
52         (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
53         return true;
54     }
55 
56     return false;
57 }
58 
translateFieldMatcher(int tag,const FieldMatcher & matcher,int depth,int * pos,int * mask,std::vector<Matcher> * output)59 void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
60                            std::vector<Matcher>* output) {
61     if (depth > kMaxLogDepth) {
62         ALOGE("depth > 2");
63         return;
64     }
65 
66     pos[depth] = matcher.field();
67     mask[depth] = 0x7f;
68 
69     if (matcher.has_position()) {
70         depth++;
71         if (depth > 2) {
72             return;
73         }
74         switch (matcher.position()) {
75             case Position::ALL:
76                 pos[depth] = 0x00;
77                 mask[depth] = 0x7f;
78                 break;
79             case Position::ANY:
80                 pos[depth] = 0;
81                 mask[depth] = 0;
82                 break;
83             case Position::FIRST:
84                 pos[depth] = 1;
85                 mask[depth] = 0x7f;
86                 break;
87             case Position::LAST:
88                 pos[depth] = 0x80;
89                 mask[depth] = 0x80;
90                 break;
91             case Position::POSITION_UNKNOWN:
92                 pos[depth] = 0;
93                 mask[depth] = 0;
94                 break;
95         }
96     }
97 
98     if (matcher.child_size() == 0) {
99         output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
100     } else {
101         for (const auto& child : matcher.child()) {
102             translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
103         }
104     }
105 }
106 
translateFieldMatcher(const FieldMatcher & matcher,std::vector<Matcher> * output)107 void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
108     int pos[] = {1, 1, 1};
109     int mask[] = {0x7f, 0x7f, 0x7f};
110     int tag = matcher.field();
111     for (const auto& child : matcher.child()) {
112         translateFieldMatcher(tag, child, 0, pos, mask, output);
113     }
114 }
115 
isAttributionUidField(const FieldValue & value)116 bool isAttributionUidField(const FieldValue& value) {
117     int field = value.mField.getField() & 0xff007f;
118     if (field == 0x10001 && value.mValue.getType() == INT) {
119         return true;
120     }
121     return false;
122 }
123 
isAttributionUidField(const Field & field,const Value & value)124 bool isAttributionUidField(const Field& field, const Value& value) {
125     int f = field.getField() & 0xff007f;
126     if (f == 0x10001 && value.getType() == INT) {
127         return true;
128     }
129     return false;
130 }
131 
Value(const Value & from)132 Value::Value(const Value& from) {
133     type = from.getType();
134     switch (type) {
135         case INT:
136             int_value = from.int_value;
137             break;
138         case LONG:
139             long_value = from.long_value;
140             break;
141         case FLOAT:
142             float_value = from.float_value;
143             break;
144         case STRING:
145             str_value = from.str_value;
146             break;
147         default:
148             break;
149     }
150 }
151 
toString() const152 std::string Value::toString() const {
153     switch (type) {
154         case INT:
155             return std::to_string(int_value) + "[I]";
156         case LONG:
157             return std::to_string(long_value) + "[L]";
158         case FLOAT:
159             return std::to_string(float_value) + "[F]";
160         case STRING:
161             return str_value + "[S]";
162         default:
163             return "[UNKNOWN]";
164     }
165 }
166 
operator ==(const Value & that) const167 bool Value::operator==(const Value& that) const {
168     if (type != that.getType()) return false;
169 
170     switch (type) {
171         case INT:
172             return int_value == that.int_value;
173         case LONG:
174             return long_value == that.long_value;
175         case FLOAT:
176             return float_value == that.float_value;
177         case STRING:
178             return str_value == that.str_value;
179         default:
180             return false;
181     }
182 }
183 
operator !=(const Value & that) const184 bool Value::operator!=(const Value& that) const {
185     if (type != that.getType()) return true;
186     switch (type) {
187         case INT:
188             return int_value != that.int_value;
189         case LONG:
190             return long_value != that.long_value;
191         case FLOAT:
192             return float_value != that.float_value;
193         case STRING:
194             return str_value != that.str_value;
195         default:
196             return false;
197     }
198 }
199 
operator <(const Value & that) const200 bool Value::operator<(const Value& that) const {
201     if (type != that.getType()) return type < that.getType();
202 
203     switch (type) {
204         case INT:
205             return int_value < that.int_value;
206         case LONG:
207             return long_value < that.long_value;
208         case FLOAT:
209             return float_value < that.float_value;
210         case STRING:
211             return str_value < that.str_value;
212         default:
213             return false;
214     }
215 }
216 
equalDimensions(const std::vector<Matcher> & dimension_a,const std::vector<Matcher> & dimension_b)217 bool equalDimensions(const std::vector<Matcher>& dimension_a,
218                      const std::vector<Matcher>& dimension_b) {
219     bool eq = dimension_a.size() == dimension_b.size();
220     for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
221         if (dimension_b[i] != dimension_a[i]) {
222             eq = false;
223         }
224     }
225     return eq;
226 }
227 
HasPositionANY(const FieldMatcher & matcher)228 bool HasPositionANY(const FieldMatcher& matcher) {
229     if (matcher.has_position() && matcher.position() == Position::ANY) {
230         return true;
231     }
232     for (const auto& child : matcher.child()) {
233         if (HasPositionANY(child)) {
234             return true;
235         }
236     }
237     return false;
238 }
239 
HasPositionALL(const FieldMatcher & matcher)240 bool HasPositionALL(const FieldMatcher& matcher) {
241     if (matcher.has_position() && matcher.position() == Position::ALL) {
242         return true;
243     }
244     for (const auto& child : matcher.child()) {
245         if (HasPositionALL(child)) {
246             return true;
247         }
248     }
249     return false;
250 }
251 
252 }  // namespace statsd
253 }  // namespace os
254 }  // namespace android