• 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 
20 #include "FieldValue.h"
21 
22 #include "HashableDimensionKey.h"
23 #include "hash.h"
24 #include "math.h"
25 
26 namespace android {
27 namespace os {
28 namespace statsd {
29 
getEncodedField(int32_t pos[],int32_t depth,bool includeDepth)30 int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
31     int32_t field = 0;
32     for (int32_t i = 0; i <= depth; i++) {
33         int32_t shiftBits = 8 * (kMaxLogDepth - i);
34         field |= (pos[i] << shiftBits);
35     }
36 
37     if (includeDepth) {
38         field |= (depth << 24);
39     }
40     return field;
41 }
42 
encodeMatcherMask(int32_t mask[],int32_t depth)43 int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
44     return getEncodedField(mask, depth, false) | 0xff000000;
45 }
46 
matches(const Matcher & matcher) const47 bool Field::matches(const Matcher& matcher) const {
48     if (mTag != matcher.mMatcher.getTag()) {
49         return false;
50     }
51     if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
52         return true;
53     }
54 
55     if (matcher.hasAllPositionMatcher() &&
56         (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
57         return true;
58     }
59 
60     return false;
61 }
62 
translateFieldMatcher(int tag,const FieldMatcher & matcher,int depth,int * pos,int * mask,std::vector<Matcher> * output)63 void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
64                            std::vector<Matcher>* output) {
65     if (depth > kMaxLogDepth) {
66         ALOGE("depth > 2");
67         return;
68     }
69 
70     pos[depth] = matcher.field();
71     mask[depth] = 0x7f;
72 
73     if (matcher.has_position()) {
74         depth++;
75         if (depth > 2) {
76             return;
77         }
78         switch (matcher.position()) {
79             case Position::ALL:
80                 pos[depth] = 0x00;
81                 mask[depth] = 0x7f;
82                 break;
83             case Position::ANY:
84                 pos[depth] = 0;
85                 mask[depth] = 0;
86                 break;
87             case Position::FIRST:
88                 pos[depth] = 1;
89                 mask[depth] = 0x7f;
90                 break;
91             case Position::LAST:
92                 pos[depth] = 0x80;
93                 mask[depth] = 0x80;
94                 break;
95             case Position::POSITION_UNKNOWN:
96                 pos[depth] = 0;
97                 mask[depth] = 0;
98                 break;
99         }
100     }
101 
102     if (matcher.child_size() == 0) {
103         output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
104     } else {
105         for (const auto& child : matcher.child()) {
106             translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
107         }
108     }
109 }
110 
translateFieldMatcher(const FieldMatcher & matcher,std::vector<Matcher> * output)111 void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
112     int pos[] = {1, 1, 1};
113     int mask[] = {0x7f, 0x7f, 0x7f};
114     int tag = matcher.field();
115     for (const auto& child : matcher.child()) {
116         translateFieldMatcher(tag, child, 0, pos, mask, output);
117     }
118 }
119 
isAttributionUidField(const FieldValue & value)120 bool isAttributionUidField(const FieldValue& value) {
121     return isAttributionUidField(value.mField, value.mValue);
122 }
123 
getUidIfExists(const FieldValue & value)124 int32_t getUidIfExists(const FieldValue& value) {
125     // the field is uid field if the field is the uid field in attribution node
126     // or annotated as such in the atom
127     bool isUid = isAttributionUidField(value) || isUidField(value);
128     return isUid ? value.mValue.int_value : -1;
129 }
130 
isAttributionUidField(const Field & field,const Value & value)131 bool isAttributionUidField(const Field& field, const Value& value) {
132     int f = field.getField() & 0xff007f;
133     if (f == 0x10001 && value.getType() == INT) {
134         return true;
135     }
136     return false;
137 }
138 
isUidField(const FieldValue & fieldValue)139 bool isUidField(const FieldValue& fieldValue) {
140     return fieldValue.mAnnotations.isUidField();
141 }
142 
isPrimitiveRepeatedField(const Field & field)143 bool isPrimitiveRepeatedField(const Field& field) {
144     return field.getDepth() == 1;
145 }
146 
Value(const Value & from)147 Value::Value(const Value& from) {
148     type = from.getType();
149     switch (type) {
150         case INT:
151             int_value = from.int_value;
152             break;
153         case LONG:
154             long_value = from.long_value;
155             break;
156         case FLOAT:
157             float_value = from.float_value;
158             break;
159         case DOUBLE:
160             double_value = from.double_value;
161             break;
162         case STRING:
163             str_value = from.str_value;
164             break;
165         case STORAGE:
166             storage_value = from.storage_value;
167             break;
168         default:
169             break;
170     }
171 }
172 
toString() const173 std::string Value::toString() const {
174     switch (type) {
175         case INT:
176             return std::to_string(int_value) + "[I]";
177         case LONG:
178             return std::to_string(long_value) + "[L]";
179         case FLOAT:
180             return std::to_string(float_value) + "[F]";
181         case DOUBLE:
182             return std::to_string(double_value) + "[D]";
183         case STRING:
184             return str_value + "[S]";
185         case STORAGE:
186             return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
187         default:
188             return "[UNKNOWN]";
189     }
190 }
191 
isZero() const192 bool Value::isZero() const {
193     switch (type) {
194         case INT:
195             return int_value == 0;
196         case LONG:
197             return long_value == 0;
198         case FLOAT:
199             return fabs(float_value) <= std::numeric_limits<float>::epsilon();
200         case DOUBLE:
201             return fabs(double_value) <= std::numeric_limits<double>::epsilon();
202         case STRING:
203             return str_value.size() == 0;
204         case STORAGE:
205             return storage_value.size() == 0;
206         default:
207             return false;
208     }
209 }
210 
operator ==(const Value & that) const211 bool Value::operator==(const Value& that) const {
212     if (type != that.getType()) return false;
213 
214     switch (type) {
215         case INT:
216             return int_value == that.int_value;
217         case LONG:
218             return long_value == that.long_value;
219         case FLOAT:
220             return float_value == that.float_value;
221         case DOUBLE:
222             return double_value == that.double_value;
223         case STRING:
224             return str_value == that.str_value;
225         case STORAGE:
226             return storage_value == that.storage_value;
227         default:
228             return false;
229     }
230 }
231 
operator !=(const Value & that) const232 bool Value::operator!=(const Value& that) const {
233     if (type != that.getType()) return true;
234     switch (type) {
235         case INT:
236             return int_value != that.int_value;
237         case LONG:
238             return long_value != that.long_value;
239         case FLOAT:
240             return float_value != that.float_value;
241         case DOUBLE:
242             return double_value != that.double_value;
243         case STRING:
244             return str_value != that.str_value;
245         case STORAGE:
246             return storage_value != that.storage_value;
247         default:
248             return false;
249     }
250 }
251 
operator <(const Value & that) const252 bool Value::operator<(const Value& that) const {
253     if (type != that.getType()) return type < that.getType();
254 
255     switch (type) {
256         case INT:
257             return int_value < that.int_value;
258         case LONG:
259             return long_value < that.long_value;
260         case FLOAT:
261             return float_value < that.float_value;
262         case DOUBLE:
263             return double_value < that.double_value;
264         case STRING:
265             return str_value < that.str_value;
266         case STORAGE:
267             return storage_value < that.storage_value;
268         default:
269             return false;
270     }
271 }
272 
operator >(const Value & that) const273 bool Value::operator>(const Value& that) const {
274     if (type != that.getType()) return type > that.getType();
275 
276     switch (type) {
277         case INT:
278             return int_value > that.int_value;
279         case LONG:
280             return long_value > that.long_value;
281         case FLOAT:
282             return float_value > that.float_value;
283         case DOUBLE:
284             return double_value > that.double_value;
285         case STRING:
286             return str_value > that.str_value;
287         case STORAGE:
288             return storage_value > that.storage_value;
289         default:
290             return false;
291     }
292 }
293 
operator >=(const Value & that) const294 bool Value::operator>=(const Value& that) const {
295     if (type != that.getType()) return type >= that.getType();
296 
297     switch (type) {
298         case INT:
299             return int_value >= that.int_value;
300         case LONG:
301             return long_value >= that.long_value;
302         case FLOAT:
303             return float_value >= that.float_value;
304         case DOUBLE:
305             return double_value >= that.double_value;
306         case STRING:
307             return str_value >= that.str_value;
308         case STORAGE:
309             return storage_value >= that.storage_value;
310         default:
311             return false;
312     }
313 }
314 
operator -(const Value & that) const315 Value Value::operator-(const Value& that) const {
316     Value v;
317     if (type != that.type) {
318         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
319         return v;
320     }
321     if (type == STRING) {
322         ALOGE("Can't operate on string value type");
323         return v;
324     }
325 
326     if (type == STORAGE) {
327         ALOGE("Can't operate on storage value type");
328         return v;
329     }
330 
331     switch (type) {
332         case INT:
333             v.setInt(int_value - that.int_value);
334             break;
335         case LONG:
336             v.setLong(long_value - that.long_value);
337             break;
338         case FLOAT:
339             v.setFloat(float_value - that.float_value);
340             break;
341         case DOUBLE:
342             v.setDouble(double_value - that.double_value);
343             break;
344         default:
345             break;
346     }
347     return v;
348 }
349 
operator =(const Value & that)350 Value& Value::operator=(const Value& that) {
351     type = that.type;
352     switch (type) {
353         case INT:
354             int_value = that.int_value;
355             break;
356         case LONG:
357             long_value = that.long_value;
358             break;
359         case FLOAT:
360             float_value = that.float_value;
361             break;
362         case DOUBLE:
363             double_value = that.double_value;
364             break;
365         case STRING:
366             str_value = that.str_value;
367             break;
368         case STORAGE:
369             storage_value = that.storage_value;
370             break;
371         default:
372             break;
373     }
374     return *this;
375 }
376 
operator +=(const Value & that)377 Value& Value::operator+=(const Value& that) {
378     if (type != that.type) {
379         ALOGE("Can't operate on different value types, %d, %d", type, that.type);
380         return *this;
381     }
382     if (type == STRING) {
383         ALOGE("Can't operate on string value type");
384         return *this;
385     }
386     if (type == STORAGE) {
387         ALOGE("Can't operate on storage value type");
388         return *this;
389     }
390 
391     switch (type) {
392         case INT:
393             int_value += that.int_value;
394             break;
395         case LONG:
396             long_value += that.long_value;
397             break;
398         case FLOAT:
399             float_value += that.float_value;
400             break;
401         case DOUBLE:
402             double_value += that.double_value;
403             break;
404         default:
405             break;
406     }
407     return *this;
408 }
409 
getDouble() const410 double Value::getDouble() const {
411     switch (type) {
412         case INT:
413             return int_value;
414         case LONG:
415             return long_value;
416         case FLOAT:
417             return float_value;
418         case DOUBLE:
419             return double_value;
420         default:
421             return 0;
422     }
423 }
424 
getSize() const425 size_t Value::getSize() const {
426     size_t size = 0;
427     switch (type) {
428         case INT:
429             size = sizeof(int32_t);
430             break;
431         case LONG:
432             size = sizeof(int64_t);
433             break;
434         case FLOAT:
435             size = sizeof(float);
436             break;
437         case DOUBLE:
438             size = sizeof(double);
439             break;
440         case STRING:
441             size = sizeof(char) * str_value.length();
442             break;
443         case STORAGE:
444             size = sizeof(uint8_t) * storage_value.size();
445             break;
446         default:
447             break;
448     }
449     return size;
450 }
451 
toString() const452 std::string Annotations::toString() const {
453     std::string annotations;
454     if (isUidField()) {
455         annotations += "UID";
456     }
457     if (isPrimaryField()) {
458         annotations += annotations.size() > 0 ? ",PRIMARY" : "PRIMARY";
459     }
460     if (isExclusiveState()) {
461         annotations += annotations.size() > 0 ? ",EXCLUSIVE" : "EXCLUSIVE";
462     }
463     if (isNested()) {
464         annotations += annotations.size() > 0 ? ",NESTED" : "NESTED";
465     }
466     if (annotations.size()) {
467         annotations = "[" + annotations + "]";
468     }
469     return annotations;
470 }
471 
equalDimensions(const std::vector<Matcher> & dimension_a,const std::vector<Matcher> & dimension_b)472 bool equalDimensions(const std::vector<Matcher>& dimension_a,
473                      const std::vector<Matcher>& dimension_b) {
474     bool eq = dimension_a.size() == dimension_b.size();
475     for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
476         if (dimension_b[i] != dimension_a[i]) {
477             eq = false;
478         }
479     }
480     return eq;
481 }
482 
subsetDimensions(const std::vector<Matcher> & dimension_a,const std::vector<Matcher> & dimension_b)483 bool subsetDimensions(const std::vector<Matcher>& dimension_a,
484                       const std::vector<Matcher>& dimension_b) {
485     if (dimension_a.size() > dimension_b.size()) {
486         return false;
487     }
488     for (size_t i = 0; i < dimension_a.size(); ++i) {
489         bool found = false;
490         for (size_t j = 0; j < dimension_b.size(); ++j) {
491             if (dimension_a[i] == dimension_b[j]) {
492                 found = true;
493             }
494         }
495         if (!found) {
496             return false;
497         }
498     }
499     return true;
500 }
501 
HasPositionANY(const FieldMatcher & matcher)502 bool HasPositionANY(const FieldMatcher& matcher) {
503     if (matcher.has_position() && matcher.position() == Position::ANY) {
504         return true;
505     }
506     for (const auto& child : matcher.child()) {
507         if (HasPositionANY(child)) {
508             return true;
509         }
510     }
511     return false;
512 }
513 
HasPositionALL(const FieldMatcher & matcher)514 bool HasPositionALL(const FieldMatcher& matcher) {
515     if (matcher.has_position() && matcher.position() == Position::ALL) {
516         return true;
517     }
518     for (const auto& child : matcher.child()) {
519         if (HasPositionALL(child)) {
520             return true;
521         }
522     }
523     return false;
524 }
525 
HasPrimitiveRepeatedField(const FieldMatcher & matcher)526 bool HasPrimitiveRepeatedField(const FieldMatcher& matcher) {
527     for (const auto& child : matcher.child()) {
528         if (child.has_position() && child.child_size() == 0) {
529             return true;
530         }
531     }
532     return false;
533 }
534 
ShouldUseNestedDimensions(const FieldMatcher & matcher)535 bool ShouldUseNestedDimensions(const FieldMatcher& matcher) {
536     return HasPositionALL(matcher) || HasPrimitiveRepeatedField(matcher);
537 }
538 
getSize(const std::vector<FieldValue> & fieldValues)539 size_t getSize(const std::vector<FieldValue>& fieldValues) {
540     size_t totalSize = 0;
541     for (const FieldValue& fieldValue : fieldValues) {
542         totalSize += fieldValue.getSize();
543     }
544     return totalSize;
545 }
546 
shouldKeepSample(const FieldValue & sampleFieldValue,int shardOffset,int shardCount)547 bool shouldKeepSample(const FieldValue& sampleFieldValue, int shardOffset, int shardCount) {
548     int hashValue = 0;
549     switch (sampleFieldValue.mValue.type) {
550         case INT:
551             hashValue = Hash32(reinterpret_cast<const char*>(&sampleFieldValue.mValue.int_value),
552                                sizeof(sampleFieldValue.mValue.int_value));
553             break;
554         case LONG:
555             hashValue = Hash32(reinterpret_cast<const char*>(&sampleFieldValue.mValue.long_value),
556                                sizeof(sampleFieldValue.mValue.long_value));
557             break;
558         case FLOAT:
559             hashValue = Hash32(reinterpret_cast<const char*>(&sampleFieldValue.mValue.float_value),
560                                sizeof(sampleFieldValue.mValue.float_value));
561             break;
562         case DOUBLE:
563             hashValue = Hash32(reinterpret_cast<const char*>(&sampleFieldValue.mValue.double_value),
564                                sizeof(sampleFieldValue.mValue.double_value));
565             break;
566         case STRING:
567             hashValue = Hash32(sampleFieldValue.mValue.str_value);
568             break;
569         case STORAGE:
570             hashValue = Hash32((const char*)sampleFieldValue.mValue.storage_value.data(),
571                                sampleFieldValue.mValue.storage_value.size());
572             break;
573         default:
574             return true;
575     }
576     return (hashValue + shardOffset) % shardCount == 0;
577 }
578 
579 }  // namespace statsd
580 }  // namespace os
581 }  // namespace android
582