summaryrefslogtreecommitdiff
path: root/cmds/statsd/src/matchers/matcher_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cmds/statsd/src/matchers/matcher_util.cpp')
-rw-r--r--cmds/statsd/src/matchers/matcher_util.cpp372
1 files changed, 0 insertions, 372 deletions
diff --git a/cmds/statsd/src/matchers/matcher_util.cpp b/cmds/statsd/src/matchers/matcher_util.cpp
deleted file mode 100644
index 2b4c6a3cbf1e..000000000000
--- a/cmds/statsd/src/matchers/matcher_util.cpp
+++ /dev/null
@@ -1,372 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#define DEBUG false // STOPSHIP if true
-#include "Log.h"
-
-#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
-#include "matchers/LogMatchingTracker.h"
-#include "matchers/matcher_util.h"
-#include "stats_util.h"
-
-using std::set;
-using std::string;
-using std::vector;
-
-namespace android {
-namespace os {
-namespace statsd {
-
-bool combinationMatch(const vector<int>& children, const LogicalOperation& operation,
- const vector<MatchingState>& matcherResults) {
- bool matched;
- switch (operation) {
- case LogicalOperation::AND: {
- matched = true;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] != MatchingState::kMatched) {
- matched = false;
- break;
- }
- }
- break;
- }
- case LogicalOperation::OR: {
- matched = false;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] == MatchingState::kMatched) {
- matched = true;
- break;
- }
- }
- break;
- }
- case LogicalOperation::NOT:
- matched = matcherResults[children[0]] == MatchingState::kNotMatched;
- break;
- case LogicalOperation::NAND:
- matched = false;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] != MatchingState::kMatched) {
- matched = true;
- break;
- }
- }
- break;
- case LogicalOperation::NOR:
- matched = true;
- for (const int childIndex : children) {
- if (matcherResults[childIndex] == MatchingState::kMatched) {
- matched = false;
- break;
- }
- }
- break;
- case LogicalOperation::LOGICAL_OPERATION_UNSPECIFIED:
- matched = false;
- break;
- }
- return matched;
-}
-
-bool tryMatchString(const UidMap& uidMap, const FieldValue& fieldValue, const string& str_match) {
- if (isAttributionUidField(fieldValue) || isUidField(fieldValue)) {
- int uid = fieldValue.mValue.int_value;
- auto aidIt = UidMap::sAidToUidMapping.find(str_match);
- if (aidIt != UidMap::sAidToUidMapping.end()) {
- return ((int)aidIt->second) == uid;
- }
- std::set<string> packageNames = uidMap.getAppNamesFromUid(uid, true /* normalize*/);
- return packageNames.find(str_match) != packageNames.end();
- } else if (fieldValue.mValue.getType() == STRING) {
- return fieldValue.mValue.str_value == str_match;
- }
- return false;
-}
-
-bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher,
- const vector<FieldValue>& values, int start, int end, int depth) {
- if (depth > 2) {
- ALOGE("Depth > 3 not supported");
- return false;
- }
-
- if (start >= end) {
- return false;
- }
-
- // Filter by entry field first
- int newStart = -1;
- int newEnd = end;
- // because the fields are naturally sorted in the DFS order. we can safely
- // break when pos is larger than the one we are searching for.
- for (int i = start; i < end; i++) {
- int pos = values[i].mField.getPosAtDepth(depth);
- if (pos == matcher.field()) {
- if (newStart == -1) {
- newStart = i;
- }
- newEnd = i + 1;
- } else if (pos > matcher.field()) {
- break;
- }
- }
-
- // Now we have zoomed in to a new range
- start = newStart;
- end = newEnd;
-
- if (start == -1) {
- // No such field found.
- return false;
- }
-
- vector<pair<int, int>> ranges; // the ranges are for matching ANY position
- if (matcher.has_position()) {
- // Repeated fields position is stored as a node in the path.
- depth++;
- if (depth > 2) {
- return false;
- }
- switch (matcher.position()) {
- case Position::FIRST: {
- for (int i = start; i < end; i++) {
- int pos = values[i].mField.getPosAtDepth(depth);
- if (pos != 1) {
- // Again, the log elements are stored in sorted order. so
- // once the position is > 1, we break;
- end = i;
- break;
- }
- }
- ranges.push_back(std::make_pair(start, end));
- break;
- }
- case Position::LAST: {
- // move the starting index to the first LAST field at the depth.
- for (int i = start; i < end; i++) {
- if (values[i].mField.isLastPos(depth)) {
- start = i;
- break;
- }
- }
- ranges.push_back(std::make_pair(start, end));
- break;
- }
- case Position::ANY: {
- // ANY means all the children matchers match in any of the sub trees, it's a match
- newStart = start;
- newEnd = end;
- // Here start is guaranteed to be a valid index.
- int currentPos = values[start].mField.getPosAtDepth(depth);
- // Now find all sub trees ranges.
- for (int i = start; i < end; i++) {
- int newPos = values[i].mField.getPosAtDepth(depth);
- if (newPos != currentPos) {
- ranges.push_back(std::make_pair(newStart, i));
- newStart = i;
- currentPos = newPos;
- }
- }
- ranges.push_back(std::make_pair(newStart, end));
- break;
- }
- case Position::ALL:
- ALOGE("Not supported: field matcher with ALL position.");
- break;
- case Position::POSITION_UNKNOWN:
- break;
- }
- } else {
- // No position
- ranges.push_back(std::make_pair(start, end));
- }
- // start and end are still pointing to the matched range.
- switch (matcher.value_matcher_case()) {
- case FieldValueMatcher::kMatchesTuple: {
- ++depth;
- // If any range matches all matchers, good.
- for (const auto& range : ranges) {
- bool matched = true;
- for (const auto& subMatcher : matcher.matches_tuple().field_value_matcher()) {
- if (!matchesSimple(uidMap, subMatcher, values, range.first, range.second,
- depth)) {
- matched = false;
- break;
- }
- }
- if (matched) return true;
- }
- return false;
- }
- // Finally, we get to the point of real value matching.
- // If the field matcher ends with ANY, then we have [start, end) range > 1.
- // In the following, we should return true, when ANY of the values matches.
- case FieldValueMatcher::ValueMatcherCase::kEqBool: {
- for (int i = start; i < end; i++) {
- if ((values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value != 0) == matcher.eq_bool()) ||
- (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value != 0) == matcher.eq_bool())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqString: {
- for (int i = start; i < end; i++) {
- if (tryMatchString(uidMap, values[i], matcher.eq_string())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
- const auto& str_list = matcher.neq_any_string();
- for (int i = start; i < end; i++) {
- bool notEqAll = true;
- for (const auto& str : str_list.str_value()) {
- if (tryMatchString(uidMap, values[i], str)) {
- notEqAll = false;
- break;
- }
- }
- if (notEqAll) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
- const auto& str_list = matcher.eq_any_string();
- for (int i = start; i < end; i++) {
- for (const auto& str : str_list.str_value()) {
- if (tryMatchString(uidMap, values[i], str)) {
- return true;
- }
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kEqInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (matcher.eq_int() == values[i].mValue.int_value)) {
- return true;
- }
- // eq_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (matcher.eq_int() == values[i].mValue.long_value)) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value < matcher.lt_int())) {
- return true;
- }
- // lt_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value < matcher.lt_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value > matcher.gt_int())) {
- return true;
- }
- // gt_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value > matcher.gt_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLtFloat: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == FLOAT &&
- (values[i].mValue.float_value < matcher.lt_float())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGtFloat: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == FLOAT &&
- (values[i].mValue.float_value > matcher.gt_float())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kLteInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value <= matcher.lte_int())) {
- return true;
- }
- // lte_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value <= matcher.lte_int())) {
- return true;
- }
- }
- return false;
- }
- case FieldValueMatcher::ValueMatcherCase::kGteInt: {
- for (int i = start; i < end; i++) {
- if (values[i].mValue.getType() == INT &&
- (values[i].mValue.int_value >= matcher.gte_int())) {
- return true;
- }
- // gte_int covers both int and long.
- if (values[i].mValue.getType() == LONG &&
- (values[i].mValue.long_value >= matcher.gte_int())) {
- return true;
- }
- }
- return false;
- }
- default:
- return false;
- }
-}
-
-bool matchesSimple(const UidMap& uidMap, const SimpleAtomMatcher& simpleMatcher,
- const LogEvent& event) {
- if (event.GetTagId() != simpleMatcher.atom_id()) {
- return false;
- }
-
- for (const auto& matcher : simpleMatcher.field_value_matcher()) {
- if (!matchesSimple(uidMap, matcher, event.getValues(), 0, event.getValues().size(), 0)) {
- return false;
- }
- }
- return true;
-}
-
-} // namespace statsd
-} // namespace os
-} // namespace android