Loading cmds/statsd/src/matchers/matcher_util.cpp +48 −7 Original line number Diff line number Diff line Loading @@ -87,6 +87,10 @@ bool tryMatchString(const UidMap& uidMap, const Field& field, const Value& value const string& str_match) { if (isAttributionUidField(field, value)) { int uid = value.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 (value.getType() == STRING) { Loading Loading @@ -207,6 +211,9 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } 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 && Loading @@ -225,9 +232,36 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, return true; } } return false; } case FieldValueMatcher::ValueMatcherCase::kNeqAllString: { const auto& str_list = matcher.neq_all_string(); for (int i = start; i < end; i++) { bool notEqAll = true; for (const auto& str : str_list.str_value()) { if (tryMatchString(uidMap, values[i].mField, values[i].mValue, 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].mField, values[i].mValue, str)) { return true; } } } return false; case FieldValueMatcher::ValueMatcherCase::kEqInt: } 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)) { Loading @@ -240,7 +274,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kLtInt: } 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())) { Loading @@ -253,7 +288,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kGtInt: } 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())) { Loading @@ -266,7 +302,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kLtFloat: } 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())) { Loading @@ -274,7 +311,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kGtFloat: } 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())) { Loading @@ -282,7 +320,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kLteInt: } 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())) { Loading @@ -295,7 +334,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kGteInt: } 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())) { Loading @@ -308,6 +348,7 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; } default: return false; } Loading cmds/statsd/src/statsd_config.proto +7 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ message FieldValueMatcher { int64 gte_int = 11; MessageMatcher matches_tuple = 12; StringListMatcher eq_any_string = 13; StringListMatcher neq_all_string = 14; } } Loading @@ -81,6 +84,10 @@ message MessageMatcher { repeated FieldValueMatcher field_value_matcher = 1; } message StringListMatcher { repeated string str_value = 1; } enum LogicalOperation { LOGICAL_OPERATION_UNSPECIFIED = 0; AND = 1; Loading cmds/statsd/tests/LogEntryMatcher_test.cpp +153 −0 Original line number Diff line number Diff line Loading @@ -294,6 +294,159 @@ TEST(AtomMatcherTest, TestAttributionMatcher) { EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestNeqAnyStringMatcher) { UidMap uidMap; uidMap.updateMap( {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */); AttributionNodeInternal attribution_node1; attribution_node1.set_uid(1111); attribution_node1.set_tag("location1"); AttributionNodeInternal attribution_node2; attribution_node2.set_uid(2222); attribution_node2.set_tag("location2"); AttributionNodeInternal attribution_node3; attribution_node3.set_uid(3333); attribution_node3.set_tag("location3"); AttributionNodeInternal attribution_node4; attribution_node4.set_uid(1066); attribution_node4.set_tag("location3"); std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2, attribution_node3, attribution_node4}; // Set up the event LogEvent event(TAG_ID, 0); event.write(attribution_nodes); event.write("some value"); // Convert to a LogEvent event.init(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first node. auto attributionMatcher = simpleMatcher->add_field_value_matcher(); attributionMatcher->set_field(FIELD_ID_1); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_UID_FIELD_ID); auto neqStringList = attributionMatcher->mutable_matches_tuple() ->mutable_field_value_matcher(0) ->mutable_neq_all_string(); neqStringList->add_str_value("pkg2"); neqStringList->add_str_value("pkg3"); auto fieldMatcher = simpleMatcher->add_field_value_matcher(); fieldMatcher->set_field(FIELD_ID_2); fieldMatcher->set_eq_string("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->Clear(); neqStringList->add_str_value("pkg1"); neqStringList->add_str_value("pkg3"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::ANY); neqStringList->Clear(); neqStringList->add_str_value("maps.com"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->Clear(); neqStringList->add_str_value("PkG3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::LAST); neqStringList->Clear(); neqStringList->add_str_value("AID_STATSD"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestEqAnyStringMatcher) { UidMap uidMap; uidMap.updateMap( {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */); AttributionNodeInternal attribution_node1; attribution_node1.set_uid(1067); attribution_node1.set_tag("location1"); AttributionNodeInternal attribution_node2; attribution_node2.set_uid(2222); attribution_node2.set_tag("location2"); AttributionNodeInternal attribution_node3; attribution_node3.set_uid(3333); attribution_node3.set_tag("location3"); AttributionNodeInternal attribution_node4; attribution_node4.set_uid(1066); attribution_node4.set_tag("location3"); std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2, attribution_node3, attribution_node4}; // Set up the event LogEvent event(TAG_ID, 0); event.write(attribution_nodes); event.write("some value"); // Convert to a LogEvent event.init(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first node. auto attributionMatcher = simpleMatcher->add_field_value_matcher(); attributionMatcher->set_field(FIELD_ID_1); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_UID_FIELD_ID); auto eqStringList = attributionMatcher->mutable_matches_tuple() ->mutable_field_value_matcher(0) ->mutable_eq_any_string(); eqStringList->add_str_value("AID_ROOT"); eqStringList->add_str_value("AID_INCIDENTD"); auto fieldMatcher = simpleMatcher->add_field_value_matcher(); fieldMatcher->set_field(FIELD_ID_2); fieldMatcher->set_eq_string("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::ANY); eqStringList->Clear(); eqStringList->add_str_value("AID_STATSD"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->Clear(); eqStringList->add_str_value("pkg1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); auto normalStringField = fieldMatcher->mutable_eq_any_string(); normalStringField->add_str_value("some value123"); normalStringField->add_str_value("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); normalStringField->Clear(); normalStringField->add_str_value("AID_STATSD"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->Clear(); eqStringList->add_str_value("maps.com"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestBoolMatcher) { UidMap uidMap; // Set up the matcher Loading Loading
cmds/statsd/src/matchers/matcher_util.cpp +48 −7 Original line number Diff line number Diff line Loading @@ -87,6 +87,10 @@ bool tryMatchString(const UidMap& uidMap, const Field& field, const Value& value const string& str_match) { if (isAttributionUidField(field, value)) { int uid = value.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 (value.getType() == STRING) { Loading Loading @@ -207,6 +211,9 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } 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 && Loading @@ -225,9 +232,36 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, return true; } } return false; } case FieldValueMatcher::ValueMatcherCase::kNeqAllString: { const auto& str_list = matcher.neq_all_string(); for (int i = start; i < end; i++) { bool notEqAll = true; for (const auto& str : str_list.str_value()) { if (tryMatchString(uidMap, values[i].mField, values[i].mValue, 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].mField, values[i].mValue, str)) { return true; } } } return false; case FieldValueMatcher::ValueMatcherCase::kEqInt: } 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)) { Loading @@ -240,7 +274,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kLtInt: } 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())) { Loading @@ -253,7 +288,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kGtInt: } 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())) { Loading @@ -266,7 +302,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kLtFloat: } 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())) { Loading @@ -274,7 +311,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kGtFloat: } 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())) { Loading @@ -282,7 +320,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kLteInt: } 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())) { Loading @@ -295,7 +334,8 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; case FieldValueMatcher::ValueMatcherCase::kGteInt: } 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())) { Loading @@ -308,6 +348,7 @@ bool matchesSimple(const UidMap& uidMap, const FieldValueMatcher& matcher, } } return false; } default: return false; } Loading
cmds/statsd/src/statsd_config.proto +7 −0 Original line number Diff line number Diff line Loading @@ -74,6 +74,9 @@ message FieldValueMatcher { int64 gte_int = 11; MessageMatcher matches_tuple = 12; StringListMatcher eq_any_string = 13; StringListMatcher neq_all_string = 14; } } Loading @@ -81,6 +84,10 @@ message MessageMatcher { repeated FieldValueMatcher field_value_matcher = 1; } message StringListMatcher { repeated string str_value = 1; } enum LogicalOperation { LOGICAL_OPERATION_UNSPECIFIED = 0; AND = 1; Loading
cmds/statsd/tests/LogEntryMatcher_test.cpp +153 −0 Original line number Diff line number Diff line Loading @@ -294,6 +294,159 @@ TEST(AtomMatcherTest, TestAttributionMatcher) { EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestNeqAnyStringMatcher) { UidMap uidMap; uidMap.updateMap( {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */); AttributionNodeInternal attribution_node1; attribution_node1.set_uid(1111); attribution_node1.set_tag("location1"); AttributionNodeInternal attribution_node2; attribution_node2.set_uid(2222); attribution_node2.set_tag("location2"); AttributionNodeInternal attribution_node3; attribution_node3.set_uid(3333); attribution_node3.set_tag("location3"); AttributionNodeInternal attribution_node4; attribution_node4.set_uid(1066); attribution_node4.set_tag("location3"); std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2, attribution_node3, attribution_node4}; // Set up the event LogEvent event(TAG_ID, 0); event.write(attribution_nodes); event.write("some value"); // Convert to a LogEvent event.init(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first node. auto attributionMatcher = simpleMatcher->add_field_value_matcher(); attributionMatcher->set_field(FIELD_ID_1); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_UID_FIELD_ID); auto neqStringList = attributionMatcher->mutable_matches_tuple() ->mutable_field_value_matcher(0) ->mutable_neq_all_string(); neqStringList->add_str_value("pkg2"); neqStringList->add_str_value("pkg3"); auto fieldMatcher = simpleMatcher->add_field_value_matcher(); fieldMatcher->set_field(FIELD_ID_2); fieldMatcher->set_eq_string("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->Clear(); neqStringList->add_str_value("pkg1"); neqStringList->add_str_value("pkg3"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::ANY); neqStringList->Clear(); neqStringList->add_str_value("maps.com"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); neqStringList->Clear(); neqStringList->add_str_value("PkG3"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::LAST); neqStringList->Clear(); neqStringList->add_str_value("AID_STATSD"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestEqAnyStringMatcher) { UidMap uidMap; uidMap.updateMap( {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), android::String16("Pkg2"), android::String16("PkG3")} /* package name list */); AttributionNodeInternal attribution_node1; attribution_node1.set_uid(1067); attribution_node1.set_tag("location1"); AttributionNodeInternal attribution_node2; attribution_node2.set_uid(2222); attribution_node2.set_tag("location2"); AttributionNodeInternal attribution_node3; attribution_node3.set_uid(3333); attribution_node3.set_tag("location3"); AttributionNodeInternal attribution_node4; attribution_node4.set_uid(1066); attribution_node4.set_tag("location3"); std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2, attribution_node3, attribution_node4}; // Set up the event LogEvent event(TAG_ID, 0); event.write(attribution_nodes); event.write("some value"); // Convert to a LogEvent event.init(); // Set up the matcher AtomMatcher matcher; auto simpleMatcher = matcher.mutable_simple_atom_matcher(); simpleMatcher->set_atom_id(TAG_ID); // Match first node. auto attributionMatcher = simpleMatcher->add_field_value_matcher(); attributionMatcher->set_field(FIELD_ID_1); attributionMatcher->set_position(Position::FIRST); attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( ATTRIBUTION_UID_FIELD_ID); auto eqStringList = attributionMatcher->mutable_matches_tuple() ->mutable_field_value_matcher(0) ->mutable_eq_any_string(); eqStringList->add_str_value("AID_ROOT"); eqStringList->add_str_value("AID_INCIDENTD"); auto fieldMatcher = simpleMatcher->add_field_value_matcher(); fieldMatcher->set_field(FIELD_ID_2); fieldMatcher->set_eq_string("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); attributionMatcher->set_position(Position::ANY); eqStringList->Clear(); eqStringList->add_str_value("AID_STATSD"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->Clear(); eqStringList->add_str_value("pkg1"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); auto normalStringField = fieldMatcher->mutable_eq_any_string(); normalStringField->add_str_value("some value123"); normalStringField->add_str_value("some value"); EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); normalStringField->Clear(); normalStringField->add_str_value("AID_STATSD"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); eqStringList->Clear(); eqStringList->add_str_value("maps.com"); EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); } TEST(AtomMatcherTest, TestBoolMatcher) { UidMap uidMap; // Set up the matcher Loading