blob: cfc1de49e2595c0f7bb1746bcb8e4e56ef8d1426 [file] [log] [blame]
Yao Chen8a8d16c2018-02-08 14:50:40 -08001/*
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"
Muhammad Qureshic8e22662019-11-20 17:18:03 -080021#include "atoms_info.h"
Chenjie Yuc715b9e2018-10-19 07:52:12 -070022#include "math.h"
Yao Chen8a8d16c2018-02-08 14:50:40 -080023
24namespace android {
25namespace os {
26namespace statsd {
27
Yao Chen4c959cb2018-02-13 13:27:48 -080028int32_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
41int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
42 return getEncodedField(mask, depth, false) | 0xff000000;
43}
44
Yao Chen8a8d16c2018-02-08 14:50:40 -080045bool 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
Yangster-mace06cfd72018-03-10 23:22:59 -080053 if (matcher.hasAllPositionMatcher() &&
54 (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
55 return true;
56 }
57
Yao Chen8a8d16c2018-02-08 14:50:40 -080058 return false;
Yao Chen4c959cb2018-02-13 13:27:48 -080059}
Yao Chen8a8d16c2018-02-08 14:50:40 -080060
61void 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()) {
Yangster-mace06cfd72018-03-10 23:22:59 -080077 case Position::ALL:
78 pos[depth] = 0x00;
79 mask[depth] = 0x7f;
80 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -080081 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)));
Yao Chen8a8d16c2018-02-08 14:50:40 -0800102 } else {
103 for (const auto& child : matcher.child()) {
104 translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
105 }
106 }
107}
108
109void 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
118bool isAttributionUidField(const FieldValue& value) {
Rafal Slawik390692b2019-09-18 12:40:17 +0100119 return isAttributionUidField(value.mField, value.mValue);
Yao Chen8a8d16c2018-02-08 14:50:40 -0800120}
121
Yao Chen4ce07292019-02-13 13:06:36 -0800122int32_t getUidIfExists(const FieldValue& value) {
Ruchir Rastogiffa34f052020-04-04 15:30:11 -0700123 // the field is uid field if the field is the uid field in attribution node
124 // or annotated as such in the atom
125 bool isUid = isAttributionUidField(value) || isUidField(value);
Yao Chen4ce07292019-02-13 13:06:36 -0800126 return isUid ? value.mValue.int_value : -1;
127}
128
Yao Chen8a8d16c2018-02-08 14:50:40 -0800129bool isAttributionUidField(const Field& field, const Value& value) {
130 int f = field.getField() & 0xff007f;
131 if (f == 0x10001 && value.getType() == INT) {
132 return true;
133 }
134 return false;
135}
136
Ruchir Rastogiffa34f052020-04-04 15:30:11 -0700137bool isUidField(const FieldValue& fieldValue) {
138 return fieldValue.mAnnotations.isUidField();
tsaichristine7a57b8e2019-06-24 18:25:38 -0700139}
140
Yao Chen8a8d16c2018-02-08 14:50:40 -0800141Value::Value(const Value& from) {
142 type = from.getType();
143 switch (type) {
144 case INT:
145 int_value = from.int_value;
146 break;
147 case LONG:
148 long_value = from.long_value;
149 break;
150 case FLOAT:
151 float_value = from.float_value;
152 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700153 case DOUBLE:
154 double_value = from.double_value;
155 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800156 case STRING:
157 str_value = from.str_value;
158 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700159 case STORAGE:
160 storage_value = from.storage_value;
161 break;
Yangster-macf5204922018-02-23 13:08:03 -0800162 default:
163 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800164 }
165}
166
167std::string Value::toString() const {
168 switch (type) {
169 case INT:
170 return std::to_string(int_value) + "[I]";
171 case LONG:
172 return std::to_string(long_value) + "[L]";
173 case FLOAT:
174 return std::to_string(float_value) + "[F]";
Chenjie Yua0f02242018-07-06 16:14:34 -0700175 case DOUBLE:
176 return std::to_string(double_value) + "[D]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800177 case STRING:
178 return str_value + "[S]";
Chenjie Yu12e5e672018-09-14 15:54:59 -0700179 case STORAGE:
180 return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
Yangster-macf5204922018-02-23 13:08:03 -0800181 default:
182 return "[UNKNOWN]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800183 }
184}
185
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700186bool Value::isZero() const {
187 switch (type) {
188 case INT:
189 return int_value == 0;
190 case LONG:
191 return long_value == 0;
192 case FLOAT:
193 return fabs(float_value) <= std::numeric_limits<float>::epsilon();
194 case DOUBLE:
195 return fabs(double_value) <= std::numeric_limits<double>::epsilon();
196 case STRING:
197 return str_value.size() == 0;
198 case STORAGE:
199 return storage_value.size() == 0;
200 default:
201 return false;
202 }
203}
204
Yao Chen8a8d16c2018-02-08 14:50:40 -0800205bool Value::operator==(const Value& that) const {
206 if (type != that.getType()) return false;
207
208 switch (type) {
209 case INT:
210 return int_value == that.int_value;
211 case LONG:
212 return long_value == that.long_value;
213 case FLOAT:
214 return float_value == that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700215 case DOUBLE:
216 return double_value == that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800217 case STRING:
218 return str_value == that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700219 case STORAGE:
220 return storage_value == that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800221 default:
222 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800223 }
224}
225
226bool Value::operator!=(const Value& that) const {
227 if (type != that.getType()) return true;
228 switch (type) {
229 case INT:
230 return int_value != that.int_value;
231 case LONG:
232 return long_value != that.long_value;
233 case FLOAT:
234 return float_value != that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700235 case DOUBLE:
236 return double_value != that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800237 case STRING:
238 return str_value != that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700239 case STORAGE:
240 return storage_value != that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800241 default:
242 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800243 }
244}
245
246bool Value::operator<(const Value& that) const {
247 if (type != that.getType()) return type < that.getType();
248
249 switch (type) {
250 case INT:
251 return int_value < that.int_value;
252 case LONG:
253 return long_value < that.long_value;
254 case FLOAT:
255 return float_value < that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700256 case DOUBLE:
257 return double_value < that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800258 case STRING:
259 return str_value < that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700260 case STORAGE:
261 return storage_value < that.storage_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800262 default:
263 return false;
264 }
265}
266
Chenjie Yua0f02242018-07-06 16:14:34 -0700267bool Value::operator>(const Value& that) const {
268 if (type != that.getType()) return type > that.getType();
269
270 switch (type) {
271 case INT:
272 return int_value > that.int_value;
273 case LONG:
274 return long_value > that.long_value;
275 case FLOAT:
276 return float_value > that.float_value;
277 case DOUBLE:
278 return double_value > that.double_value;
279 case STRING:
280 return str_value > that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700281 case STORAGE:
282 return storage_value > that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700283 default:
284 return false;
285 }
286}
287
288bool Value::operator>=(const Value& that) const {
289 if (type != that.getType()) return type >= that.getType();
290
291 switch (type) {
292 case INT:
293 return int_value >= that.int_value;
294 case LONG:
295 return long_value >= that.long_value;
296 case FLOAT:
297 return float_value >= that.float_value;
298 case DOUBLE:
299 return double_value >= that.double_value;
300 case STRING:
301 return str_value >= that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700302 case STORAGE:
303 return storage_value >= that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700304 default:
305 return false;
306 }
307}
308
309Value Value::operator-(const Value& that) const {
310 Value v;
311 if (type != that.type) {
312 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
313 return v;
314 }
315 if (type == STRING) {
316 ALOGE("Can't operate on string value type");
317 return v;
318 }
319
Chenjie Yu12e5e672018-09-14 15:54:59 -0700320 if (type == STORAGE) {
321 ALOGE("Can't operate on storage value type");
322 return v;
323 }
324
Chenjie Yua0f02242018-07-06 16:14:34 -0700325 switch (type) {
326 case INT:
327 v.setInt(int_value - that.int_value);
328 break;
329 case LONG:
330 v.setLong(long_value - that.long_value);
331 break;
332 case FLOAT:
333 v.setFloat(float_value - that.float_value);
334 break;
335 case DOUBLE:
336 v.setDouble(double_value - that.double_value);
337 break;
338 default:
339 break;
340 }
341 return v;
342}
343
344Value& Value::operator=(const Value& that) {
345 type = that.type;
346 switch (type) {
347 case INT:
348 int_value = that.int_value;
349 break;
350 case LONG:
351 long_value = that.long_value;
352 break;
353 case FLOAT:
354 float_value = that.float_value;
355 break;
356 case DOUBLE:
357 double_value = that.double_value;
358 break;
359 case STRING:
360 str_value = that.str_value;
361 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700362 case STORAGE:
363 storage_value = that.storage_value;
364 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700365 default:
366 break;
367 }
368 return *this;
369}
370
371Value& Value::operator+=(const Value& that) {
372 if (type != that.type) {
373 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
374 return *this;
375 }
376 if (type == STRING) {
377 ALOGE("Can't operate on string value type");
378 return *this;
379 }
Chenjie Yu12e5e672018-09-14 15:54:59 -0700380 if (type == STORAGE) {
381 ALOGE("Can't operate on storage value type");
382 return *this;
383 }
Chenjie Yua0f02242018-07-06 16:14:34 -0700384
385 switch (type) {
386 case INT:
387 int_value += that.int_value;
388 break;
389 case LONG:
390 long_value += that.long_value;
391 break;
392 case FLOAT:
393 float_value += that.float_value;
394 break;
395 case DOUBLE:
396 double_value += that.double_value;
397 break;
398 default:
399 break;
400 }
401 return *this;
402}
403
404double Value::getDouble() const {
405 switch (type) {
406 case INT:
407 return int_value;
408 case LONG:
409 return long_value;
410 case FLOAT:
411 return float_value;
412 case DOUBLE:
413 return double_value;
414 default:
415 return 0;
416 }
417}
418
Yangster13fb7e42018-03-07 17:30:49 -0800419bool equalDimensions(const std::vector<Matcher>& dimension_a,
420 const std::vector<Matcher>& dimension_b) {
421 bool eq = dimension_a.size() == dimension_b.size();
422 for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
423 if (dimension_b[i] != dimension_a[i]) {
424 eq = false;
425 }
426 }
427 return eq;
428}
429
tsaichristine3a83e812019-12-13 16:46:11 -0800430bool subsetDimensions(const std::vector<Matcher>& dimension_a,
431 const std::vector<Matcher>& dimension_b) {
432 if (dimension_a.size() > dimension_b.size()) {
433 return false;
434 }
435 for (size_t i = 0; i < dimension_a.size(); ++i) {
436 bool found = false;
437 for (size_t j = 0; j < dimension_b.size(); ++j) {
438 if (dimension_a[i] == dimension_b[j]) {
439 found = true;
440 }
441 }
442 if (!found) {
443 return false;
444 }
445 }
446 return true;
447}
448
Yangster13fb7e42018-03-07 17:30:49 -0800449bool HasPositionANY(const FieldMatcher& matcher) {
450 if (matcher.has_position() && matcher.position() == Position::ANY) {
451 return true;
452 }
453 for (const auto& child : matcher.child()) {
454 if (HasPositionANY(child)) {
455 return true;
456 }
457 }
458 return false;
459}
460
Yangster-mac9def8e32018-04-17 13:55:51 -0700461bool HasPositionALL(const FieldMatcher& matcher) {
462 if (matcher.has_position() && matcher.position() == Position::ALL) {
463 return true;
464 }
465 for (const auto& child : matcher.child()) {
466 if (HasPositionALL(child)) {
467 return true;
468 }
469 }
470 return false;
471}
472
Yao Chen8a8d16c2018-02-08 14:50:40 -0800473} // namespace statsd
474} // namespace os
tsaichristine7a57b8e2019-06-24 18:25:38 -0700475} // namespace android