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