blob: 1185127ab805cd3fbd324d7f8865e7010ff64ec5 [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"
Chenjie Yuc715b9e2018-10-19 07:52:12 -070021#include "math.h"
Yao Chen4ce07292019-02-13 13:06:36 -080022#include "statslog.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) {
119 int field = value.mField.getField() & 0xff007f;
120 if (field == 0x10001 && value.mValue.getType() == INT) {
121 return true;
122 }
123 return false;
124}
125
Yao Chen4ce07292019-02-13 13:06:36 -0800126int32_t getUidIfExists(const FieldValue& value) {
127 bool isUid = false;
128 // the field is uid field if the field is the uid field in attribution node or marked as
129 // is_uid in atoms.proto
130 if (isAttributionUidField(value)) {
131 isUid = true;
132 } else {
133 auto it = android::util::AtomsInfo::kAtomsWithUidField.find(value.mField.getTag());
134 if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) {
135 int uidField = it->second; // uidField is the field number in proto
136 isUid = value.mField.getDepth() == 0 && value.mField.getPosAtDepth(0) == uidField &&
137 value.mValue.getType() == INT;
138 }
139 }
140
141 return isUid ? value.mValue.int_value : -1;
142}
143
Yao Chen8a8d16c2018-02-08 14:50:40 -0800144bool isAttributionUidField(const Field& field, const Value& value) {
145 int f = field.getField() & 0xff007f;
146 if (f == 0x10001 && value.getType() == INT) {
147 return true;
148 }
149 return false;
150}
151
tsaichristine7a57b8e2019-06-24 18:25:38 -0700152bool isUidField(const Field& field, const Value& value) {
153 auto it = android::util::AtomsInfo::kAtomsWithUidField.find(field.getTag());
154
155 if (it != android::util::AtomsInfo::kAtomsWithUidField.end()) {
156 int uidField = it->second;
157 return field.getDepth() == 0 && field.getPosAtDepth(0) == uidField &&
158 value.getType() == INT;
159 }
160
161 return false;
162}
163
Yao Chen8a8d16c2018-02-08 14:50:40 -0800164Value::Value(const Value& from) {
165 type = from.getType();
166 switch (type) {
167 case INT:
168 int_value = from.int_value;
169 break;
170 case LONG:
171 long_value = from.long_value;
172 break;
173 case FLOAT:
174 float_value = from.float_value;
175 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700176 case DOUBLE:
177 double_value = from.double_value;
178 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800179 case STRING:
180 str_value = from.str_value;
181 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700182 case STORAGE:
183 storage_value = from.storage_value;
184 break;
Yangster-macf5204922018-02-23 13:08:03 -0800185 default:
186 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800187 }
188}
189
190std::string Value::toString() const {
191 switch (type) {
192 case INT:
193 return std::to_string(int_value) + "[I]";
194 case LONG:
195 return std::to_string(long_value) + "[L]";
196 case FLOAT:
197 return std::to_string(float_value) + "[F]";
Chenjie Yua0f02242018-07-06 16:14:34 -0700198 case DOUBLE:
199 return std::to_string(double_value) + "[D]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800200 case STRING:
201 return str_value + "[S]";
Chenjie Yu12e5e672018-09-14 15:54:59 -0700202 case STORAGE:
203 return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
Yangster-macf5204922018-02-23 13:08:03 -0800204 default:
205 return "[UNKNOWN]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800206 }
207}
208
Chenjie Yuc715b9e2018-10-19 07:52:12 -0700209bool Value::isZero() const {
210 switch (type) {
211 case INT:
212 return int_value == 0;
213 case LONG:
214 return long_value == 0;
215 case FLOAT:
216 return fabs(float_value) <= std::numeric_limits<float>::epsilon();
217 case DOUBLE:
218 return fabs(double_value) <= std::numeric_limits<double>::epsilon();
219 case STRING:
220 return str_value.size() == 0;
221 case STORAGE:
222 return storage_value.size() == 0;
223 default:
224 return false;
225 }
226}
227
Yao Chen8a8d16c2018-02-08 14:50:40 -0800228bool Value::operator==(const Value& that) const {
229 if (type != that.getType()) return false;
230
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;
Chenjie Yua0f02242018-07-06 16:14:34 -0700238 case DOUBLE:
239 return double_value == that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800240 case STRING:
241 return str_value == that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700242 case STORAGE:
243 return storage_value == that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800244 default:
245 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800246 }
247}
248
249bool Value::operator!=(const Value& that) const {
250 if (type != that.getType()) return true;
251 switch (type) {
252 case INT:
253 return int_value != that.int_value;
254 case LONG:
255 return long_value != that.long_value;
256 case FLOAT:
257 return float_value != that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700258 case DOUBLE:
259 return double_value != that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800260 case STRING:
261 return str_value != that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700262 case STORAGE:
263 return storage_value != that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800264 default:
265 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800266 }
267}
268
269bool Value::operator<(const Value& that) const {
270 if (type != that.getType()) return type < that.getType();
271
272 switch (type) {
273 case INT:
274 return int_value < that.int_value;
275 case LONG:
276 return long_value < that.long_value;
277 case FLOAT:
278 return float_value < that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700279 case DOUBLE:
280 return double_value < that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800281 case STRING:
282 return str_value < that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700283 case STORAGE:
284 return storage_value < that.storage_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800285 default:
286 return false;
287 }
288}
289
Chenjie Yua0f02242018-07-06 16:14:34 -0700290bool Value::operator>(const Value& that) const {
291 if (type != that.getType()) return type > that.getType();
292
293 switch (type) {
294 case INT:
295 return int_value > that.int_value;
296 case LONG:
297 return long_value > that.long_value;
298 case FLOAT:
299 return float_value > that.float_value;
300 case DOUBLE:
301 return double_value > that.double_value;
302 case STRING:
303 return str_value > that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700304 case STORAGE:
305 return storage_value > that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700306 default:
307 return false;
308 }
309}
310
311bool Value::operator>=(const Value& that) const {
312 if (type != that.getType()) return type >= that.getType();
313
314 switch (type) {
315 case INT:
316 return int_value >= that.int_value;
317 case LONG:
318 return long_value >= that.long_value;
319 case FLOAT:
320 return float_value >= that.float_value;
321 case DOUBLE:
322 return double_value >= that.double_value;
323 case STRING:
324 return str_value >= that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700325 case STORAGE:
326 return storage_value >= that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700327 default:
328 return false;
329 }
330}
331
332Value Value::operator-(const Value& that) const {
333 Value v;
334 if (type != that.type) {
335 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
336 return v;
337 }
338 if (type == STRING) {
339 ALOGE("Can't operate on string value type");
340 return v;
341 }
342
Chenjie Yu12e5e672018-09-14 15:54:59 -0700343 if (type == STORAGE) {
344 ALOGE("Can't operate on storage value type");
345 return v;
346 }
347
Chenjie Yua0f02242018-07-06 16:14:34 -0700348 switch (type) {
349 case INT:
350 v.setInt(int_value - that.int_value);
351 break;
352 case LONG:
353 v.setLong(long_value - that.long_value);
354 break;
355 case FLOAT:
356 v.setFloat(float_value - that.float_value);
357 break;
358 case DOUBLE:
359 v.setDouble(double_value - that.double_value);
360 break;
361 default:
362 break;
363 }
364 return v;
365}
366
367Value& Value::operator=(const Value& that) {
368 type = that.type;
369 switch (type) {
370 case INT:
371 int_value = that.int_value;
372 break;
373 case LONG:
374 long_value = that.long_value;
375 break;
376 case FLOAT:
377 float_value = that.float_value;
378 break;
379 case DOUBLE:
380 double_value = that.double_value;
381 break;
382 case STRING:
383 str_value = that.str_value;
384 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700385 case STORAGE:
386 storage_value = that.storage_value;
387 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700388 default:
389 break;
390 }
391 return *this;
392}
393
394Value& Value::operator+=(const Value& that) {
395 if (type != that.type) {
396 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
397 return *this;
398 }
399 if (type == STRING) {
400 ALOGE("Can't operate on string value type");
401 return *this;
402 }
Chenjie Yu12e5e672018-09-14 15:54:59 -0700403 if (type == STORAGE) {
404 ALOGE("Can't operate on storage value type");
405 return *this;
406 }
Chenjie Yua0f02242018-07-06 16:14:34 -0700407
408 switch (type) {
409 case INT:
410 int_value += that.int_value;
411 break;
412 case LONG:
413 long_value += that.long_value;
414 break;
415 case FLOAT:
416 float_value += that.float_value;
417 break;
418 case DOUBLE:
419 double_value += that.double_value;
420 break;
421 default:
422 break;
423 }
424 return *this;
425}
426
427double Value::getDouble() const {
428 switch (type) {
429 case INT:
430 return int_value;
431 case LONG:
432 return long_value;
433 case FLOAT:
434 return float_value;
435 case DOUBLE:
436 return double_value;
437 default:
438 return 0;
439 }
440}
441
Yangster13fb7e42018-03-07 17:30:49 -0800442bool equalDimensions(const std::vector<Matcher>& dimension_a,
443 const std::vector<Matcher>& dimension_b) {
444 bool eq = dimension_a.size() == dimension_b.size();
445 for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
446 if (dimension_b[i] != dimension_a[i]) {
447 eq = false;
448 }
449 }
450 return eq;
451}
452
453bool HasPositionANY(const FieldMatcher& matcher) {
454 if (matcher.has_position() && matcher.position() == Position::ANY) {
455 return true;
456 }
457 for (const auto& child : matcher.child()) {
458 if (HasPositionANY(child)) {
459 return true;
460 }
461 }
462 return false;
463}
464
Yangster-mac9def8e32018-04-17 13:55:51 -0700465bool HasPositionALL(const FieldMatcher& matcher) {
466 if (matcher.has_position() && matcher.position() == Position::ALL) {
467 return true;
468 }
469 for (const auto& child : matcher.child()) {
470 if (HasPositionALL(child)) {
471 return true;
472 }
473 }
474 return false;
475}
476
Yao Chen8a8d16c2018-02-08 14:50:40 -0800477} // namespace statsd
478} // namespace os
tsaichristine7a57b8e2019-06-24 18:25:38 -0700479} // namespace android