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