• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 #define STATSD_DEBUG false  // STOPSHIP if true
17 #include "Log.h"
18 
19 #include "src/statsd_config.pb.h"
20 #include "matchers/AtomMatchingTracker.h"
21 #include "matchers/matcher_util.h"
22 #include "stats_util.h"
23 
24 using std::set;
25 using std::string;
26 using std::vector;
27 
28 namespace android {
29 namespace os {
30 namespace statsd {
31 
combinationMatch(const vector<int> & children,const LogicalOperation & operation,const vector<MatchingState> & matcherResults)32 bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
33                       const vector<MatchingState>& matcherResults) {
34     bool matched;
35     switch (operation) {
36         case LogicalOperation::AND: {
37             matched = true;
38             for (const int childIndex : children) {
39                 if (matcherResults[childIndex] != MatchingState::kMatched) {
40                     matched = false;
41                     break;
42                 }
43             }
44             break;
45         }
46         case LogicalOperation::OR: {
47             matched = false;
48             for (const int childIndex : children) {
49                 if (matcherResults[childIndex] == MatchingState::kMatched) {
50                     matched = true;
51                     break;
52                 }
53             }
54             break;
55         }
56         case LogicalOperation::NOT:
57             matched = matcherResults[children[0]] == MatchingState::kNotMatched;
58             break;
59         case LogicalOperation::NAND:
60             matched = false;
61             for (const int childIndex : children) {
62                 if (matcherResults[childIndex] != MatchingState::kMatched) {
63                     matched = true;
64                     break;
65                 }
66             }
67             break;
68         case LogicalOperation::NOR:
69             matched = true;
70             for (const int childIndex : children) {
71                 if (matcherResults[childIndex] == MatchingState::kMatched) {
72                     matched = false;
73                     break;
74                 }
75             }
76             break;
77         case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
78             matched = false;
79             break;
80     }
81     return matched;
82 }
83 
tryMatchString(const sp<UidMap> & uidMap,const FieldValue & fieldValue,const string & str_match)84 bool tryMatchString(const sp<UidMap>& uidMap, const FieldValue& fieldValue,
85                     const string& str_match) {
86     if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
87         int uid = fieldValue.mValue.int_value;
88         auto aidIt = UidMap::sAidToUidMapping.find(str_match);
89         if (aidIt != UidMap::sAidToUidMapping.end()) {
90             return ((int)aidIt->second) == uid;
91         }
92         std::set<string> packageNames = uidMap->getAppNamesFromUid(uid, true /* normalize*/);
93         return packageNames.find(str_match) != packageNames.end();
94     } else if (fieldValue.mValue.getType() == STRING) {
95         return fieldValue.mValue.str_value == str_match;
96     }
97     return false;
98 }
99 
matchesSimple(const sp<UidMap> & uidMap,const FieldValueMatcher & matcher,const vector<FieldValue> & values,int start,int end,int depth)100 bool matchesSimple(const sp<UidMap>& uidMap, const FieldValueMatcher& matcher,
101                    const vector<FieldValue>& values, int start, int end, int depth) {
102     if (depth > 2) {
103         ALOGE("Depth > 3 not supported");
104         return false;
105     }
106 
107     if (start >= end) {
108         return false;
109     }
110 
111     // Filter by entry field first
112     int newStart = -1;
113     int newEnd = end;
114     // because the fields are naturally sorted in the DFS order. we can safely
115     // break when pos is larger than the one we are searching for.
116     for (int i = start; i < end; i++) {
117         int pos = values[i].mField.getPosAtDepth(depth);
118         if (pos == matcher.field()) {
119             if (newStart == -1) {
120                 newStart = i;
121             }
122             newEnd = i + 1;
123         } else if (pos > matcher.field()) {
124             break;
125         }
126     }
127 
128     // Now we have zoomed in to a new range
129     start = newStart;
130     end = newEnd;
131 
132     if (start == -1) {
133         // No such field found.
134         return false;
135     }
136 
137     vector<pair<int, int>> ranges; // the ranges are for matching ANY position
138     if (matcher.has_position()) {
139         // Repeated fields position is stored as a node in the path.
140         depth++;
141         if (depth > 2) {
142             return false;
143         }
144         switch (matcher.position()) {
145             case Position::FIRST: {
146                 for (int i = start; i < end; i++) {
147                     int pos = values[i].mField.getPosAtDepth(depth);
148                     if (pos != 1) {
149                         // Again, the log elements are stored in sorted order. so
150                         // once the position is > 1, we break;
151                         end = i;
152                         break;
153                     }
154                 }
155                 ranges.push_back(std::make_pair(start, end));
156                 break;
157             }
158             case Position::LAST: {
159                 // move the starting index to the first LAST field at the depth.
160                 for (int i = start; i < end; i++) {
161                     if (values[i].mField.isLastPos(depth)) {
162                         start = i;
163                         break;
164                     }
165                 }
166                 ranges.push_back(std::make_pair(start, end));
167                 break;
168             }
169             case Position::ANY: {
170                 // ANY means all the children matchers match in any of the sub trees, it's a match
171                 newStart = start;
172                 newEnd = end;
173                 // Here start is guaranteed to be a valid index.
174                 int currentPos = values[start].mField.getPosAtDepth(depth);
175                 // Now find all sub trees ranges.
176                 for (int i = start; i < end; i++) {
177                     int newPos = values[i].mField.getPosAtDepth(depth);
178                     if (newPos != currentPos) {
179                         ranges.push_back(std::make_pair(newStart, i));
180                         newStart = i;
181                         currentPos = newPos;
182                     }
183                 }
184                 ranges.push_back(std::make_pair(newStart, end));
185                 break;
186             }
187             case Position::ALL:
188                 ALOGE("Not supported: field matcher with ALL position.");
189                 break;
190             case Position::POSITION_UNKNOWN:
191                 break;
192         }
193     } else {
194         // No position
195         ranges.push_back(std::make_pair(start, end));
196     }
197     // start and end are still pointing to the matched range.
198     switch (matcher.value_matcher_case()) {
199         case FieldValueMatcher::kMatchesTuple: {
200             ++depth;
201             // If any range matches all matchers, good.
202             for (const auto& range : ranges) {
203                 bool matched = true;
204                 for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
205                     if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
206                                        depth)) {
207                         matched = false;
208                         break;
209                     }
210                 }
211                 if (matched) return true;
212             }
213             return false;
214         }
215         // Finally, we get to the point of real value matching.
216         // If the field matcher ends with ANY, then we have [start, end) range > 1.
217         // In the following, we should return true, when ANY of the values matches.
218         case FieldValueMatcher::ValueMatcherCase::kEqBool: {
219             for (int i = start; i < end; i++) {
220                 if ((values[i].mValue.getType() == INT &&
221                      (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
222                     (values[i].mValue.getType() == LONG &&
223                      (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
224                     return true;
225                 }
226             }
227             return false;
228         }
229         case FieldValueMatcher::ValueMatcherCase::kEqString: {
230             for (int i = start; i < end; i++) {
231                 if (tryMatchString(uidMap, values[i], matcher.eq_string())) {
232                     return true;
233                 }
234             }
235             return false;
236         }
237         case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
238             const auto& str_list = matcher.neq_any_string();
239             for (int i = start; i < end; i++) {
240                 for (const auto& str : str_list.str_value()) {
241                     if (tryMatchString(uidMap, values[i], str)) {
242                         return false;
243                     }
244                 }
245             }
246             return true;
247         }
248         case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
249             const auto& str_list = matcher.eq_any_string();
250             for (int i = start; i < end; i++) {
251                 for (const auto& str : str_list.str_value()) {
252                     if (tryMatchString(uidMap, values[i], str)) {
253                         return true;
254                     }
255                 }
256             }
257             return false;
258         }
259         case FieldValueMatcher::ValueMatcherCase::kEqInt: {
260             for (int i = start; i < end; i++) {
261                 if (values[i].mValue.getType() == INT &&
262                     (matcher.eq_int() == values[i].mValue.int_value)) {
263                     return true;
264                 }
265                 // eq_int covers both int and long.
266                 if (values[i].mValue.getType() == LONG &&
267                     (matcher.eq_int() == values[i].mValue.long_value)) {
268                     return true;
269                 }
270             }
271             return false;
272         }
273         case FieldValueMatcher::ValueMatcherCase::kLtInt: {
274             for (int i = start; i < end; i++) {
275                 if (values[i].mValue.getType() == INT &&
276                     (values[i].mValue.int_value < matcher.lt_int())) {
277                     return true;
278                 }
279                 // lt_int covers both int and long.
280                 if (values[i].mValue.getType() == LONG &&
281                     (values[i].mValue.long_value < matcher.lt_int())) {
282                     return true;
283                 }
284             }
285             return false;
286         }
287         case FieldValueMatcher::ValueMatcherCase::kGtInt: {
288             for (int i = start; i < end; i++) {
289                 if (values[i].mValue.getType() == INT &&
290                     (values[i].mValue.int_value > matcher.gt_int())) {
291                     return true;
292                 }
293                 // gt_int covers both int and long.
294                 if (values[i].mValue.getType() == LONG &&
295                     (values[i].mValue.long_value > matcher.gt_int())) {
296                     return true;
297                 }
298             }
299             return false;
300         }
301         case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
302             for (int i = start; i < end; i++) {
303                 if (values[i].mValue.getType() == FLOAT &&
304                     (values[i].mValue.float_value < matcher.lt_float())) {
305                     return true;
306                 }
307             }
308             return false;
309         }
310         case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
311             for (int i = start; i < end; i++) {
312                 if (values[i].mValue.getType() == FLOAT &&
313                     (values[i].mValue.float_value > matcher.gt_float())) {
314                     return true;
315                 }
316             }
317             return false;
318         }
319         case FieldValueMatcher::ValueMatcherCase::kLteInt: {
320             for (int i = start; i < end; i++) {
321                 if (values[i].mValue.getType() == INT &&
322                     (values[i].mValue.int_value <= matcher.lte_int())) {
323                     return true;
324                 }
325                 // lte_int covers both int and long.
326                 if (values[i].mValue.getType() == LONG &&
327                     (values[i].mValue.long_value <= matcher.lte_int())) {
328                     return true;
329                 }
330             }
331             return false;
332         }
333         case FieldValueMatcher::ValueMatcherCase::kGteInt: {
334             for (int i = start; i < end; i++) {
335                 if (values[i].mValue.getType() == INT &&
336                     (values[i].mValue.int_value >= matcher.gte_int())) {
337                     return true;
338                 }
339                 // gte_int covers both int and long.
340                 if (values[i].mValue.getType() == LONG &&
341                     (values[i].mValue.long_value >= matcher.gte_int())) {
342                     return true;
343                 }
344             }
345             return false;
346         }
347         default:
348             return false;
349     }
350 }
351 
matchesSimple(const sp<UidMap> & uidMap,const SimpleAtomMatcher & simpleMatcher,const LogEvent & event)352 bool matchesSimple(const sp<UidMap>& uidMap, const SimpleAtomMatcher& simpleMatcher,
353                    const LogEvent& event) {
354     if (event.GetTagId() != simpleMatcher.atom_id()) {
355         return false;
356     }
357 
358     for (const auto& matcher : simpleMatcher.field_value_matcher()) {
359         if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
360             return false;
361         }
362     }
363     return true;
364 }
365 
366 }  // namespace statsd
367 }  // namespace os
368 }  // namespace android
369