• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 STATSD_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 
isPrimitiveRepeatedField(const Field & field)140 bool isPrimitiveRepeatedField(const Field& field) {
141     return field.getDepth() == 1;
142 }
143 
Value(const Value & from)144 Value::Value(const Value& from) {
145     type = from.getType();
146     switch (type) {
147         case INT:
148             int_value = from.int_value;
149             break;
150         case LONG:
151             long_value = from.long_value;
152             break;
153         case FLOAT:
154             float_value = from.float_value;
155             break;
156         case DOUBLE:
157             double_value = from.double_value;
158             break;
159         case STRING:
160             str_value = from.str_value;
161             break;
162         case STORAGE:
163             storage_value = from.storage_value;
164             break;
165         default:
166             break;
167     }
168 }
169 
toString() const170 std::string Value::toString() const {
171     switch (type) {
172         case INT:
173             return std::to_string(int_value) + "[I]";
174         case LONG:
175             return std::to_string(long_value) + "[L]";
176         case FLOAT:
177             return std::to_string(float_value) + "[F]";
178         case DOUBLE:
179             return std::to_string(double_value) + "[D]";
180         case STRING:
181             return str_value + "[S]";
182         case STORAGE:
183             return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
184         default:
185             return "[UNKNOWN]";
186     }
187 }
188 
isZero() const189 bool Value::isZero() const {
190     switch (type) {
191         case INT:
192             return int_value == 0;
193         case LONG:
194             return long_value == 0;
195         case FLOAT:
196             return fabs(float_value) <= std::numeric_limits<float>::epsilon();
197         case DOUBLE:
198             return fabs(double_value) <= std::numeric_limits<double>::epsilon();
199         case STRING:
200             return str_value.size() == 0;
201         case STORAGE:
202             return storage_value.size() == 0;
203         default:
204             return false;
205     }
206 }
207 
operator ==(const Value & that) const208 bool Value::operator==(const Value& that) const {
209     if (type != that.getType()) return false;
210 
211     switch (type) {
212         case INT:
213             return int_value == that.int_value;
214         case LONG:
215             return long_value == that.long_value;
216         case FLOAT:
217             return float_value == that.float_value;
218         case DOUBLE:
219             return double_value == that.double_value;
220         case STRING:
221             return str_value == that.str_value;
222         case STORAGE:
223             return storage_value == that.storage_value;
224         default:
225             return false;
226     }
227 }
228 
operator !=(const Value & that) const229 bool Value::operator!=(const Value& that) const {
230     if (type != that.getType()) return true;
231     switch (type) {
232         case INT:
233             return int_value != that.int_value;
234         case LONG:
235             return long_value != that.long_value;
236         case FLOAT:
237             return float_value != that.float_value;
238         case DOUBLE:
239             return double_value != that.double_value;
240         case STRING:
241             return str_value != that.str_value;
242         case STORAGE:
243             return storage_value != that.storage_value;
244         default:
245             return false;
246     }
247 }
248 
operator <(const Value & that) const249 bool Value::operator<(const Value& that) const {
250     if (type != that.getType()) return type < that.getType();
251 
252     switch (type) {
253         case INT:
254             return int_value < that.int_value;
255         case LONG:
256             return long_value < that.long_value;
257         case FLOAT:
258             return float_value < that.float_value;
259         case DOUBLE:
260             return double_value < that.double_value;
261         case STRING:
262             return str_value < that.str_value;
263         case STORAGE:
264             return storage_value < that.storage_value;
265         default:
266             return false;
267     }
268 }
269 
operator >(const Value & that) const270 bool Value::operator>(const Value& that) const {
271     if (type != that.getType()) return type > that.getType();
272 
273     switch (type) {
274         case INT:
275             return int_value > that.int_value;
276         case LONG:
277             return long_value > that.long_value;
278         case FLOAT:
279             return float_value > that.float_value;
280         case DOUBLE:
281             return double_value > that.double_value;
282         case STRING:
283             return str_value > that.str_value;
284         case STORAGE:
285             return storage_value > that.storage_value;
286         default:
287             return false;
288     }
289 }
290 
operator >=(const Value & that) const291 bool Value::operator>=(const Value& that) const {
292     if (type != that.getType()) return type >= that.getType();
293 
294     switch (type) {
295         case INT:
296             return int_value >= that.int_value;
297         case LONG:
298             return long_value >= that.long_value;
299         case FLOAT:
300             return float_value >= that.float_value;
301         case DOUBLE:
302             return double_value >= that.double_value;
303         case STRING:
304             return str_value >= that.str_value;
305         case STORAGE:
306             return storage_value >= that.storage_value;
307         default:
308             return false;
309     }
310 }
311 
operator -(const Value & that) const312 Value Value::operator-(const Value& that) const {
313     Value v;
314     if (type != that.type) {
315         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
316         return v;
317     }
318     if (type == STRING) {
319         ALOGE("Can't operate on string value type");
320         return v;
321     }
322 
323     if (type == STORAGE) {
324         ALOGE("Can't operate on storage value type");
325         return v;
326     }
327 
328     switch (type) {
329         case INT:
330             v.setInt(int_value - that.int_value);
331             break;
332         case LONG:
333             v.setLong(long_value - that.long_value);
334             break;
335         case FLOAT:
336             v.setFloat(float_value - that.float_value);
337             break;
338         case DOUBLE:
339             v.setDouble(double_value - that.double_value);
340             break;
341         default:
342             break;
343     }
344     return v;
345 }
346 
operator =(const Value & that)347 Value& Value::operator=(const Value& that) {
348     type = that.type;
349     switch (type) {
350         case INT:
351             int_value = that.int_value;
352             break;
353         case LONG:
354             long_value = that.long_value;
355             break;
356         case FLOAT:
357             float_value = that.float_value;
358             break;
359         case DOUBLE:
360             double_value = that.double_value;
361             break;
362         case STRING:
363             str_value = that.str_value;
364             break;
365         case STORAGE:
366             storage_value = that.storage_value;
367             break;
368         default:
369             break;
370     }
371     return *this;
372 }
373 
operator +=(const Value & that)374 Value& Value::operator+=(const Value& that) {
375     if (type != that.type) {
376         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
377         return *this;
378     }
379     if (type == STRING) {
380         ALOGE("Can't operate on string value type");
381         return *this;
382     }
383     if (type == STORAGE) {
384         ALOGE("Can't operate on storage value type");
385         return *this;
386     }
387 
388     switch (type) {
389         case INT:
390             int_value += that.int_value;
391             break;
392         case LONG:
393             long_value += that.long_value;
394             break;
395         case FLOAT:
396             float_value += that.float_value;
397             break;
398         case DOUBLE:
399             double_value += that.double_value;
400             break;
401         default:
402             break;
403     }
404     return *this;
405 }
406 
getDouble() const407 double Value::getDouble() const {
408     switch (type) {
409         case INT:
410             return int_value;
411         case LONG:
412             return long_value;
413         case FLOAT:
414             return float_value;
415         case DOUBLE:
416             return double_value;
417         default:
418             return 0;
419     }
420 }
421 
getSize() const422 size_t Value::getSize() const {
423     size_t size = 0;
424     switch (type) {
425         case INT:
426             size = sizeof(int32_t);
427             break;
428         case LONG:
429             size = sizeof(int64_t);
430             break;
431         case FLOAT:
432             size = sizeof(float);
433             break;
434         case DOUBLE:
435             size = sizeof(double);
436             break;
437         case STRING:
438             size = sizeof(char) * str_value.length();
439             break;
440         case STORAGE:
441             size = sizeof(uint8_t) * storage_value.size();
442             break;
443         default:
444             break;
445     }
446     return size;
447 }
448 
equalDimensions(const std::vector<Matcher> & dimension_a,const std::vector<Matcher> & dimension_b)449 bool equalDimensions(const std::vector<Matcher>& dimension_a,
450                      const std::vector<Matcher>& dimension_b) {
451     bool eq = dimension_a.size() == dimension_b.size();
452     for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
453         if (dimension_b[i] != dimension_a[i]) {
454             eq = false;
455         }
456     }
457     return eq;
458 }
459 
subsetDimensions(const std::vector<Matcher> & dimension_a,const std::vector<Matcher> & dimension_b)460 bool subsetDimensions(const std::vector<Matcher>& dimension_a,
461                       const std::vector<Matcher>& dimension_b) {
462     if (dimension_a.size() > dimension_b.size()) {
463         return false;
464     }
465     for (size_t i = 0; i < dimension_a.size(); ++i) {
466         bool found = false;
467         for (size_t j = 0; j < dimension_b.size(); ++j) {
468             if (dimension_a[i] == dimension_b[j]) {
469                 found = true;
470             }
471         }
472         if (!found) {
473             return false;
474         }
475     }
476     return true;
477 }
478 
HasPositionANY(const FieldMatcher & matcher)479 bool HasPositionANY(const FieldMatcher& matcher) {
480     if (matcher.has_position() && matcher.position() == Position::ANY) {
481         return true;
482     }
483     for (const auto& child : matcher.child()) {
484         if (HasPositionANY(child)) {
485             return true;
486         }
487     }
488     return false;
489 }
490 
HasPositionALL(const FieldMatcher & matcher)491 bool HasPositionALL(const FieldMatcher& matcher) {
492     if (matcher.has_position() && matcher.position() == Position::ALL) {
493         return true;
494     }
495     for (const auto& child : matcher.child()) {
496         if (HasPositionALL(child)) {
497             return true;
498         }
499     }
500     return false;
501 }
502 
HasPrimitiveRepeatedField(const FieldMatcher & matcher)503 bool HasPrimitiveRepeatedField(const FieldMatcher& matcher) {
504     for (const auto& child : matcher.child()) {
505         if (child.has_position() && child.child_size() == 0) {
506             return true;
507         }
508     }
509     return false;
510 }
511 
ShouldUseNestedDimensions(const FieldMatcher & matcher)512 bool ShouldUseNestedDimensions(const FieldMatcher& matcher) {
513     return HasPositionALL(matcher) || HasPrimitiveRepeatedField(matcher);
514 }
515 
getSize(const std::vector<FieldValue> & fieldValues)516 size_t getSize(const std::vector<FieldValue>& fieldValues) {
517     size_t totalSize = 0;
518     for (const FieldValue& fieldValue : fieldValues) {
519         totalSize += fieldValue.getSize();
520     }
521     return totalSize;
522 }
523 
524 }  // namespace statsd
525 }  // namespace os
526 }  // namespace android
527