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 #include "math.h"
22 
23 namespace android {
24 namespace os {
25 namespace statsd {
26 
getEncodedField(int32_t pos[],int32_t depth,bool includeDepth)27 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
28     int32_t field = 0;
29     for (int32_t i = 0; i <= depth; i++) {
30         int32_t shiftBits = 8 * (kMaxLogDepth - i);
31         field |= (pos[i] << shiftBits);
32     }
33 
34     if (includeDepth) {
35         field |= (depth << 24);
36     }
37     return field;
38 }
39 
encodeMatcherMask(int32_t mask[],int32_t depth)40 int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
41     return getEncodedField(mask, depth, false) | 0xff000000;
42 }
43 
matches(const Matcher & matcher) const44 bool Field::matches(const Matcher& matcher) const {
45     if (mTag != matcher.mMatcher.getTag()) {
46         return false;
47     }
48     if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
49         return true;
50     }
51 
52     if (matcher.hasAllPositionMatcher() &&
53         (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
54         return true;
55     }
56 
57     return false;
58 }
59 
translateFieldMatcher(int tag,const FieldMatcher & matcher,int depth,int * pos,int * mask,std::vector<Matcher> * output)60 void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
61                            std::vector<Matcher>* output) {
62     if (depth > kMaxLogDepth) {
63         ALOGE("depth > 2");
64         return;
65     }
66 
67     pos[depth] = matcher.field();
68     mask[depth] = 0x7f;
69 
70     if (matcher.has_position()) {
71         depth++;
72         if (depth > 2) {
73             return;
74         }
75         switch (matcher.position()) {
76             case Position::ALL:
77                 pos[depth] = 0x00;
78                 mask[depth] = 0x7f;
79                 break;
80             case Position::ANY:
81                 pos[depth] = 0;
82                 mask[depth] = 0;
83                 break;
84             case Position::FIRST:
85                 pos[depth] = 1;
86                 mask[depth] = 0x7f;
87                 break;
88             case Position::LAST:
89                 pos[depth] = 0x80;
90                 mask[depth] = 0x80;
91                 break;
92             case Position::POSITION_UNKNOWN:
93                 pos[depth] = 0;
94                 mask[depth] = 0;
95                 break;
96         }
97     }
98 
99     if (matcher.child_size() == 0) {
100         output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
101     } else {
102         for (const auto& child : matcher.child()) {
103             translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
104         }
105     }
106 }
107 
translateFieldMatcher(const FieldMatcher & matcher,std::vector<Matcher> * output)108 void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
109     int pos[] = {1, 1, 1};
110     int mask[] = {0x7f, 0x7f, 0x7f};
111     int tag = matcher.field();
112     for (const auto& child : matcher.child()) {
113         translateFieldMatcher(tag, child, 0, pos, mask, output);
114     }
115 }
116 
isAttributionUidField(const FieldValue & value)117 bool isAttributionUidField(const FieldValue& value) {
118     return isAttributionUidField(value.mField, value.mValue);
119 }
120 
getUidIfExists(const FieldValue & value)121 int32_t getUidIfExists(const FieldValue& value) {
122     // the field is uid field if the field is the uid field in attribution node
123     // or annotated as such in the atom
124     bool isUid = isAttributionUidField(value) || isUidField(value);
125     return isUid ? value.mValue.int_value : -1;
126 }
127 
isAttributionUidField(const Field & field,const Value & value)128 bool isAttributionUidField(const Field& field, const Value& value) {
129     int f = field.getField() & 0xff007f;
130     if (f == 0x10001 && value.getType() == INT) {
131         return true;
132     }
133     return false;
134 }
135 
isUidField(const FieldValue & fieldValue)136 bool isUidField(const FieldValue& fieldValue) {
137     return fieldValue.mAnnotations.isUidField();
138 }
139 
Value(const Value & from)140 Value::Value(const Value& from) {
141     type = from.getType();
142     switch (type) {
143         case INT:
144             int_value = from.int_value;
145             break;
146         case LONG:
147             long_value = from.long_value;
148             break;
149         case FLOAT:
150             float_value = from.float_value;
151             break;
152         case DOUBLE:
153             double_value = from.double_value;
154             break;
155         case STRING:
156             str_value = from.str_value;
157             break;
158         case STORAGE:
159             storage_value = from.storage_value;
160             break;
161         default:
162             break;
163     }
164 }
165 
toString() const166 std::string Value::toString() const {
167     switch (type) {
168         case INT:
169             return std::to_string(int_value) + "[I]";
170         case LONG:
171             return std::to_string(long_value) + "[L]";
172         case FLOAT:
173             return std::to_string(float_value) + "[F]";
174         case DOUBLE:
175             return std::to_string(double_value) + "[D]";
176         case STRING:
177             return str_value + "[S]";
178         case STORAGE:
179             return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
180         default:
181             return "[UNKNOWN]";
182     }
183 }
184 
isZero() const185 bool Value::isZero() const {
186     switch (type) {
187         case INT:
188             return int_value == 0;
189         case LONG:
190             return long_value == 0;
191         case FLOAT:
192             return fabs(float_value) <= std::numeric_limits<float>::epsilon();
193         case DOUBLE:
194             return fabs(double_value) <= std::numeric_limits<double>::epsilon();
195         case STRING:
196             return str_value.size() == 0;
197         case STORAGE:
198             return storage_value.size() == 0;
199         default:
200             return false;
201     }
202 }
203 
operator ==(const Value & that) const204 bool Value::operator==(const Value& that) const {
205     if (type != that.getType()) return false;
206 
207     switch (type) {
208         case INT:
209             return int_value == that.int_value;
210         case LONG:
211             return long_value == that.long_value;
212         case FLOAT:
213             return float_value == that.float_value;
214         case DOUBLE:
215             return double_value == that.double_value;
216         case STRING:
217             return str_value == that.str_value;
218         case STORAGE:
219             return storage_value == that.storage_value;
220         default:
221             return false;
222     }
223 }
224 
operator !=(const Value & that) const225 bool Value::operator!=(const Value& that) const {
226     if (type != that.getType()) return true;
227     switch (type) {
228         case INT:
229             return int_value != that.int_value;
230         case LONG:
231             return long_value != that.long_value;
232         case FLOAT:
233             return float_value != that.float_value;
234         case DOUBLE:
235             return double_value != that.double_value;
236         case STRING:
237             return str_value != that.str_value;
238         case STORAGE:
239             return storage_value != that.storage_value;
240         default:
241             return false;
242     }
243 }
244 
operator <(const Value & that) const245 bool Value::operator<(const Value& that) const {
246     if (type != that.getType()) return type < that.getType();
247 
248     switch (type) {
249         case INT:
250             return int_value < that.int_value;
251         case LONG:
252             return long_value < that.long_value;
253         case FLOAT:
254             return float_value < that.float_value;
255         case DOUBLE:
256             return double_value < that.double_value;
257         case STRING:
258             return str_value < that.str_value;
259         case STORAGE:
260             return storage_value < that.storage_value;
261         default:
262             return false;
263     }
264 }
265 
operator >(const Value & that) const266 bool Value::operator>(const Value& that) const {
267     if (type != that.getType()) return type > that.getType();
268 
269     switch (type) {
270         case INT:
271             return int_value > that.int_value;
272         case LONG:
273             return long_value > that.long_value;
274         case FLOAT:
275             return float_value > that.float_value;
276         case DOUBLE:
277             return double_value > that.double_value;
278         case STRING:
279             return str_value > that.str_value;
280         case STORAGE:
281             return storage_value > that.storage_value;
282         default:
283             return false;
284     }
285 }
286 
operator >=(const Value & that) const287 bool Value::operator>=(const Value& that) const {
288     if (type != that.getType()) return type >= that.getType();
289 
290     switch (type) {
291         case INT:
292             return int_value >= that.int_value;
293         case LONG:
294             return long_value >= that.long_value;
295         case FLOAT:
296             return float_value >= that.float_value;
297         case DOUBLE:
298             return double_value >= that.double_value;
299         case STRING:
300             return str_value >= that.str_value;
301         case STORAGE:
302             return storage_value >= that.storage_value;
303         default:
304             return false;
305     }
306 }
307 
operator -(const Value & that) const308 Value Value::operator-(const Value& that) const {
309     Value v;
310     if (type != that.type) {
311         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
312         return v;
313     }
314     if (type == STRING) {
315         ALOGE("Can't operate on string value type");
316         return v;
317     }
318 
319     if (type == STORAGE) {
320         ALOGE("Can't operate on storage value type");
321         return v;
322     }
323 
324     switch (type) {
325         case INT:
326             v.setInt(int_value - that.int_value);
327             break;
328         case LONG:
329             v.setLong(long_value - that.long_value);
330             break;
331         case FLOAT:
332             v.setFloat(float_value - that.float_value);
333             break;
334         case DOUBLE:
335             v.setDouble(double_value - that.double_value);
336             break;
337         default:
338             break;
339     }
340     return v;
341 }
342 
operator =(const Value & that)343 Value& Value::operator=(const Value& that) {
344     type = that.type;
345     switch (type) {
346         case INT:
347             int_value = that.int_value;
348             break;
349         case LONG:
350             long_value = that.long_value;
351             break;
352         case FLOAT:
353             float_value = that.float_value;
354             break;
355         case DOUBLE:
356             double_value = that.double_value;
357             break;
358         case STRING:
359             str_value = that.str_value;
360             break;
361         case STORAGE:
362             storage_value = that.storage_value;
363             break;
364         default:
365             break;
366     }
367     return *this;
368 }
369 
operator +=(const Value & that)370 Value& Value::operator+=(const Value& that) {
371     if (type != that.type) {
372         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
373         return *this;
374     }
375     if (type == STRING) {
376         ALOGE("Can't operate on string value type");
377         return *this;
378     }
379     if (type == STORAGE) {
380         ALOGE("Can't operate on storage value type");
381         return *this;
382     }
383 
384     switch (type) {
385         case INT:
386             int_value += that.int_value;
387             break;
388         case LONG:
389             long_value += that.long_value;
390             break;
391         case FLOAT:
392             float_value += that.float_value;
393             break;
394         case DOUBLE:
395             double_value += that.double_value;
396             break;
397         default:
398             break;
399     }
400     return *this;
401 }
402 
getDouble() const403 double Value::getDouble() const {
404     switch (type) {
405         case INT:
406             return int_value;
407         case LONG:
408             return long_value;
409         case FLOAT:
410             return float_value;
411         case DOUBLE:
412             return double_value;
413         default:
414             return 0;
415     }
416 }
417 
equalDimensions(const std::vector<Matcher> & dimension_a,const std::vector<Matcher> & dimension_b)418 bool equalDimensions(const std::vector<Matcher>& dimension_a,
419                      const std::vector<Matcher>& dimension_b) {
420     bool eq = dimension_a.size() == dimension_b.size();
421     for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
422         if (dimension_b[i] != dimension_a[i]) {
423             eq = false;
424         }
425     }
426     return eq;
427 }
428 
subsetDimensions(const std::vector<Matcher> & dimension_a,const std::vector<Matcher> & dimension_b)429 bool subsetDimensions(const std::vector<Matcher>& dimension_a,
430                       const std::vector<Matcher>& dimension_b) {
431     if (dimension_a.size() > dimension_b.size()) {
432         return false;
433     }
434     for (size_t i = 0; i < dimension_a.size(); ++i) {
435         bool found = false;
436         for (size_t j = 0; j < dimension_b.size(); ++j) {
437             if (dimension_a[i] == dimension_b[j]) {
438                 found = true;
439             }
440         }
441         if (!found) {
442             return false;
443         }
444     }
445     return true;
446 }
447 
HasPositionANY(const FieldMatcher & matcher)448 bool HasPositionANY(const FieldMatcher& matcher) {
449     if (matcher.has_position() && matcher.position() == Position::ANY) {
450         return true;
451     }
452     for (const auto& child : matcher.child()) {
453         if (HasPositionANY(child)) {
454             return true;
455         }
456     }
457     return false;
458 }
459 
HasPositionALL(const FieldMatcher & matcher)460 bool HasPositionALL(const FieldMatcher& matcher) {
461     if (matcher.has_position() && matcher.position() == Position::ALL) {
462         return true;
463     }
464     for (const auto& child : matcher.child()) {
465         if (HasPositionALL(child)) {
466             return true;
467         }
468     }
469     return false;
470 }
471 
472 }  // namespace statsd
473 }  // namespace os
474 }  // namespace android
475