blob: fc1a61cac558547b718e380ba15c31d5ff4628a0 [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"
21
22namespace android {
23namespace os {
24namespace statsd {
25
Yao Chen4c959cb2018-02-13 13:27:48 -080026int32_t getEncodedField(int32_t pos[], int32_t depth, bool includeDepth) {
27 int32_t field = 0;
28 for (int32_t i = 0; i <= depth; i++) {
29 int32_t shiftBits = 8 * (kMaxLogDepth - i);
30 field |= (pos[i] << shiftBits);
31 }
32
33 if (includeDepth) {
34 field |= (depth << 24);
35 }
36 return field;
37}
38
39int32_t encodeMatcherMask(int32_t mask[], int32_t depth) {
40 return getEncodedField(mask, depth, false) | 0xff000000;
41}
42
Yao Chen8a8d16c2018-02-08 14:50:40 -080043bool Field::matches(const Matcher& matcher) const {
44 if (mTag != matcher.mMatcher.getTag()) {
45 return false;
46 }
47 if ((mField & matcher.mMask) == matcher.mMatcher.getField()) {
48 return true;
49 }
50
Yangster-mace06cfd72018-03-10 23:22:59 -080051 if (matcher.hasAllPositionMatcher() &&
52 (mField & (matcher.mMask & kClearAllPositionMatcherMask)) == matcher.mMatcher.getField()) {
53 return true;
54 }
55
Yao Chen8a8d16c2018-02-08 14:50:40 -080056 return false;
Yao Chen4c959cb2018-02-13 13:27:48 -080057}
Yao Chen8a8d16c2018-02-08 14:50:40 -080058
59void translateFieldMatcher(int tag, const FieldMatcher& matcher, int depth, int* pos, int* mask,
60 std::vector<Matcher>* output) {
61 if (depth > kMaxLogDepth) {
62 ALOGE("depth > 2");
63 return;
64 }
65
66 pos[depth] = matcher.field();
67 mask[depth] = 0x7f;
68
69 if (matcher.has_position()) {
70 depth++;
71 if (depth > 2) {
72 return;
73 }
74 switch (matcher.position()) {
Yangster-mace06cfd72018-03-10 23:22:59 -080075 case Position::ALL:
76 pos[depth] = 0x00;
77 mask[depth] = 0x7f;
78 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -080079 case Position::ANY:
80 pos[depth] = 0;
81 mask[depth] = 0;
82 break;
83 case Position::FIRST:
84 pos[depth] = 1;
85 mask[depth] = 0x7f;
86 break;
87 case Position::LAST:
88 pos[depth] = 0x80;
89 mask[depth] = 0x80;
90 break;
91 case Position::POSITION_UNKNOWN:
92 pos[depth] = 0;
93 mask[depth] = 0;
94 break;
95 }
96 }
97
98 if (matcher.child_size() == 0) {
99 output->push_back(Matcher(Field(tag, pos, depth), encodeMatcherMask(mask, depth)));
Yao Chen8a8d16c2018-02-08 14:50:40 -0800100 } else {
101 for (const auto& child : matcher.child()) {
102 translateFieldMatcher(tag, child, depth + 1, pos, mask, output);
103 }
104 }
105}
106
107void translateFieldMatcher(const FieldMatcher& matcher, std::vector<Matcher>* output) {
108 int pos[] = {1, 1, 1};
109 int mask[] = {0x7f, 0x7f, 0x7f};
110 int tag = matcher.field();
111 for (const auto& child : matcher.child()) {
112 translateFieldMatcher(tag, child, 0, pos, mask, output);
113 }
114}
115
116bool isAttributionUidField(const FieldValue& value) {
117 int field = value.mField.getField() & 0xff007f;
118 if (field == 0x10001 && value.mValue.getType() == INT) {
119 return true;
120 }
121 return false;
122}
123
124bool isAttributionUidField(const Field& field, const Value& value) {
125 int f = field.getField() & 0xff007f;
126 if (f == 0x10001 && value.getType() == INT) {
127 return true;
128 }
129 return false;
130}
131
132Value::Value(const Value& from) {
133 type = from.getType();
134 switch (type) {
135 case INT:
136 int_value = from.int_value;
137 break;
138 case LONG:
139 long_value = from.long_value;
140 break;
141 case FLOAT:
142 float_value = from.float_value;
143 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700144 case DOUBLE:
145 double_value = from.double_value;
146 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800147 case STRING:
148 str_value = from.str_value;
149 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700150 case STORAGE:
151 storage_value = from.storage_value;
152 break;
Yangster-macf5204922018-02-23 13:08:03 -0800153 default:
154 break;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800155 }
156}
157
158std::string Value::toString() const {
159 switch (type) {
160 case INT:
161 return std::to_string(int_value) + "[I]";
162 case LONG:
163 return std::to_string(long_value) + "[L]";
164 case FLOAT:
165 return std::to_string(float_value) + "[F]";
Chenjie Yua0f02242018-07-06 16:14:34 -0700166 case DOUBLE:
167 return std::to_string(double_value) + "[D]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800168 case STRING:
169 return str_value + "[S]";
Chenjie Yu12e5e672018-09-14 15:54:59 -0700170 case STORAGE:
171 return "bytes of size " + std::to_string(storage_value.size()) + "[ST]";
Yangster-macf5204922018-02-23 13:08:03 -0800172 default:
173 return "[UNKNOWN]";
Yao Chen8a8d16c2018-02-08 14:50:40 -0800174 }
175}
176
177bool Value::operator==(const Value& that) const {
178 if (type != that.getType()) return false;
179
180 switch (type) {
181 case INT:
182 return int_value == that.int_value;
183 case LONG:
184 return long_value == that.long_value;
185 case FLOAT:
186 return float_value == that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700187 case DOUBLE:
188 return double_value == that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800189 case STRING:
190 return str_value == that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700191 case STORAGE:
192 return storage_value == that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800193 default:
194 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800195 }
196}
197
198bool Value::operator!=(const Value& that) const {
199 if (type != that.getType()) return true;
200 switch (type) {
201 case INT:
202 return int_value != that.int_value;
203 case LONG:
204 return long_value != that.long_value;
205 case FLOAT:
206 return float_value != that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700207 case DOUBLE:
208 return double_value != that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800209 case STRING:
210 return str_value != that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700211 case STORAGE:
212 return storage_value != that.storage_value;
Yangster-macf5204922018-02-23 13:08:03 -0800213 default:
214 return false;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800215 }
216}
217
218bool Value::operator<(const Value& that) const {
219 if (type != that.getType()) return type < that.getType();
220
221 switch (type) {
222 case INT:
223 return int_value < that.int_value;
224 case LONG:
225 return long_value < that.long_value;
226 case FLOAT:
227 return float_value < that.float_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700228 case DOUBLE:
229 return double_value < that.double_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800230 case STRING:
231 return str_value < that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700232 case STORAGE:
233 return storage_value < that.storage_value;
Yao Chen8a8d16c2018-02-08 14:50:40 -0800234 default:
235 return false;
236 }
237}
238
Chenjie Yua0f02242018-07-06 16:14:34 -0700239bool Value::operator>(const Value& that) const {
240 if (type != that.getType()) return type > that.getType();
241
242 switch (type) {
243 case INT:
244 return int_value > that.int_value;
245 case LONG:
246 return long_value > that.long_value;
247 case FLOAT:
248 return float_value > that.float_value;
249 case DOUBLE:
250 return double_value > that.double_value;
251 case STRING:
252 return str_value > that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700253 case STORAGE:
254 return storage_value > that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700255 default:
256 return false;
257 }
258}
259
260bool Value::operator>=(const Value& that) const {
261 if (type != that.getType()) return type >= that.getType();
262
263 switch (type) {
264 case INT:
265 return int_value >= that.int_value;
266 case LONG:
267 return long_value >= that.long_value;
268 case FLOAT:
269 return float_value >= that.float_value;
270 case DOUBLE:
271 return double_value >= that.double_value;
272 case STRING:
273 return str_value >= that.str_value;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700274 case STORAGE:
275 return storage_value >= that.storage_value;
Chenjie Yua0f02242018-07-06 16:14:34 -0700276 default:
277 return false;
278 }
279}
280
281Value Value::operator-(const Value& that) const {
282 Value v;
283 if (type != that.type) {
284 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
285 return v;
286 }
287 if (type == STRING) {
288 ALOGE("Can't operate on string value type");
289 return v;
290 }
291
Chenjie Yu12e5e672018-09-14 15:54:59 -0700292 if (type == STORAGE) {
293 ALOGE("Can't operate on storage value type");
294 return v;
295 }
296
Chenjie Yua0f02242018-07-06 16:14:34 -0700297 switch (type) {
298 case INT:
299 v.setInt(int_value - that.int_value);
300 break;
301 case LONG:
302 v.setLong(long_value - that.long_value);
303 break;
304 case FLOAT:
305 v.setFloat(float_value - that.float_value);
306 break;
307 case DOUBLE:
308 v.setDouble(double_value - that.double_value);
309 break;
310 default:
311 break;
312 }
313 return v;
314}
315
316Value& Value::operator=(const Value& that) {
317 type = that.type;
318 switch (type) {
319 case INT:
320 int_value = that.int_value;
321 break;
322 case LONG:
323 long_value = that.long_value;
324 break;
325 case FLOAT:
326 float_value = that.float_value;
327 break;
328 case DOUBLE:
329 double_value = that.double_value;
330 break;
331 case STRING:
332 str_value = that.str_value;
333 break;
Chenjie Yu12e5e672018-09-14 15:54:59 -0700334 case STORAGE:
335 storage_value = that.storage_value;
336 break;
Chenjie Yua0f02242018-07-06 16:14:34 -0700337 default:
338 break;
339 }
340 return *this;
341}
342
343Value& Value::operator+=(const Value& that) {
344 if (type != that.type) {
345 ALOGE("Can't operate on different value types, %d, %d", type, that.type);
346 return *this;
347 }
348 if (type == STRING) {
349 ALOGE("Can't operate on string value type");
350 return *this;
351 }
Chenjie Yu12e5e672018-09-14 15:54:59 -0700352 if (type == STORAGE) {
353 ALOGE("Can't operate on storage value type");
354 return *this;
355 }
Chenjie Yua0f02242018-07-06 16:14:34 -0700356
357 switch (type) {
358 case INT:
359 int_value += that.int_value;
360 break;
361 case LONG:
362 long_value += that.long_value;
363 break;
364 case FLOAT:
365 float_value += that.float_value;
366 break;
367 case DOUBLE:
368 double_value += that.double_value;
369 break;
370 default:
371 break;
372 }
373 return *this;
374}
375
376double Value::getDouble() const {
377 switch (type) {
378 case INT:
379 return int_value;
380 case LONG:
381 return long_value;
382 case FLOAT:
383 return float_value;
384 case DOUBLE:
385 return double_value;
386 default:
387 return 0;
388 }
389}
390
Yangster13fb7e42018-03-07 17:30:49 -0800391bool equalDimensions(const std::vector<Matcher>& dimension_a,
392 const std::vector<Matcher>& dimension_b) {
393 bool eq = dimension_a.size() == dimension_b.size();
394 for (size_t i = 0; eq && i < dimension_a.size(); ++i) {
395 if (dimension_b[i] != dimension_a[i]) {
396 eq = false;
397 }
398 }
399 return eq;
400}
401
402bool HasPositionANY(const FieldMatcher& matcher) {
403 if (matcher.has_position() && matcher.position() == Position::ANY) {
404 return true;
405 }
406 for (const auto& child : matcher.child()) {
407 if (HasPositionANY(child)) {
408 return true;
409 }
410 }
411 return false;
412}
413
Yangster-mac9def8e32018-04-17 13:55:51 -0700414bool HasPositionALL(const FieldMatcher& matcher) {
415 if (matcher.has_position() && matcher.position() == Position::ALL) {
416 return true;
417 }
418 for (const auto& child : matcher.child()) {
419 if (HasPositionALL(child)) {
420 return true;
421 }
422 }
423 return false;
424}
425
Yao Chen8a8d16c2018-02-08 14:50:40 -0800426} // namespace statsd
427} // namespace os
428} // namespace android