blob: 8c0ae978fcb8161ad18fd490cf8afe4f87b9a450 [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"
20#include "dimension.h"
21#include "field_util.h"
22
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
41void appendLeafNodeToParent(const Field& field,
42 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 }
61 appendLeafNodeToParent(
62 field.child(0), value,
63 parentValue->mutable_value_tuple()->mutable_dimensions_value(idx));
64}
65
66void addNodeToRootDimensionsValues(const Field& field,
67 const DimensionsValue& node,
68 std::vector<DimensionsValue>* rootValues) {
69 if (rootValues == nullptr) {
70 return;
71 }
72 if (rootValues->empty()) {
73 DimensionsValue rootValue;
74 appendLeafNodeToParent(field, node, &rootValue);
75 rootValues->push_back(rootValue);
76 } else {
77 for (size_t i = 0; i < rootValues->size(); ++i) {
78 appendLeafNodeToParent(field, node, &rootValues->at(i));
79 }
80 }
81}
82
83namespace {
84
85void findDimensionsValues(
86 const FieldValueMap& fieldValueMap,
87 const FieldMatcher& matcher,
88 const Field& field,
89 std::vector<DimensionsValue>* rootDimensionsValues);
90
91void findNonRepeatedDimensionsValues(
92 const FieldValueMap& fieldValueMap,
93 const FieldMatcher& matcher,
94 const Field& field,
95 std::vector<DimensionsValue>* rootValues) {
96 if (matcher.child_size() > 0) {
97 for (const auto& childMatcher : matcher.child()) {
98 Field childField = field;
99 appendLeaf(&childField, childMatcher.field());
100 findDimensionsValues(fieldValueMap, childMatcher, childField, rootValues);
101 }
102 } else {
103 auto ret = fieldValueMap.equal_range(field);
104 int found = 0;
105 for (auto it = ret.first; it != ret.second; ++it) {
106 found++;
107 }
108 // Not found.
109 if (found <= 0) {
110 return;
111 }
112 if (found > 1) {
113 ALOGE("Found multiple values for optional field.");
114 return;
115 }
116 addNodeToRootDimensionsValues(field, ret.first->second, rootValues);
117 }
118}
119
120void findRepeatedDimensionsValues(const FieldValueMap& fieldValueMap,
121 const FieldMatcher& matcher,
122 const Field& field,
123 std::vector<DimensionsValue>* rootValues) {
124 if (matcher.position() == Position::FIRST) {
125 Field first_field = field;
126 setPositionForLeaf(&first_field, 0);
127 findNonRepeatedDimensionsValues(fieldValueMap, matcher, first_field, rootValues);
128 } else {
129 auto itLower = fieldValueMap.lower_bound(field);
130 if (itLower == fieldValueMap.end()) {
131 return;
132 }
133 Field next_field = field;
134 getNextField(&next_field);
135 auto itUpper = fieldValueMap.lower_bound(next_field);
136
137 switch (matcher.position()) {
138 case Position::LAST:
139 {
140 itUpper--;
141 if (itUpper != fieldValueMap.end()) {
142 Field last_field = field;
143 int last_index = getPositionByReferenceField(field, itUpper->first);
144 if (last_index < 0) {
145 return;
146 }
147 setPositionForLeaf(&last_field, last_index);
148 findNonRepeatedDimensionsValues(
149 fieldValueMap, matcher, last_field, rootValues);
150 }
151 }
152 break;
153 case Position::ANY:
154 {
155 std::set<int> indexes;
156 for (auto it = itLower; it != itUpper; ++it) {
157 int index = getPositionByReferenceField(field, it->first);
158 if (index >= 0) {
159 indexes.insert(index);
160 }
161 }
162 if (!indexes.empty()) {
163 Field any_field = field;
164 std::vector<DimensionsValue> allValues;
165 for (const int index : indexes) {
166 setPositionForLeaf(&any_field, index);
167 std::vector<DimensionsValue> newValues = *rootValues;
168 findNonRepeatedDimensionsValues(
169 fieldValueMap, matcher, any_field, &newValues);
170 allValues.insert(allValues.end(), newValues.begin(), newValues.end());
171 }
172 rootValues->clear();
173 rootValues->insert(rootValues->end(), allValues.begin(), allValues.end());
174 }
175 }
176 break;
177 default:
178 break;
179 }
180 }
181}
182
183void findDimensionsValues(
184 const FieldValueMap& fieldValueMap,
185 const FieldMatcher& matcher,
186 const Field& field,
187 std::vector<DimensionsValue>* rootDimensionsValues) {
188 if (!matcher.has_position()) {
189 findNonRepeatedDimensionsValues(fieldValueMap, matcher, field, rootDimensionsValues);
190 } else {
191 findRepeatedDimensionsValues(fieldValueMap, matcher, field, rootDimensionsValues);
192 }
193}
194
195} // namespace
196
197void findDimensionsValues(
198 const FieldValueMap& fieldValueMap,
199 const FieldMatcher& matcher,
200 std::vector<DimensionsValue>* rootDimensionsValues) {
201 findDimensionsValues(fieldValueMap, matcher,
202 buildSimpleAtomField(matcher.field()), rootDimensionsValues);
203}
204
205FieldMatcher buildSimpleAtomFieldMatcher(const int tagId) {
206 FieldMatcher matcher;
207 matcher.set_field(tagId);
208 return matcher;
209}
210
211FieldMatcher buildSimpleAtomFieldMatcher(const int tagId, const int atomFieldNum) {
212 FieldMatcher matcher;
213 matcher.set_field(tagId);
214 matcher.add_child()->set_field(atomFieldNum);
215 return matcher;
216}
217
218constexpr int ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO = 1;
219constexpr int UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 1;
220constexpr int TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO = 2;
221
222void buildAttributionUidFieldMatcher(const int tagId, const Position position,
223 FieldMatcher *matcher) {
224 matcher->set_field(tagId);
225 matcher->add_child()->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
226 FieldMatcher* child = matcher->mutable_child(0)->add_child();
227 child->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
228}
229
230void buildAttributionTagFieldMatcher(const int tagId, const Position position,
231 FieldMatcher *matcher) {
232 matcher->set_field(tagId);
233 FieldMatcher* child = matcher->add_child();
234 child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
235 child->set_position(position);
236 child = child->add_child();
237 child->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
238}
239
240void buildAttributionFieldMatcher(const int tagId, const Position position,
241 FieldMatcher *matcher) {
242 matcher->set_field(tagId);
243 FieldMatcher* child = matcher->add_child();
244 child->set_field(ATTRIBUTION_FIELD_NUM_IN_ATOM_PROTO);
245 child->set_position(position);
246 child = child->add_child();
247 child->set_field(UID_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
248 child->set_field(TAG_FIELD_NUM_IN_ATTRIBUTION_NODE_PROTO);
249}
250
251void DimensionsValueToString(const DimensionsValue& value, std::string *flattened) {
252 *flattened += std::to_string(value.field());
253 *flattened += ":";
254 switch (value.value_case()) {
255 case DimensionsValue::ValueCase::kValueStr:
256 *flattened += value.value_str();
257 break;
258 case DimensionsValue::ValueCase::kValueInt:
259 *flattened += std::to_string(value.value_int());
260 break;
261 case DimensionsValue::ValueCase::kValueLong:
262 *flattened += std::to_string(value.value_long());
263 break;
264 case DimensionsValue::ValueCase::kValueBool:
265 *flattened += std::to_string(value.value_bool());
266 break;
267 case DimensionsValue::ValueCase::kValueFloat:
268 *flattened += std::to_string(value.value_float());
269 break;
270 case DimensionsValue::ValueCase::kValueTuple:
271 {
272 *flattened += "{";
273 for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
274 DimensionsValueToString(value.value_tuple().dimensions_value(i), flattened);
275 *flattened += "|";
276 }
277 *flattened += "}";
278 }
279 break;
280 case DimensionsValue::ValueCase::VALUE_NOT_SET:
281 break;
282 }
283}
284
285void getDimensionsValueLeafNodes(
286 const DimensionsValue& value, std::vector<DimensionsValue> *leafNodes) {
287 switch (value.value_case()) {
288 case DimensionsValue::ValueCase::kValueStr:
289 case DimensionsValue::ValueCase::kValueInt:
290 case DimensionsValue::ValueCase::kValueLong:
291 case DimensionsValue::ValueCase::kValueBool:
292 case DimensionsValue::ValueCase::kValueFloat:
293 leafNodes->push_back(value);
294 break;
295 case DimensionsValue::ValueCase::kValueTuple:
296 for (int i = 0; i < value.value_tuple().dimensions_value_size(); ++i) {
297 getDimensionsValueLeafNodes(value.value_tuple().dimensions_value(i), leafNodes);
298 }
299 break;
300 case DimensionsValue::ValueCase::VALUE_NOT_SET:
301 break;
302 default:
303 break;
304 }
305}
306
307std::string DimensionsValueToString(const DimensionsValue& value) {
308 std::string flatten;
309 DimensionsValueToString(value, &flatten);
310 return flatten;
311}
312
313bool IsSubDimension(const DimensionsValue& dimension, const DimensionsValue& sub) {
314 if (dimension.field() != sub.field()) {
315 return false;
316 }
317 if (dimension.value_case() != sub.value_case()) {
318 return false;
319 }
320 switch (dimension.value_case()) {
321 case DimensionsValue::ValueCase::kValueStr:
322 return dimension.value_str() == sub.value_str();
323 case DimensionsValue::ValueCase::kValueInt:
324 return dimension.value_int() == sub.value_int();
325 case DimensionsValue::ValueCase::kValueLong:
326 return dimension.value_long() == sub.value_long();
327 case DimensionsValue::ValueCase::kValueBool:
328 return dimension.value_bool() == sub.value_bool();
329 case DimensionsValue::ValueCase::kValueFloat:
330 return dimension.value_float() == sub.value_float();
331 case DimensionsValue::ValueCase::kValueTuple: {
332 if (dimension.value_tuple().dimensions_value_size() < sub.value_tuple().dimensions_value_size()) {
333 return false;
334 }
335 bool allSub = true;
336 for (int i = 0; i < sub.value_tuple().dimensions_value_size(); ++i) {
337 bool isSub = false;
338 for (int j = 0; !isSub && j < dimension.value_tuple().dimensions_value_size(); ++j) {
339 isSub |= IsSubDimension(dimension.value_tuple().dimensions_value(j),
340 sub.value_tuple().dimensions_value(i));
341 }
342 allSub &= isSub;
343 }
344 return allSub;
345 }
346 break;
347 case DimensionsValue::ValueCase::VALUE_NOT_SET:
348 return false;
349 default:
350 return false;
351 }
352}
353
Yangster-maca7fb12d2018-01-03 17:17:20 -0800354long getLongFromDimenValue(const DimensionsValue& dimensionValue) {
355 switch (dimensionValue.value_case()) {
356 case DimensionsValue::ValueCase::kValueInt:
357 return dimensionValue.value_int();
358 case DimensionsValue::ValueCase::kValueLong:
359 return dimensionValue.value_long();
360 case DimensionsValue::ValueCase::kValueBool:
361 return dimensionValue.value_bool() ? 1 : 0;
362 case DimensionsValue::ValueCase::kValueFloat:
363 return (int64_t)dimensionValue.value_float();
364 case DimensionsValue::ValueCase::kValueTuple:
365 case DimensionsValue::ValueCase::kValueStr:
366 case DimensionsValue::ValueCase::VALUE_NOT_SET:
367 return 0;
368 }
369}
370
Yangster-mac20877162017-12-22 17:19:39 -0800371} // namespace statsd
372} // namespace os
373} // namespace android