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