blob: 04445ca0e230b2e6ac5f24aa8ecdf6446efb297f [file] [log] [blame]
Yangster-mac20877162017-12-22 17:19:39 -08001/*
2 * Copyright (C) 2017 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#include "Log.h"
18
19#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
Yangster-macd19bcae42018-01-04 15:43:39 -080020#include "frameworks/base/cmds/statsd/src/statsd_internal.pb.h"
Yangster-mac20877162017-12-22 17:19:39 -080021#include "dimension.h"
Yangster-mac20877162017-12-22 17:19:39 -080022
23
24namespace android {
25namespace os {
26namespace statsd {
27
28const DimensionsValue* getSingleLeafValue(const DimensionsValue* value) {
29 if (value->value_case() == DimensionsValue::ValueCase::kValueTuple) {
30 return getSingleLeafValue(&value->value_tuple().dimensions_value(0));
31 } else {
32 return value;
33 }
34}
35
36DimensionsValue getSingleLeafValue(const DimensionsValue& value) {
37 const DimensionsValue* leafValue = getSingleLeafValue(&value);
38 return *leafValue;
39}
40
Yangster-mac7ba8fc32018-01-24 16:16:46 -080041void appendLeafNodeToTree(const Field& field,
Yangster-mac20877162017-12-22 17:19:39 -080042 const DimensionsValue& value,
43 DimensionsValue* parentValue) {
44 if (field.child_size() <= 0) {
45 *parentValue = value;
46 parentValue->set_field(field.field());
47 return;
48 }
49 parentValue->set_field(field.field());
50 int idx = -1;
51 for (int i = 0; i < parentValue->mutable_value_tuple()->dimensions_value_size(); ++i) {
52 if (parentValue->mutable_value_tuple()->dimensions_value(i).field() ==
53 field.child(0).field()) {
54 idx = i;
55 }
56 }
57 if (idx < 0) {
58 parentValue->mutable_value_tuple()->add_dimensions_value();
59 idx = parentValue->mutable_value_tuple()->dimensions_value_size() - 1;
60 }
Yangster-mac7ba8fc32018-01-24 16:16:46 -080061 appendLeafNodeToTree(
Yangster-mac20877162017-12-22 17:19:39 -080062 field.child(0), value,
63 parentValue->mutable_value_tuple()->mutable_dimensions_value(idx));
64}
65
Yangster-mac7ba8fc32018-01-24 16:16:46 -080066void appendLeafNodeToTrees(const Field& field,
67 const DimensionsValue& node,
68 std::vector<DimensionsValue>* rootTrees) {
69 if (rootTrees == nullptr) {
Yangster-mac20877162017-12-22 17:19:39 -080070 return;
71 }
Yangster-mac7ba8fc32018-01-24 16:16:46 -080072 if (rootTrees->empty()) {
73 DimensionsValue tree;
74 appendLeafNodeToTree(field, node, &tree);
75 rootTrees->push_back(tree);
Yangster-mac20877162017-12-22 17:19:39 -080076 } else {
Yangster-mac7ba8fc32018-01-24 16:16:46 -080077 for (size_t i = 0; i < rootTrees->size(); ++i) {
78 appendLeafNodeToTree(field, node, &rootTrees->at(i));
Yangster-mac20877162017-12-22 17:19:39 -080079 }
80 }
81}
82
83namespace {
84
85void findDimensionsValues(
86 const FieldValueMap& fieldValueMap,
87 const FieldMatcher& matcher,
Yangster-mac7ba8fc32018-01-24 16:16:46 -080088 Field* rootField,
89 Field* leafField,
Yangster-mac20877162017-12-22 17:19:39 -080090 std::vector<DimensionsValue>* rootDimensionsValues);
91
92void findNonRepeatedDimensionsValues(
93 const FieldValueMap& fieldValueMap,
94 const FieldMatcher& matcher,
Yangster-mac7ba8fc32018-01-24 16:16:46 -080095 Field* rootField,
96 Field* leafField,
Yangster-mac20877162017-12-22 17:19:39 -080097 std::vector<DimensionsValue>* rootValues) {
98 if (matcher.child_size() > 0) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -080099 Field* newLeafField = leafField->add_child();
Yangster-mac20877162017-12-22 17:19:39 -0800100 for (const auto& childMatcher : matcher.child()) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800101 newLeafField->set_field(childMatcher.field());
102 findDimensionsValues(fieldValueMap, childMatcher, rootField, newLeafField, rootValues);
Yangster-mac20877162017-12-22 17:19:39 -0800103 }
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800104 leafField->clear_child();
Yangster-mac20877162017-12-22 17:19:39 -0800105 } else {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800106 auto ret = fieldValueMap.equal_range(*rootField);
Yangster-mac20877162017-12-22 17:19:39 -0800107 int found = 0;
108 for (auto it = ret.first; it != ret.second; ++it) {
109 found++;
110 }
111 // Not found.
112 if (found <= 0) {
113 return;
114 }
115 if (found > 1) {
116 ALOGE("Found multiple values for optional field.");
117 return;
118 }
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800119 appendLeafNodeToTrees(*rootField, ret.first->second, rootValues);
Yangster-mac20877162017-12-22 17:19:39 -0800120 }
121}
122
123void findRepeatedDimensionsValues(const FieldValueMap& fieldValueMap,
124 const FieldMatcher& matcher,
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800125 Field* rootField,
126 Field* leafField,
Yangster-mac20877162017-12-22 17:19:39 -0800127 std::vector<DimensionsValue>* rootValues) {
128 if (matcher.position() == Position::FIRST) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800129 leafField->set_position_index(0);
130 findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField, rootValues);
131 leafField->clear_position_index();
Yangster-mac20877162017-12-22 17:19:39 -0800132 } else {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800133 auto itLower = fieldValueMap.lower_bound(*rootField);
Yangster-mac20877162017-12-22 17:19:39 -0800134 if (itLower == fieldValueMap.end()) {
135 return;
136 }
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800137 const int leafFieldNum = leafField->field();
138 leafField->set_field(leafFieldNum + 1);
139 auto itUpper = fieldValueMap.lower_bound(*rootField);
140 // Resets the field number.
141 leafField->set_field(leafFieldNum);
Yangster-mac20877162017-12-22 17:19:39 -0800142
143 switch (matcher.position()) {
144 case Position::LAST:
145 {
146 itUpper--;
147 if (itUpper != fieldValueMap.end()) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800148 int last_index = getPositionByReferenceField(*rootField, itUpper->first);
Yangster-mac20877162017-12-22 17:19:39 -0800149 if (last_index < 0) {
150 return;
151 }
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800152 leafField->set_position_index(last_index);
Yangster-mac20877162017-12-22 17:19:39 -0800153 findNonRepeatedDimensionsValues(
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800154 fieldValueMap, matcher, rootField, leafField, rootValues);
155 leafField->clear_position_index();
Yangster-mac20877162017-12-22 17:19:39 -0800156 }
157 }
158 break;
159 case Position::ANY:
160 {
161 std::set<int> indexes;
162 for (auto it = itLower; it != itUpper; ++it) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800163 int index = getPositionByReferenceField(*rootField, it->first);
Yangster-mac20877162017-12-22 17:19:39 -0800164 if (index >= 0) {
165 indexes.insert(index);
166 }
167 }
168 if (!indexes.empty()) {
Yangster-mac20877162017-12-22 17:19:39 -0800169 std::vector<DimensionsValue> allValues;
170 for (const int index : indexes) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800171 leafField->set_position_index(index);
Yangster-mac20877162017-12-22 17:19:39 -0800172 std::vector<DimensionsValue> newValues = *rootValues;
173 findNonRepeatedDimensionsValues(
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800174 fieldValueMap, matcher, rootField, leafField, &newValues);
Yangster-mac20877162017-12-22 17:19:39 -0800175 allValues.insert(allValues.end(), newValues.begin(), newValues.end());
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800176 leafField->clear_position_index();
Yangster-mac20877162017-12-22 17:19:39 -0800177 }
178 rootValues->clear();
179 rootValues->insert(rootValues->end(), allValues.begin(), allValues.end());
180 }
181 }
182 break;
183 default:
184 break;
185 }
186 }
187}
188
189void findDimensionsValues(
190 const FieldValueMap& fieldValueMap,
191 const FieldMatcher& matcher,
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800192 Field* rootField,
193 Field* leafField,
Yangster-mac20877162017-12-22 17:19:39 -0800194 std::vector<DimensionsValue>* rootDimensionsValues) {
195 if (!matcher.has_position()) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800196 findNonRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
197 rootDimensionsValues);
Yangster-mac20877162017-12-22 17:19:39 -0800198 } else {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800199 findRepeatedDimensionsValues(fieldValueMap, matcher, rootField, leafField,
200 rootDimensionsValues);
Yangster-mac20877162017-12-22 17:19:39 -0800201 }
202}
203
204} // namespace
205
206void findDimensionsValues(
207 const FieldValueMap& fieldValueMap,
208 const FieldMatcher& matcher,
209 std::vector<DimensionsValue>* rootDimensionsValues) {
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800210 Field rootField;
211 buildSimpleAtomField(matcher.field(), &rootField);
212 findDimensionsValues(fieldValueMap, matcher, &rootField, &rootField, rootDimensionsValues);
Yangster-mac20877162017-12-22 17:19:39 -0800213}
214
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800215void buildSimpleAtomFieldMatcher(const int tagId, FieldMatcher* matcher) {
216 matcher->set_field(tagId);
Yangster-mac20877162017-12-22 17:19:39 -0800217}
218
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800219void buildSimpleAtomFieldMatcher(const int tagId, const int fieldNum, FieldMatcher* matcher) {
220 matcher->set_field(tagId);
221 matcher->add_child()->set_field(fieldNum);
Yangster-mac20877162017-12-22 17:19:39 -0800222}
223
224constexpr int ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO = 1;
225constexpr int UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 1;
226constexpr int TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 2;
227
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800228void buildAttributionUidFieldMatcher(const int tagId, const Position position,
229 FieldMatcher* matcher) {
230 matcher->set_field(tagId);
231 auto child = matcher->add_child();
Yangster-mac20877162017-12-22 17:19:39 -0800232 child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
233 child->set_position(position);
Yangster-macd40053e2018-01-09 16:29:22 -0800234 child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
Yangster-mac20877162017-12-22 17:19:39 -0800235}
236
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800237void buildAttributionTagFieldMatcher(const int tagId, const Position position,
238 FieldMatcher* matcher) {
239 matcher->set_field(tagId);
240 FieldMatcher* child = matcher->add_child();
Yangster-mac20877162017-12-22 17:19:39 -0800241 child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
242 child->set_position(position);
Yangster-macd40053e2018-01-09 16:29:22 -0800243 child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
Yangster-macd40053e2018-01-09 16:29:22 -0800244}
245
Yangster-mac7ba8fc32018-01-24 16:16:46 -0800246void buildAttributionFieldMatcher(const int tagId, const Position position, FieldMatcher* matcher) {
247 matcher->set_field(tagId);
248 FieldMatcher* child = matcher->add_child();
Yangster-macd40053e2018-01-09 16:29:22 -0800249 child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
250 child->set_position(position);
251 child->add_child()->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
252 child->add_child()->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
Yangster-mac20877162017-12-22 17:19:39 -0800253}
254
255void DimensionsValueToString(const DimensionsValue& value, std::string *flattened) {
256 *flattened += std::to_string(value.field());
257 *flattened += ":";
258 switch (value.value_case()) {
259 case DimensionsValue::ValueCase::kValueStr:
260 *flattened += value.value_str();
261 break;
262 case DimensionsValue::ValueCase::kValueInt:
263 *flattened += std::to_string(value.value_int());
264 break;
265 case DimensionsValue::ValueCase::kValueLong:
266 *flattened += std::to_string(value.value_long());
267 break;
268 case DimensionsValue::ValueCase::kValueBool:
269 *flattened += std::to_string(value.value_bool());
270 break;
271 case DimensionsValue::ValueCase::kValueFloat:
272 *flattened += std::to_string(value.value_float());
273 break;
274 case DimensionsValue::ValueCase::kValueTuple:
275 {
276 *flattened += "{";
277 for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
278 DimensionsValueToString(value.value_tuple().dimensions_value(i), flattened);
279 *flattened += "|";
280 }
281 *flattened += "}";
282 }
283 break;
284 case DimensionsValue::ValueCase::VALUE_NOT_SET:
285 break;
286 }
287}
288
Yangster-mac20877162017-12-22 17:19:39 -0800289std::string DimensionsValueToString(const DimensionsValue& value) {
290 std::string flatten;
291 DimensionsValueToString(value, &flatten);
292 return flatten;
293}
294
295bool IsSubDimension(const DimensionsValue& dimension, const DimensionsValue& sub) {
296 if (dimension.field() != sub.field()) {
297 return false;
298 }
299 if (dimension.value_case() != sub.value_case()) {
300 return false;
301 }
302 switch (dimension.value_case()) {
303 case DimensionsValue::ValueCase::kValueStr:
304 return dimension.value_str() == sub.value_str();
305 case DimensionsValue::ValueCase::kValueInt:
306 return dimension.value_int() == sub.value_int();
307 case DimensionsValue::ValueCase::kValueLong:
308 return dimension.value_long() == sub.value_long();
309 case DimensionsValue::ValueCase::kValueBool:
310 return dimension.value_bool() == sub.value_bool();
311 case DimensionsValue::ValueCase::kValueFloat:
312 return dimension.value_float() == sub.value_float();
313 case DimensionsValue::ValueCase::kValueTuple: {
Yangster-mac5503f5c2018-01-15 23:20:44 -0800314 if (dimension.value_tuple().dimensions_value_size() <
315 sub.value_tuple().dimensions_value_size()) {
Yangster-mac20877162017-12-22 17:19:39 -0800316 return false;
317 }
318 bool allSub = true;
Yangster-mac5503f5c2018-01-15 23:20:44 -0800319 for (int i = 0; allSub && i < sub.value_tuple().dimensions_value_size(); ++i) {
Yangster-mac20877162017-12-22 17:19:39 -0800320 bool isSub = false;
Yangster-mac5503f5c2018-01-15 23:20:44 -0800321 for (int j = 0; !isSub &&
322 j < dimension.value_tuple().dimensions_value_size(); ++j) {
Yangster-mac20877162017-12-22 17:19:39 -0800323 isSub |= IsSubDimension(dimension.value_tuple().dimensions_value(j),
324 sub.value_tuple().dimensions_value(i));
325 }
326 allSub &= isSub;
327 }
328 return allSub;
329 }
330 break;
331 case DimensionsValue::ValueCase::VALUE_NOT_SET:
332 return false;
333 default:
334 return false;
335 }
336}
337
Yangster-maca7fb12d2018-01-03 17:17:20 -0800338long getLongFromDimenValue(const DimensionsValue& dimensionValue) {
339 switch (dimensionValue.value_case()) {
340 case DimensionsValue::ValueCase::kValueInt:
341 return dimensionValue.value_int();
342 case DimensionsValue::ValueCase::kValueLong:
343 return dimensionValue.value_long();
344 case DimensionsValue::ValueCase::kValueBool:
345 return dimensionValue.value_bool() ? 1 : 0;
346 case DimensionsValue::ValueCase::kValueFloat:
347 return (int64_t)dimensionValue.value_float();
348 case DimensionsValue::ValueCase::kValueTuple:
349 case DimensionsValue::ValueCase::kValueStr:
350 case DimensionsValue::ValueCase::VALUE_NOT_SET:
351 return 0;
352 }
353}
354
Yangster-mac20877162017-12-22 17:19:39 -0800355} // namespace statsd
356} // namespace os
357} // namespace android