diff options
| -rw-r--r-- | cmds/statsd/src/atoms.proto | 5 | ||||
| -rw-r--r-- | cmds/statsd/tests/FieldValue_test.cpp | 329 | ||||
| -rw-r--r-- | cmds/statsd/tests/LogEntryMatcher_test.cpp | 1338 | ||||
| -rw-r--r-- | cmds/statsd/tests/StatsLogProcessor_test.cpp | 2824 | ||||
| -rw-r--r-- | cmds/statsd/tests/UidMap_test.cpp | 51 | ||||
| -rw-r--r-- | cmds/statsd/tests/shell/ShellSubscriber_test.cpp | 27 | ||||
| -rw-r--r-- | cmds/statsd/tests/state/StateTracker_test.cpp | 755 | ||||
| -rw-r--r-- | cmds/statsd/tests/statsd_test_util.cpp | 127 | ||||
| -rw-r--r-- | cmds/statsd/tests/statsd_test_util.h | 26 |
9 files changed, 2799 insertions, 2683 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index f9711c3ce763..57e54557d9f5 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -78,7 +78,8 @@ message Atom { // Pushed atoms start at 2. oneof pushed { // For StatsLog reasons, 1 is illegal and will not work. Must start at 2. - BleScanStateChanged ble_scan_state_changed = 2 [(module) = "bluetooth"]; + BleScanStateChanged ble_scan_state_changed = 2 + [(module) = "bluetooth", (module) = "statsdtest"]; ProcessStateChanged process_state_changed = 3 [(module) = "framework"]; BleScanResultReceived ble_scan_result_received = 4 [(module) = "bluetooth"]; SensorStateChanged sensor_state_changed = @@ -434,7 +435,7 @@ message Atom { ProcessMemoryState process_memory_state = 10013 [(module) = "framework"]; SystemElapsedRealtime system_elapsed_realtime = 10014 [(module) = "framework"]; SystemUptime system_uptime = 10015 [(module) = "framework", (module) = "statsdtest"]; - CpuActiveTime cpu_active_time = 10016 [(module) = "framework"]; + CpuActiveTime cpu_active_time = 10016 [(module) = "framework", (module) = "statsdtest"]; CpuClusterTime cpu_cluster_time = 10017 [(module) = "framework", (module) = "statsdtest"]; DiskSpace disk_space = 10018 [deprecated=true, (module) = "statsdtest"]; RemainingBatteryCapacity remaining_battery_capacity = 10019 [(module) = "framework"]; diff --git a/cmds/statsd/tests/FieldValue_test.cpp b/cmds/statsd/tests/FieldValue_test.cpp index a5ff0674f2dd..0bf24f1d3606 100644 --- a/cmds/statsd/tests/FieldValue_test.cpp +++ b/cmds/statsd/tests/FieldValue_test.cpp @@ -14,13 +14,16 @@ * limitations under the License. */ #include <gtest/gtest.h> + #include "frameworks/base/cmds/statsd/src/stats_log.pb.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "matchers/matcher_util.h" #include "src/logd/LogEvent.h" +#include "stats_event.h" #include "stats_log_util.h" #include "stats_util.h" #include "subscriber/SubscriberReporter.h" +#include "tests/statsd_test_util.h" #ifdef __ANDROID__ @@ -30,6 +33,58 @@ namespace android { namespace os { namespace statsd { +namespace { +void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const vector<int>& attributionUids, const vector<string>& attributionTags, + const string& name) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + vector<const char*> cTags(attributionTags.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = attributionTags[i].c_str(); + } + + AStatsEvent_writeAttributionChain(statsEvent, + reinterpret_cast<const uint32_t*>(attributionUids.data()), + cTags.data(), attributionUids.size()); + AStatsEvent_writeString(statsEvent, name.c_str()); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + +void makeLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const vector<int>& attributionUids, const vector<string>& attributionTags, + const int32_t value) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + vector<const char*> cTags(attributionTags.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = attributionTags[i].c_str(); + } + + AStatsEvent_writeAttributionChain(statsEvent, + reinterpret_cast<const uint32_t*>(attributionUids.data()), + cTags.data(), attributionUids.size()); + AStatsEvent_writeInt32(statsEvent, value); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} +} // anonymous namespace + TEST(AtomMatcherTest, TestFieldTranslation) { FieldMatcher matcher1; matcher1.set_field(10); @@ -72,66 +127,50 @@ TEST(AtomMatcherTest, TestFieldTranslation_ALL) { EXPECT_EQ((int32_t)0xff7f7f7f, matcher12.mMask); } -// TODO(b/149590301): Update this test to use new socket schema. -//TEST(AtomMatcherTest, TestFilter_ALL) { -// FieldMatcher matcher1; -// matcher1.set_field(10); -// FieldMatcher* child = matcher1.add_child(); -// child->set_field(1); -// child->set_position(Position::ALL); -// -// child->add_child()->set_field(1); -// child->add_child()->set_field(2); -// -// child = matcher1.add_child(); -// child->set_field(2); -// -// vector<Matcher> matchers; -// translateFieldMatcher(matcher1, &matchers); -// -// 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"); -// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2, -// attribution_node3}; -// -// // Set up the event -// LogEvent event(10, 12345); -// event.write(attribution_nodes); -// event.write("some value"); -// // Convert to a LogEvent -// event.init(); -// HashableDimensionKey output; -// -// filterValues(matchers, event.getValues(), &output); -// -// EXPECT_EQ((size_t)7, output.getValues().size()); -// EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField()); -// EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value); -// EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField()); -// EXPECT_EQ("location1", output.getValues()[1].mValue.str_value); -// -// EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField()); -// EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value); -// EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField()); -// EXPECT_EQ("location2", output.getValues()[3].mValue.str_value); -// -// EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField()); -// EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value); -// EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField()); -// EXPECT_EQ("location3", output.getValues()[5].mValue.str_value); -// -// EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField()); -// EXPECT_EQ("some value", output.getValues()[6].mValue.str_value); -//} +TEST(AtomMatcherTest, TestFilter_ALL) { + FieldMatcher matcher1; + matcher1.set_field(10); + FieldMatcher* child = matcher1.add_child(); + child->set_field(1); + child->set_position(Position::ALL); + + child->add_child()->set_field(1); + child->add_child()->set_field(2); + + child = matcher1.add_child(); + child->set_field(2); + + vector<Matcher> matchers; + translateFieldMatcher(matcher1, &matchers); + + std::vector<int> attributionUids = {1111, 2222, 3333}; + std::vector<string> attributionTags = {"location1", "location2", "location3"}; + + LogEvent event(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event, 10 /*atomId*/, 1012345, attributionUids, attributionTags, "some value"); + HashableDimensionKey output; + + filterValues(matchers, event.getValues(), &output); + + EXPECT_EQ((size_t)7, output.getValues().size()); + EXPECT_EQ((int32_t)0x02010101, output.getValues()[0].mField.getField()); + EXPECT_EQ((int32_t)1111, output.getValues()[0].mValue.int_value); + EXPECT_EQ((int32_t)0x02010102, output.getValues()[1].mField.getField()); + EXPECT_EQ("location1", output.getValues()[1].mValue.str_value); + + EXPECT_EQ((int32_t)0x02010201, output.getValues()[2].mField.getField()); + EXPECT_EQ((int32_t)2222, output.getValues()[2].mValue.int_value); + EXPECT_EQ((int32_t)0x02010202, output.getValues()[3].mField.getField()); + EXPECT_EQ("location2", output.getValues()[3].mValue.str_value); + + EXPECT_EQ((int32_t)0x02010301, output.getValues()[4].mField.getField()); + EXPECT_EQ((int32_t)3333, output.getValues()[4].mValue.int_value); + EXPECT_EQ((int32_t)0x02010302, output.getValues()[5].mField.getField()); + EXPECT_EQ("location3", output.getValues()[5].mValue.str_value); + + EXPECT_EQ((int32_t)0x00020000, output.getValues()[6].mField.getField()); + EXPECT_EQ("some value", output.getValues()[6].mValue.str_value); +} TEST(AtomMatcherTest, TestSubDimension) { HashableDimensionKey dim; @@ -174,61 +213,45 @@ TEST(AtomMatcherTest, TestSubDimension) { EXPECT_TRUE(dim.contains(subDim4)); } -// TODO(b/149590301): Update this test to use new socket schema. -//TEST(AtomMatcherTest, TestMetric2ConditionLink) { -// 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"); -// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2, -// attribution_node3}; -// -// // Set up the event -// LogEvent event(10, 12345); -// event.write(attribution_nodes); -// event.write("some value"); -// // Convert to a LogEvent -// event.init(); -// -// FieldMatcher whatMatcher; -// whatMatcher.set_field(10); -// FieldMatcher* child11 = whatMatcher.add_child(); -// child11->set_field(1); -// child11->set_position(Position::ANY); -// child11 = child11->add_child(); -// child11->set_field(1); -// -// FieldMatcher conditionMatcher; -// conditionMatcher.set_field(27); -// FieldMatcher* child2 = conditionMatcher.add_child(); -// child2->set_field(2); -// child2->set_position(Position::LAST); -// -// child2 = child2->add_child(); -// child2->set_field(2); -// -// Metric2Condition link; -// -// translateFieldMatcher(whatMatcher, &link.metricFields); -// translateFieldMatcher(conditionMatcher, &link.conditionFields); -// -// EXPECT_EQ((size_t)1, link.metricFields.size()); -// EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField()); -// EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask); -// EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag()); -// -// EXPECT_EQ((size_t)1, link.conditionFields.size()); -// EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField()); -// EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask); -// EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag()); -//} +TEST(AtomMatcherTest, TestMetric2ConditionLink) { + std::vector<int> attributionUids = {1111, 2222, 3333}; + std::vector<string> attributionTags = {"location1", "location2", "location3"}; + + LogEvent event(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event, 10 /*atomId*/, 12345, attributionUids, attributionTags, "some value"); + + FieldMatcher whatMatcher; + whatMatcher.set_field(10); + FieldMatcher* child11 = whatMatcher.add_child(); + child11->set_field(1); + child11->set_position(Position::ANY); + child11 = child11->add_child(); + child11->set_field(1); + + FieldMatcher conditionMatcher; + conditionMatcher.set_field(27); + FieldMatcher* child2 = conditionMatcher.add_child(); + child2->set_field(2); + child2->set_position(Position::LAST); + + child2 = child2->add_child(); + child2->set_field(2); + + Metric2Condition link; + + translateFieldMatcher(whatMatcher, &link.metricFields); + translateFieldMatcher(conditionMatcher, &link.conditionFields); + + EXPECT_EQ((size_t)1, link.metricFields.size()); + EXPECT_EQ((int32_t)0x02010001, link.metricFields[0].mMatcher.getField()); + EXPECT_EQ((int32_t)0xff7f007f, link.metricFields[0].mMask); + EXPECT_EQ((int32_t)10, link.metricFields[0].mMatcher.getTag()); + + EXPECT_EQ((size_t)1, link.conditionFields.size()); + EXPECT_EQ((int32_t)0x02028002, link.conditionFields[0].mMatcher.getField()); + EXPECT_EQ((int32_t)0xff7f807f, link.conditionFields[0].mMask); + EXPECT_EQ((int32_t)27, link.conditionFields[0].mMatcher.getTag()); +} TEST(AtomMatcherTest, TestWriteDimensionPath) { for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) { @@ -439,50 +462,38 @@ TEST(AtomMatcherTest, TestWriteDimensionLeafNodesToProto) { EXPECT_EQ(99999, dim4.value_long()); } -// TODO(b/149590301): Update this test to use new socket schema. -//TEST(AtomMatcherTest, TestWriteAtomToProto) { -// 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"); -// -// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2}; -// -// // Set up the event -// LogEvent event(4, 12345); -// event.write(attribution_nodes); -// event.write((int32_t)999); -// // Convert to a LogEvent -// event.init(); -// -// android::util::ProtoOutputStream protoOutput; -// writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput); -// -// vector<uint8_t> outData; -// outData.resize(protoOutput.size()); -// size_t pos = 0; -// sp<ProtoReader> reader = protoOutput.data(); -// while (reader->readBuffer() != NULL) { -// size_t toRead = reader->currentToRead(); -// std::memcpy(&(outData[pos]), reader->readBuffer(), toRead); -// pos += toRead; -// reader->move(toRead); -// } -// -// Atom result; -// EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size())); -// EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case()); -// const auto& atom = result.ble_scan_result_received(); -// EXPECT_EQ(2, atom.attribution_node_size()); -// EXPECT_EQ(1111, atom.attribution_node(0).uid()); -// EXPECT_EQ("location1", atom.attribution_node(0).tag()); -// EXPECT_EQ(2222, atom.attribution_node(1).uid()); -// EXPECT_EQ("location2", atom.attribution_node(1).tag()); -// EXPECT_EQ(999, atom.num_results()); -//} +TEST(AtomMatcherTest, TestWriteAtomToProto) { + std::vector<int> attributionUids = {1111, 2222}; + std::vector<string> attributionTags = {"location1", "location2"}; + + LogEvent event(/*uid=*/0, /*pid=*/0); + makeLogEvent(&event, 4 /*atomId*/, 12345, attributionUids, attributionTags, 999); + + android::util::ProtoOutputStream protoOutput; + writeFieldValueTreeToStream(event.GetTagId(), event.getValues(), &protoOutput); + + vector<uint8_t> outData; + outData.resize(protoOutput.size()); + size_t pos = 0; + sp<ProtoReader> reader = protoOutput.data(); + while (reader->readBuffer() != NULL) { + size_t toRead = reader->currentToRead(); + std::memcpy(&(outData[pos]), reader->readBuffer(), toRead); + pos += toRead; + reader->move(toRead); + } + + Atom result; + EXPECT_EQ(true, result.ParseFromArray(&outData[0], outData.size())); + EXPECT_EQ(Atom::PushedCase::kBleScanResultReceived, result.pushed_case()); + const auto& atom = result.ble_scan_result_received(); + EXPECT_EQ(2, atom.attribution_node_size()); + EXPECT_EQ(1111, atom.attribution_node(0).uid()); + EXPECT_EQ("location1", atom.attribution_node(0).tag()); + EXPECT_EQ(2222, atom.attribution_node(1).uid()); + EXPECT_EQ("location2", atom.attribution_node(1).tag()); + EXPECT_EQ(999, atom.num_results()); +} /* * Test two Matchers is not a subset of one Matcher. diff --git a/cmds/statsd/tests/LogEntryMatcher_test.cpp b/cmds/statsd/tests/LogEntryMatcher_test.cpp index 2de637714947..6f4c8e48eff2 100644 --- a/cmds/statsd/tests/LogEntryMatcher_test.cpp +++ b/cmds/statsd/tests/LogEntryMatcher_test.cpp @@ -12,18 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" -#include "matchers/matcher_util.h" -#include "stats_log_util.h" -#include "stats_util.h" - #include <gtest/gtest.h> #include <log/log_event_list.h> #include <log/log_read.h> #include <log/logprint.h> - #include <stdio.h> +#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" +#include "matchers/matcher_util.h" +#include "stats_event.h" +#include "stats_log_util.h" +#include "stats_util.h" +#include "statsd_test_util.h" + using namespace android::os::statsd; using std::unordered_map; using std::vector; @@ -39,646 +40,691 @@ const int ATTRIBUTION_TAG_FIELD_ID = 2; #ifdef __ANDROID__ -// TODO(b/149590301): Update these tests to use new socket schema. -//TEST(AtomMatcherTest, TestSimpleMatcher) { -// UidMap uidMap; -// -// // Set up the matcher -// AtomMatcher matcher; -// auto simpleMatcher = matcher.mutable_simple_atom_matcher(); -// simpleMatcher->set_atom_id(TAG_ID); -// -// LogEvent event(TAG_ID, 0); -// EXPECT_TRUE(event.write(11)); -// event.init(); -// -// // Test -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // Wrong tag id. -// simpleMatcher->set_atom_id(TAG_ID + 1); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -//} -// -//TEST(AtomMatcherTest, TestAttributionMatcher) { -// UidMap uidMap; -// 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"); -// std::vector<AttributionNodeInternal> attribution_nodes = {attribution_node1, attribution_node2, -// attribution_node3}; -// -// // 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_TAG_FIELD_ID); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string("tag"); -// -// auto fieldMatcher = simpleMatcher->add_field_value_matcher(); -// fieldMatcher->set_field(FIELD_ID_2); -// fieldMatcher->set_eq_string("some value"); -// -// // Tag not matched. -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location3"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // Match last node. -// attributionMatcher->set_position(Position::LAST); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // Match any node. -// attributionMatcher->set_position(Position::ANY); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location2"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location4"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // Attribution match but primitive field not match. -// attributionMatcher->set_position(Position::ANY); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("location2"); -// fieldMatcher->set_eq_string("wrong value"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// fieldMatcher->set_eq_string("some value"); -// -// // Uid match. -// attributionMatcher->set_position(Position::ANY); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_field( -// ATTRIBUTION_UID_FIELD_ID); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string("pkg0"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// uidMap.updateMap( -// 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, -// {android::String16("v1"), android::String16("v1"), android::String16("v2"), -// android::String16("v1"), android::String16("v2")}, -// {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), -// android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, -// {android::String16(""), android::String16(""), android::String16(""), -// android::String16(""), android::String16("")}); -// -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg2"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg0"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// attributionMatcher->set_position(Position::FIRST); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg0"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg2"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// attributionMatcher->set_position(Position::LAST); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg0"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg2"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // Uid + tag. -// attributionMatcher->set_position(Position::ANY); -// attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( -// ATTRIBUTION_TAG_FIELD_ID); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg0"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location2"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg2"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// attributionMatcher->set_position(Position::FIRST); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg0"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location2"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg2"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location3"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location3"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// attributionMatcher->set_position(Position::LAST); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg0"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg1"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location2"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg2"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location3"); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0) -// ->set_eq_string("pkg3"); -// attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1) -// ->set_eq_string("location1"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -//} -// -//TEST(AtomMatcherTest, TestUidFieldMatcher) { -// UidMap uidMap; -// uidMap.updateMap( -// 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, -// {android::String16("v1"), android::String16("v1"), android::String16("v2"), -// android::String16("v1"), android::String16("v2")}, -// {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), -// android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, -// {android::String16(""), android::String16(""), android::String16(""), -// android::String16(""), android::String16("")}); -// -// // Set up matcher -// AtomMatcher matcher; -// auto simpleMatcher = matcher.mutable_simple_atom_matcher(); -// simpleMatcher->set_atom_id(TAG_ID); -// simpleMatcher->add_field_value_matcher()->set_field(1); -// simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0"); -// -// // Set up the event -// LogEvent event(TAG_ID, 0); -// event.write(1111); -// event.init(); -// -// LogEvent event2(TAG_ID_2, 0); -// event2.write(1111); -// event2.write("some value"); -// event2.init(); -// -// // Tag not in kAtomsWithUidField -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // Tag found in kAtomsWithUidField and has matching uid -// simpleMatcher->set_atom_id(TAG_ID_2); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); -// -// // Tag found in kAtomsWithUidField but has non-matching uid -// simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2"); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); -//} -// -//TEST(AtomMatcherTest, TestNeqAnyStringMatcher) { -// UidMap uidMap; -// uidMap.updateMap( -// 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, -// {android::String16("v1"), android::String16("v1"), android::String16("v2"), -// android::String16("v1"), android::String16("v2")}, -// {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), -// android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, -// {android::String16(""), android::String16(""), android::String16(""), -// android::String16(""), android::String16("")}); -// -// 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_any_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( -// 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, -// {android::String16("v1"), android::String16("v1"), android::String16("v2"), -// android::String16("v1"), android::String16("v2")}, -// {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), -// android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, -// {android::String16(""), android::String16(""), android::String16(""), -// android::String16(""), android::String16("")}); -// -// 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 -// AtomMatcher matcher; -// auto simpleMatcher = matcher.mutable_simple_atom_matcher(); -// simpleMatcher->set_atom_id(TAG_ID); -// auto keyValue1 = simpleMatcher->add_field_value_matcher(); -// keyValue1->set_field(FIELD_ID_1); -// auto keyValue2 = simpleMatcher->add_field_value_matcher(); -// keyValue2->set_field(FIELD_ID_2); -// -// // Set up the event -// LogEvent event(TAG_ID, 0); -// EXPECT_TRUE(event.write(true)); -// EXPECT_TRUE(event.write(false)); -// // Convert to a LogEvent -// event.init(); -// -// // Test -// keyValue1->set_eq_bool(true); -// keyValue2->set_eq_bool(false); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// keyValue1->set_eq_bool(false); -// keyValue2->set_eq_bool(false); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// keyValue1->set_eq_bool(false); -// keyValue2->set_eq_bool(true); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// keyValue1->set_eq_bool(true); -// keyValue2->set_eq_bool(true); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -//} -// -//TEST(AtomMatcherTest, TestStringMatcher) { -// UidMap uidMap; -// // Set up the matcher -// AtomMatcher matcher; -// auto simpleMatcher = matcher.mutable_simple_atom_matcher(); -// simpleMatcher->set_atom_id(TAG_ID); -// auto keyValue = simpleMatcher->add_field_value_matcher(); -// keyValue->set_field(FIELD_ID_1); -// keyValue->set_eq_string("some value"); -// -// // Set up the event -// LogEvent event(TAG_ID, 0); -// event.write("some value"); -// // Convert to a LogEvent -// event.init(); -// -// // Test -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -//} -// -//TEST(AtomMatcherTest, TestMultiFieldsMatcher) { -// UidMap uidMap; -// // Set up the matcher -// AtomMatcher matcher; -// auto simpleMatcher = matcher.mutable_simple_atom_matcher(); -// simpleMatcher->set_atom_id(TAG_ID); -// auto keyValue1 = simpleMatcher->add_field_value_matcher(); -// keyValue1->set_field(FIELD_ID_1); -// auto keyValue2 = simpleMatcher->add_field_value_matcher(); -// keyValue2->set_field(FIELD_ID_2); -// -// // Set up the event -// LogEvent event(TAG_ID, 0); -// event.write(2); -// event.write(3); -// -// // Convert to a LogEvent -// event.init(); -// -// // Test -// keyValue1->set_eq_int(2); -// keyValue2->set_eq_int(3); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// keyValue1->set_eq_int(2); -// keyValue2->set_eq_int(4); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// keyValue1->set_eq_int(4); -// keyValue2->set_eq_int(3); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -//} -// -//TEST(AtomMatcherTest, TestIntComparisonMatcher) { -// UidMap uidMap; -// // Set up the matcher -// AtomMatcher matcher; -// auto simpleMatcher = matcher.mutable_simple_atom_matcher(); -// -// simpleMatcher->set_atom_id(TAG_ID); -// auto keyValue = simpleMatcher->add_field_value_matcher(); -// keyValue->set_field(FIELD_ID_1); -// -// // Set up the event -// LogEvent event(TAG_ID, 0); -// event.write(11); -// event.init(); -// -// // Test -// -// // eq_int -// keyValue->set_eq_int(10); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_eq_int(11); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_eq_int(12); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // lt_int -// keyValue->set_lt_int(10); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_lt_int(11); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_lt_int(12); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // lte_int -// keyValue->set_lte_int(10); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_lte_int(11); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_lte_int(12); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // gt_int -// keyValue->set_gt_int(10); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_gt_int(11); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_gt_int(12); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -// -// // gte_int -// keyValue->set_gte_int(10); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_gte_int(11); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); -// keyValue->set_gte_int(12); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); -//} -// -//TEST(AtomMatcherTest, TestFloatComparisonMatcher) { -// UidMap uidMap; -// // Set up the matcher -// AtomMatcher matcher; -// auto simpleMatcher = matcher.mutable_simple_atom_matcher(); -// simpleMatcher->set_atom_id(TAG_ID); -// -// auto keyValue = simpleMatcher->add_field_value_matcher(); -// keyValue->set_field(FIELD_ID_1); -// -// LogEvent event1(TAG_ID, 0); -// keyValue->set_lt_float(10.0); -// event1.write(10.1f); -// event1.init(); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); -// -// LogEvent event2(TAG_ID, 0); -// event2.write(9.9f); -// event2.init(); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); -// -// LogEvent event3(TAG_ID, 0); -// event3.write(10.1f); -// event3.init(); -// keyValue->set_gt_float(10.0); -// EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3)); -// -// LogEvent event4(TAG_ID, 0); -// event4.write(9.9f); -// event4.init(); -// EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event4)); -//} + +namespace { + +void makeIntLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const int32_t value) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + AStatsEvent_writeInt32(statsEvent, value); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + +void makeFloatLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const float floatValue) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + AStatsEvent_writeFloat(statsEvent, floatValue); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + +void makeStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const string& name) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + AStatsEvent_writeString(statsEvent, name.c_str()); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + +void makeIntStringLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const int32_t value, const string& name) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + AStatsEvent_writeInt32(statsEvent, value); + AStatsEvent_writeString(statsEvent, name.c_str()); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + +void makeAttributionLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const vector<int>& attributionUids, + const vector<string>& attributionTags, const string& name) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + vector<const char*> cTags(attributionTags.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = attributionTags[i].c_str(); + } + + AStatsEvent_writeAttributionChain(statsEvent, + reinterpret_cast<const uint32_t*>(attributionUids.data()), + cTags.data(), attributionUids.size()); + AStatsEvent_writeString(statsEvent, name.c_str()); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + +void makeBoolLogEvent(LogEvent* logEvent, const int32_t atomId, const int64_t timestamp, + const bool bool1, const bool bool2) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, atomId); + AStatsEvent_overwriteTimestamp(statsEvent, timestamp); + + AStatsEvent_writeBool(statsEvent, bool1); + AStatsEvent_writeBool(statsEvent, bool2); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + logEvent->parseBuffer(buf, size); + + AStatsEvent_release(statsEvent); +} + +} // anonymous namespace + +TEST(AtomMatcherTest, TestSimpleMatcher) { + UidMap uidMap; + + // Set up the matcher + AtomMatcher matcher; + auto simpleMatcher = matcher.mutable_simple_atom_matcher(); + simpleMatcher->set_atom_id(TAG_ID); + + LogEvent event(/*uid=*/0, /*pid=*/0); + makeIntLogEvent(&event, TAG_ID, 0, 11); + + // Test + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + // Wrong tag id. + simpleMatcher->set_atom_id(TAG_ID + 1); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); +} + +TEST(AtomMatcherTest, TestAttributionMatcher) { + UidMap uidMap; + std::vector<int> attributionUids = {1111, 2222, 3333}; + std::vector<string> attributionTags = {"location1", "location2", "location3"}; + + // Set up the log event. + LogEvent event(/*uid=*/0, /*pid=*/0); + makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value"); + + // 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_TAG_FIELD_ID); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "tag"); + + auto fieldMatcher = simpleMatcher->add_field_value_matcher(); + fieldMatcher->set_field(FIELD_ID_2); + fieldMatcher->set_eq_string("some value"); + + // Tag not matched. + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location3"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + // Match last node. + attributionMatcher->set_position(Position::LAST); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + // Match any node. + attributionMatcher->set_position(Position::ANY); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location2"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location4"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + // Attribution match but primitive field not match. + attributionMatcher->set_position(Position::ANY); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "location2"); + fieldMatcher->set_eq_string("wrong value"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + fieldMatcher->set_eq_string("some value"); + + // Uid match. + attributionMatcher->set_position(Position::ANY); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_field( + ATTRIBUTION_UID_FIELD_ID); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg0"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + uidMap.updateMap( + 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, + {android::String16("v1"), android::String16("v1"), android::String16("v2"), + android::String16("v1"), android::String16("v2")}, + {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), + android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, + {android::String16(""), android::String16(""), android::String16(""), + android::String16(""), android::String16("")}); + + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg2"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg0"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + attributionMatcher->set_position(Position::FIRST); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg0"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg2"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + attributionMatcher->set_position(Position::LAST); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg0"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg2"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + // Uid + tag. + attributionMatcher->set_position(Position::ANY); + attributionMatcher->mutable_matches_tuple()->add_field_value_matcher()->set_field( + ATTRIBUTION_TAG_FIELD_ID); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg0"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location2"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg2"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + attributionMatcher->set_position(Position::FIRST); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg0"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location2"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg2"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location3"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location3"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + attributionMatcher->set_position(Position::LAST); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg0"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg1"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location2"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg2"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location3"); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(0)->set_eq_string( + "pkg3"); + attributionMatcher->mutable_matches_tuple()->mutable_field_value_matcher(1)->set_eq_string( + "location1"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); +} + +TEST(AtomMatcherTest, TestUidFieldMatcher) { + UidMap uidMap; + uidMap.updateMap( + 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, + {android::String16("v1"), android::String16("v1"), android::String16("v2"), + android::String16("v1"), android::String16("v2")}, + {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), + android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, + {android::String16(""), android::String16(""), android::String16(""), + android::String16(""), android::String16("")}); + + // Set up matcher + AtomMatcher matcher; + auto simpleMatcher = matcher.mutable_simple_atom_matcher(); + simpleMatcher->set_atom_id(TAG_ID); + simpleMatcher->add_field_value_matcher()->set_field(1); + simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("pkg0"); + + // Set up the event + LogEvent event1(/*uid=*/0, /*pid=*/0); + makeIntLogEvent(&event1, TAG_ID, 0, 1111); + + LogEvent event2(/*uid=*/0, /*pid=*/0); + makeIntStringLogEvent(&event2, TAG_ID_2, 0, 1111, "some value"); + + // Tag not in kAtomsWithUidField + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); + + // Tag found in kAtomsWithUidField and has matching uid + simpleMatcher->set_atom_id(TAG_ID_2); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); + + // Tag found in kAtomsWithUidField but has non-matching uid + simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2"); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2)); +} + +TEST(AtomMatcherTest, TestNeqAnyStringMatcher) { + UidMap uidMap; + uidMap.updateMap( + 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, + {android::String16("v1"), android::String16("v1"), android::String16("v2"), + android::String16("v1"), android::String16("v2")}, + {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), + android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, + {android::String16(""), android::String16(""), android::String16(""), + android::String16(""), android::String16("")}); + + std::vector<int> attributionUids = {1111, 2222, 3333, 1066}; + std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"}; + + // Set up the event + LogEvent event(/*uid=*/0, /*pid=*/0); + makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value"); + + // 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_any_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( + 1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */, + {android::String16("v1"), android::String16("v1"), android::String16("v2"), + android::String16("v1"), android::String16("v2")}, + {android::String16("pkg0"), android::String16("pkg1"), android::String16("pkg1"), + android::String16("Pkg2"), android::String16("PkG3")} /* package name list */, + {android::String16(""), android::String16(""), android::String16(""), + android::String16(""), android::String16("")}); + + std::vector<int> attributionUids = {1067, 2222, 3333, 1066}; + std::vector<string> attributionTags = {"location1", "location2", "location3", "location3"}; + + // Set up the event + LogEvent event(/*uid=*/0, /*pid=*/0); + makeAttributionLogEvent(&event, TAG_ID, 0, attributionUids, attributionTags, "some value"); + + // 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 + AtomMatcher matcher; + auto simpleMatcher = matcher.mutable_simple_atom_matcher(); + simpleMatcher->set_atom_id(TAG_ID); + auto keyValue1 = simpleMatcher->add_field_value_matcher(); + keyValue1->set_field(FIELD_ID_1); + auto keyValue2 = simpleMatcher->add_field_value_matcher(); + keyValue2->set_field(FIELD_ID_2); + + // Set up the event + LogEvent event(/*uid=*/0, /*pid=*/0); + makeBoolLogEvent(&event, TAG_ID, 0, true, false); + + // Test + keyValue1->set_eq_bool(true); + keyValue2->set_eq_bool(false); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + keyValue1->set_eq_bool(false); + keyValue2->set_eq_bool(false); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + keyValue1->set_eq_bool(false); + keyValue2->set_eq_bool(true); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + keyValue1->set_eq_bool(true); + keyValue2->set_eq_bool(true); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); +} + +TEST(AtomMatcherTest, TestStringMatcher) { + UidMap uidMap; + // Set up the matcher + AtomMatcher matcher; + auto simpleMatcher = matcher.mutable_simple_atom_matcher(); + simpleMatcher->set_atom_id(TAG_ID); + auto keyValue = simpleMatcher->add_field_value_matcher(); + keyValue->set_field(FIELD_ID_1); + keyValue->set_eq_string("some value"); + + // Set up the event + LogEvent event(/*uid=*/0, /*pid=*/0); + makeStringLogEvent(&event, TAG_ID, 0, "some value"); + + // Test + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); +} + +TEST(AtomMatcherTest, TestMultiFieldsMatcher) { + UidMap uidMap; + // Set up the matcher + AtomMatcher matcher; + auto simpleMatcher = matcher.mutable_simple_atom_matcher(); + simpleMatcher->set_atom_id(TAG_ID); + auto keyValue1 = simpleMatcher->add_field_value_matcher(); + keyValue1->set_field(FIELD_ID_1); + auto keyValue2 = simpleMatcher->add_field_value_matcher(); + keyValue2->set_field(FIELD_ID_2); + + // Set up the event + LogEvent event(/*uid=*/0, /*pid=*/0); + CreateTwoValueLogEvent(&event, TAG_ID, 0, 2, 3); + + // Test + keyValue1->set_eq_int(2); + keyValue2->set_eq_int(3); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + keyValue1->set_eq_int(2); + keyValue2->set_eq_int(4); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + keyValue1->set_eq_int(4); + keyValue2->set_eq_int(3); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); +} + +TEST(AtomMatcherTest, TestIntComparisonMatcher) { + UidMap uidMap; + // Set up the matcher + AtomMatcher matcher; + auto simpleMatcher = matcher.mutable_simple_atom_matcher(); + + simpleMatcher->set_atom_id(TAG_ID); + auto keyValue = simpleMatcher->add_field_value_matcher(); + keyValue->set_field(FIELD_ID_1); + + // Set up the event + LogEvent event(/*uid=*/0, /*pid=*/0); + makeIntLogEvent(&event, TAG_ID, 0, 11); + + // Test + + // eq_int + keyValue->set_eq_int(10); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_eq_int(11); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_eq_int(12); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + // lt_int + keyValue->set_lt_int(10); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_lt_int(11); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_lt_int(12); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + // lte_int + keyValue->set_lte_int(10); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_lte_int(11); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_lte_int(12); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + + // gt_int + keyValue->set_gt_int(10); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_gt_int(11); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_gt_int(12); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); + + // gte_int + keyValue->set_gte_int(10); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_gte_int(11); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event)); + keyValue->set_gte_int(12); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event)); +} + +TEST(AtomMatcherTest, TestFloatComparisonMatcher) { + UidMap uidMap; + // Set up the matcher + AtomMatcher matcher; + auto simpleMatcher = matcher.mutable_simple_atom_matcher(); + simpleMatcher->set_atom_id(TAG_ID); + + auto keyValue = simpleMatcher->add_field_value_matcher(); + keyValue->set_field(FIELD_ID_1); + + LogEvent event1(/*uid=*/0, /*pid=*/0); + makeFloatLogEvent(&event1, TAG_ID, 0, 10.1f); + keyValue->set_lt_float(10.0); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1)); + + LogEvent event2(/*uid=*/0, /*pid=*/0); + makeFloatLogEvent(&event2, TAG_ID, 0, 9.9f); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2)); + + LogEvent event3(/*uid=*/0, /*pid=*/0); + makeFloatLogEvent(&event3, TAG_ID, 0, 10.1f); + keyValue->set_gt_float(10.0); + EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3)); + + LogEvent event4(/*uid=*/0, /*pid=*/0); + makeFloatLogEvent(&event4, TAG_ID, 0, 9.9f); + EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event4)); +} // Helper for the composite matchers. void addSimpleMatcher(SimpleAtomMatcher* simpleMatcher, int tag, int key, int val) { diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp index d6498f4f1554..9e7b7c820e0d 100644 --- a/cmds/statsd/tests/StatsLogProcessor_test.cpp +++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp @@ -253,1416 +253,1420 @@ TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) { EXPECT_EQ(2, report.annotation(0).field_int32()); } -// TODO(b/149590301): Update this test to use new socket schema. -//TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) { -// // Setup a simple config. -// StatsdConfig config; -// config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); -// *config.add_atom_matcher() = wakelockAcquireMatcher; -// -// auto countMetric = config.add_count_metric(); -// countMetric->set_id(123456); -// countMetric->set_what(wakelockAcquireMatcher.id()); -// countMetric->set_bucket(FIVE_MINUTES); -// -// ConfigKey cfgKey; -// sp<StatsLogProcessor> processor = CreateStatsLogProcessor(1, 1, config, cfgKey); -// -// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")}; -// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 2); -// processor->OnLogEvent(event.get()); -// -// vector<uint8_t> bytes; -// ConfigMetricsReportList output; -// -// // Dump report WITHOUT erasing data. -// processor->onDumpReport(cfgKey, 3, true, false /* Do NOT erase data. */, ADB_DUMP, FAST, &bytes); -// output.ParseFromArray(bytes.data(), bytes.size()); -// EXPECT_EQ(output.reports_size(), 1); -// EXPECT_EQ(output.reports(0).metrics_size(), 1); -// EXPECT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1); -// -// // Dump report WITH erasing data. There should be data since we didn't previously erase it. -// processor->onDumpReport(cfgKey, 4, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes); -// output.ParseFromArray(bytes.data(), bytes.size()); -// EXPECT_EQ(output.reports_size(), 1); -// EXPECT_EQ(output.reports(0).metrics_size(), 1); -// EXPECT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1); -// -// // Dump report again. There should be no data since we erased it. -// processor->onDumpReport(cfgKey, 5, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes); -// output.ParseFromArray(bytes.data(), bytes.size()); -// // We don't care whether statsd has a report, as long as it has no count metrics in it. -// bool noData = output.reports_size() == 0 -// || output.reports(0).metrics_size() == 0 -// || output.reports(0).metrics(0).count_metrics().data_size() == 0; -// EXPECT_TRUE(noData); -//} -// -//TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) { -// int uid = 1111; -// -// // Setup a simple config, no activation -// StatsdConfig config1; -// int64_t cfgId1 = 12341; -// config1.set_id(cfgId1); -// config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); -// *config1.add_atom_matcher() = wakelockAcquireMatcher; -// -// long metricId1 = 1234561; -// long metricId2 = 1234562; -// auto countMetric1 = config1.add_count_metric(); -// countMetric1->set_id(metricId1); -// countMetric1->set_what(wakelockAcquireMatcher.id()); -// countMetric1->set_bucket(FIVE_MINUTES); -// -// auto countMetric2 = config1.add_count_metric(); -// countMetric2->set_id(metricId2); -// countMetric2->set_what(wakelockAcquireMatcher.id()); -// countMetric2->set_bucket(FIVE_MINUTES); -// -// ConfigKey cfgKey1(uid, cfgId1); -// -// // Add another config, with two metrics, one with activation -// StatsdConfig config2; -// int64_t cfgId2 = 12342; -// config2.set_id(cfgId2); -// config2.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// *config2.add_atom_matcher() = wakelockAcquireMatcher; -// -// long metricId3 = 1234561; -// long metricId4 = 1234562; -// -// auto countMetric3 = config2.add_count_metric(); -// countMetric3->set_id(metricId3); -// countMetric3->set_what(wakelockAcquireMatcher.id()); -// countMetric3->set_bucket(FIVE_MINUTES); -// -// auto countMetric4 = config2.add_count_metric(); -// countMetric4->set_id(metricId4); -// countMetric4->set_what(wakelockAcquireMatcher.id()); -// countMetric4->set_bucket(FIVE_MINUTES); -// -// auto metric3Activation = config2.add_metric_activation(); -// metric3Activation->set_metric_id(metricId3); -// metric3Activation->set_activation_type(ACTIVATE_IMMEDIATELY); -// auto metric3ActivationTrigger = metric3Activation->add_event_activation(); -// metric3ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); -// metric3ActivationTrigger->set_ttl_seconds(100); -// -// ConfigKey cfgKey2(uid, cfgId2); -// -// // Add another config, with two metrics, both with activations -// StatsdConfig config3; -// int64_t cfgId3 = 12343; -// config3.set_id(cfgId3); -// config3.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// *config3.add_atom_matcher() = wakelockAcquireMatcher; -// -// long metricId5 = 1234565; -// long metricId6 = 1234566; -// auto countMetric5 = config3.add_count_metric(); -// countMetric5->set_id(metricId5); -// countMetric5->set_what(wakelockAcquireMatcher.id()); -// countMetric5->set_bucket(FIVE_MINUTES); -// -// auto countMetric6 = config3.add_count_metric(); -// countMetric6->set_id(metricId6); -// countMetric6->set_what(wakelockAcquireMatcher.id()); -// countMetric6->set_bucket(FIVE_MINUTES); -// -// auto metric5Activation = config3.add_metric_activation(); -// metric5Activation->set_metric_id(metricId5); -// metric5Activation->set_activation_type(ACTIVATE_IMMEDIATELY); -// auto metric5ActivationTrigger = metric5Activation->add_event_activation(); -// metric5ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); -// metric5ActivationTrigger->set_ttl_seconds(100); -// -// auto metric6Activation = config3.add_metric_activation(); -// metric6Activation->set_metric_id(metricId6); -// metric6Activation->set_activation_type(ACTIVATE_IMMEDIATELY); -// auto metric6ActivationTrigger = metric6Activation->add_event_activation(); -// metric6ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); -// metric6ActivationTrigger->set_ttl_seconds(200); -// -// ConfigKey cfgKey3(uid, cfgId3); -// -// sp<UidMap> m = new UidMap(); -// sp<StatsPullerManager> pullerManager = new StatsPullerManager(); -// sp<AlarmMonitor> anomalyAlarmMonitor; -// sp<AlarmMonitor> subscriberAlarmMonitor; -// vector<int64_t> activeConfigsBroadcast; -// -// long timeBase1 = 1; -// int broadcastCount = 0; -// StatsLogProcessor processor(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, -// timeBase1, [](const ConfigKey& key) { return true; }, -// [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid, -// const vector<int64_t>& activeConfigs) { -// broadcastCount++; -// EXPECT_EQ(broadcastUid, uid); -// activeConfigsBroadcast.clear(); -// activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), -// activeConfigs.begin(), activeConfigs.end()); -// return true; -// }); -// -// processor.OnConfigUpdated(1, cfgKey1, config1); -// processor.OnConfigUpdated(2, cfgKey2, config2); -// processor.OnConfigUpdated(3, cfgKey3, config3); -// -// EXPECT_EQ(3, processor.mMetricsManagers.size()); -// -// // Expect the first config and both metrics in it to be active. -// auto it = processor.mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor.mMetricsManagers.end()); -// auto& metricsManager1 = it->second; -// EXPECT_TRUE(metricsManager1->isActive()); -// -// auto metricIt = metricsManager1->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); -// auto& metricProducer1 = *metricIt; -// EXPECT_TRUE(metricProducer1->isActive()); -// -// metricIt = metricsManager1->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); -// auto& metricProducer2 = *metricIt; -// EXPECT_TRUE(metricProducer2->isActive()); -// -// // Expect config 2 to be active. Metric 3 shouldn't be active, metric 4 should be active. -// it = processor.mMetricsManagers.find(cfgKey2); -// EXPECT_TRUE(it != processor.mMetricsManagers.end()); -// auto& metricsManager2 = it->second; -// EXPECT_TRUE(metricsManager2->isActive()); -// -// metricIt = metricsManager2->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId3) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end()); -// auto& metricProducer3 = *metricIt; -// EXPECT_FALSE(metricProducer3->isActive()); -// -// metricIt = metricsManager2->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId4) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end()); -// auto& metricProducer4 = *metricIt; -// EXPECT_TRUE(metricProducer4->isActive()); -// -// // Expect the third config and both metrics in it to be inactive. -// it = processor.mMetricsManagers.find(cfgKey3); -// EXPECT_TRUE(it != processor.mMetricsManagers.end()); -// auto& metricsManager3 = it->second; -// EXPECT_FALSE(metricsManager3->isActive()); -// -// metricIt = metricsManager3->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId5) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end()); -// auto& metricProducer5 = *metricIt; -// EXPECT_FALSE(metricProducer5->isActive()); -// -// metricIt = metricsManager3->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager3->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId6) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end()); -// auto& metricProducer6 = *metricIt; -// EXPECT_FALSE(metricProducer6->isActive()); -// -// // No broadcast for active configs should have happened yet. -// EXPECT_EQ(broadcastCount, 0); -// -// // Activate all 3 metrics that were not active. -// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")}; -// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1); -// processor.OnLogEvent(event.get()); -// -// // Assert that all 3 configs are active. -// EXPECT_TRUE(metricsManager1->isActive()); -// EXPECT_TRUE(metricsManager2->isActive()); -// EXPECT_TRUE(metricsManager3->isActive()); -// -// // A broadcast should have happened, and all 3 configs should be active in the broadcast. -// EXPECT_EQ(broadcastCount, 1); -// EXPECT_EQ(activeConfigsBroadcast.size(), 3); -// EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId1) -// != activeConfigsBroadcast.end()); -// EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId2) -// != activeConfigsBroadcast.end()); -// EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId3) -// != activeConfigsBroadcast.end()); -// -// // When we shut down, metrics 3 & 5 have 100ns remaining, metric 6 has 100s + 100ns. -// int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; -// processor.SaveActiveConfigsToDisk(shutDownTime); -// const int64_t ttl3 = event->GetElapsedTimestampNs() + -// metric3ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime; -// const int64_t ttl5 = event->GetElapsedTimestampNs() + -// metric5ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime; -// const int64_t ttl6 = event->GetElapsedTimestampNs() + -// metric6ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime; -// -// // Create a second StatsLogProcessor and push the same 3 configs. -// long timeBase2 = 1000; -// sp<StatsLogProcessor> processor2 = -// CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); -// processor2->OnConfigUpdated(timeBase2, cfgKey2, config2); -// processor2->OnConfigUpdated(timeBase2, cfgKey3, config3); -// -// EXPECT_EQ(3, processor2->mMetricsManagers.size()); -// -// // First config and both metrics are active. -// it = processor2->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor2->mMetricsManagers.end()); -// auto& metricsManager1001 = it->second; -// EXPECT_TRUE(metricsManager1001->isActive()); -// -// metricIt = metricsManager1001->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); -// auto& metricProducer1001 = *metricIt; -// EXPECT_TRUE(metricProducer1001->isActive()); -// -// metricIt = metricsManager1001->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); -// auto& metricProducer1002 = *metricIt; -// EXPECT_TRUE(metricProducer1002->isActive()); -// -// // Second config is active. Metric 3 is inactive, metric 4 is active. -// it = processor2->mMetricsManagers.find(cfgKey2); -// EXPECT_TRUE(it != processor2->mMetricsManagers.end()); -// auto& metricsManager1002 = it->second; -// EXPECT_TRUE(metricsManager1002->isActive()); -// -// metricIt = metricsManager1002->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId3) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end()); -// auto& metricProducer1003 = *metricIt; -// EXPECT_FALSE(metricProducer1003->isActive()); -// -// metricIt = metricsManager1002->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId4) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end()); -// auto& metricProducer1004 = *metricIt; -// EXPECT_TRUE(metricProducer1004->isActive()); -// -// // Config 3 is inactive. both metrics are inactive. -// it = processor2->mMetricsManagers.find(cfgKey3); -// EXPECT_TRUE(it != processor2->mMetricsManagers.end()); -// auto& metricsManager1003 = it->second; -// EXPECT_FALSE(metricsManager1003->isActive()); -// EXPECT_EQ(2, metricsManager1003->mAllMetricProducers.size()); -// -// metricIt = metricsManager1003->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId5) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end()); -// auto& metricProducer1005 = *metricIt; -// EXPECT_FALSE(metricProducer1005->isActive()); -// -// metricIt = metricsManager1003->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1003->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId6) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end()); -// auto& metricProducer1006 = *metricIt; -// EXPECT_FALSE(metricProducer1006->isActive()); -// -// // Assert that all 3 metrics with activation are inactive and that the ttls were properly set. -// EXPECT_FALSE(metricProducer1003->isActive()); -// const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second; -// EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns); -// EXPECT_EQ(0, activation1003->start_ns); -// EXPECT_FALSE(metricProducer1005->isActive()); -// const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second; -// EXPECT_EQ(100 * NS_PER_SEC, activation1005->ttl_ns); -// EXPECT_EQ(0, activation1005->start_ns); -// EXPECT_FALSE(metricProducer1006->isActive()); -// const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second; -// EXPECT_EQ(200 * NS_PER_SEC, activation1006->ttl_ns); -// EXPECT_EQ(0, activation1006->start_ns); -// -// processor2->LoadActiveConfigsFromDisk(); -// -// // After loading activations from disk, assert that all 3 metrics are active. -// EXPECT_TRUE(metricProducer1003->isActive()); -// EXPECT_EQ(timeBase2 + ttl3 - activation1003->ttl_ns, activation1003->start_ns); -// EXPECT_TRUE(metricProducer1005->isActive()); -// EXPECT_EQ(timeBase2 + ttl5 - activation1005->ttl_ns, activation1005->start_ns); -// EXPECT_TRUE(metricProducer1006->isActive()); -// EXPECT_EQ(timeBase2 + ttl6 - activation1006->ttl_ns, activation1003->start_ns); -// -// // Make sure no more broadcasts have happened. -// EXPECT_EQ(broadcastCount, 1); -//} -// -//TEST(StatsLogProcessorTest, TestActivationOnBoot) { -// int uid = 1111; -// -// StatsdConfig config1; -// config1.set_id(12341); -// config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); -// *config1.add_atom_matcher() = wakelockAcquireMatcher; -// -// long metricId1 = 1234561; -// long metricId2 = 1234562; -// auto countMetric1 = config1.add_count_metric(); -// countMetric1->set_id(metricId1); -// countMetric1->set_what(wakelockAcquireMatcher.id()); -// countMetric1->set_bucket(FIVE_MINUTES); -// -// auto countMetric2 = config1.add_count_metric(); -// countMetric2->set_id(metricId2); -// countMetric2->set_what(wakelockAcquireMatcher.id()); -// countMetric2->set_bucket(FIVE_MINUTES); -// -// auto metric1Activation = config1.add_metric_activation(); -// metric1Activation->set_metric_id(metricId1); -// metric1Activation->set_activation_type(ACTIVATE_ON_BOOT); -// auto metric1ActivationTrigger = metric1Activation->add_event_activation(); -// metric1ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); -// metric1ActivationTrigger->set_ttl_seconds(100); -// -// ConfigKey cfgKey1(uid, 12341); -// long timeBase1 = 1; -// sp<StatsLogProcessor> processor = -// CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1); -// -// EXPECT_EQ(1, processor->mMetricsManagers.size()); -// auto it = processor->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor->mMetricsManagers.end()); -// auto& metricsManager1 = it->second; -// EXPECT_TRUE(metricsManager1->isActive()); -// -// auto metricIt = metricsManager1->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); -// auto& metricProducer1 = *metricIt; -// EXPECT_FALSE(metricProducer1->isActive()); -// -// metricIt = metricsManager1->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); -// auto& metricProducer2 = *metricIt; -// EXPECT_TRUE(metricProducer2->isActive()); -// -// const auto& activation1 = metricProducer1->mEventActivationMap.begin()->second; -// EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns); -// EXPECT_EQ(0, activation1->start_ns); -// EXPECT_EQ(kNotActive, activation1->state); -// -// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")}; -// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1); -// processor->OnLogEvent(event.get()); -// -// EXPECT_FALSE(metricProducer1->isActive()); -// EXPECT_EQ(0, activation1->start_ns); -// EXPECT_EQ(kActiveOnBoot, activation1->state); -// -// int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; -// processor->SaveActiveConfigsToDisk(shutDownTime); -// EXPECT_FALSE(metricProducer1->isActive()); -// const int64_t ttl1 = metric1ActivationTrigger->ttl_seconds() * NS_PER_SEC; -// -// long timeBase2 = 1000; -// sp<StatsLogProcessor> processor2 = -// CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); -// -// EXPECT_EQ(1, processor2->mMetricsManagers.size()); -// it = processor2->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor2->mMetricsManagers.end()); -// auto& metricsManager1001 = it->second; -// EXPECT_TRUE(metricsManager1001->isActive()); -// -// metricIt = metricsManager1001->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); -// auto& metricProducer1001 = *metricIt; -// EXPECT_FALSE(metricProducer1001->isActive()); -// -// metricIt = metricsManager1001->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); -// auto& metricProducer1002 = *metricIt; -// EXPECT_TRUE(metricProducer1002->isActive()); -// -// const auto& activation1001 = metricProducer1001->mEventActivationMap.begin()->second; -// EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns); -// EXPECT_EQ(0, activation1001->start_ns); -// EXPECT_EQ(kNotActive, activation1001->state); -// -// processor2->LoadActiveConfigsFromDisk(); -// -// EXPECT_TRUE(metricProducer1001->isActive()); -// EXPECT_EQ(timeBase2 + ttl1 - activation1001->ttl_ns, activation1001->start_ns); -// EXPECT_EQ(kActive, activation1001->state); -//} -// -//TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations) { -// int uid = 1111; -// -// // Create config with 2 metrics: -// // Metric 1: Activate on boot with 2 activations -// // Metric 2: Always active -// StatsdConfig config1; -// config1.set_id(12341); -// config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); -// auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher(); -// *config1.add_atom_matcher() = wakelockAcquireMatcher; -// *config1.add_atom_matcher() = screenOnMatcher; -// -// long metricId1 = 1234561; -// long metricId2 = 1234562; -// -// auto countMetric1 = config1.add_count_metric(); -// countMetric1->set_id(metricId1); -// countMetric1->set_what(wakelockAcquireMatcher.id()); -// countMetric1->set_bucket(FIVE_MINUTES); -// -// auto countMetric2 = config1.add_count_metric(); -// countMetric2->set_id(metricId2); -// countMetric2->set_what(wakelockAcquireMatcher.id()); -// countMetric2->set_bucket(FIVE_MINUTES); -// -// auto metric1Activation = config1.add_metric_activation(); -// metric1Activation->set_metric_id(metricId1); -// metric1Activation->set_activation_type(ACTIVATE_ON_BOOT); -// auto metric1ActivationTrigger1 = metric1Activation->add_event_activation(); -// metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id()); -// metric1ActivationTrigger1->set_ttl_seconds(100); -// auto metric1ActivationTrigger2 = metric1Activation->add_event_activation(); -// metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id()); -// metric1ActivationTrigger2->set_ttl_seconds(200); -// -// ConfigKey cfgKey1(uid, 12341); -// long timeBase1 = 1; -// sp<StatsLogProcessor> processor = -// CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1); -// -// // Metric 1 is not active. -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor->mMetricsManagers.size()); -// auto it = processor->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor->mMetricsManagers.end()); -// auto& metricsManager1 = it->second; -// EXPECT_TRUE(metricsManager1->isActive()); -// -// auto metricIt = metricsManager1->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); -// auto& metricProducer1 = *metricIt; -// EXPECT_FALSE(metricProducer1->isActive()); -// -// metricIt = metricsManager1->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); -// auto& metricProducer2 = *metricIt; -// EXPECT_TRUE(metricProducer2->isActive()); -// -// int i = 0; -// for (; i < metricsManager1->mAllAtomMatchers.size(); i++) { -// if (metricsManager1->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger1->atom_matcher_id()) { -// break; -// } -// } -// const auto& activation1 = metricProducer1->mEventActivationMap.at(i); -// EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns); -// EXPECT_EQ(0, activation1->start_ns); -// EXPECT_EQ(kNotActive, activation1->state); -// -// i = 0; -// for (; i < metricsManager1->mAllAtomMatchers.size(); i++) { -// if (metricsManager1->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger2->atom_matcher_id()) { -// break; -// } -// } -// const auto& activation2 = metricProducer1->mEventActivationMap.at(i); -// EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns); -// EXPECT_EQ(0, activation2->start_ns); -// EXPECT_EQ(kNotActive, activation2->state); -// // }}}------------------------------------------------------------------------------ -// -// // Trigger Activation 1 for Metric 1 -// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")}; -// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1); -// processor->OnLogEvent(event.get()); -// -// // Metric 1 is not active; Activation 1 set to kActiveOnBoot -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_FALSE(metricProducer1->isActive()); -// EXPECT_EQ(0, activation1->start_ns); -// EXPECT_EQ(kActiveOnBoot, activation1->state); -// EXPECT_EQ(0, activation2->start_ns); -// EXPECT_EQ(kNotActive, activation2->state); -// -// EXPECT_TRUE(metricProducer2->isActive()); -// // }}}----------------------------------------------------------------------------- -// -// // Simulate shutdown by saving state to disk -// int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; -// processor->SaveActiveConfigsToDisk(shutDownTime); -// EXPECT_FALSE(metricProducer1->isActive()); -// int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC; -// -// // Simulate device restarted state by creating new instance of StatsLogProcessor with the -// // same config. -// long timeBase2 = 1000; -// sp<StatsLogProcessor> processor2 = -// CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); -// -// // Metric 1 is not active. -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor2->mMetricsManagers.size()); -// it = processor2->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor2->mMetricsManagers.end()); -// auto& metricsManager1001 = it->second; -// EXPECT_TRUE(metricsManager1001->isActive()); -// -// metricIt = metricsManager1001->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); -// auto& metricProducer1001 = *metricIt; -// EXPECT_FALSE(metricProducer1001->isActive()); -// -// metricIt = metricsManager1001->mAllMetricProducers.begin(); -// for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); -// auto& metricProducer1002 = *metricIt; -// EXPECT_TRUE(metricProducer1002->isActive()); -// -// i = 0; -// for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) { -// if (metricsManager1001->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger1->atom_matcher_id()) { -// break; -// } -// } -// const auto& activation1001_1 = metricProducer1001->mEventActivationMap.at(i); -// EXPECT_EQ(100 * NS_PER_SEC, activation1001_1->ttl_ns); -// EXPECT_EQ(0, activation1001_1->start_ns); -// EXPECT_EQ(kNotActive, activation1001_1->state); -// -// i = 0; -// for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) { -// if (metricsManager1001->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger2->atom_matcher_id()) { -// break; -// } -// } -// -// const auto& activation1001_2 = metricProducer1001->mEventActivationMap.at(i); -// EXPECT_EQ(200 * NS_PER_SEC, activation1001_2->ttl_ns); -// EXPECT_EQ(0, activation1001_2->start_ns); -// EXPECT_EQ(kNotActive, activation1001_2->state); -// // }}}----------------------------------------------------------------------------------- -// -// // Load saved state from disk. -// processor2->LoadActiveConfigsFromDisk(); -// -// // Metric 1 active; Activation 1 is active, Activation 2 is not active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducer1001->isActive()); -// EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns); -// EXPECT_EQ(kActive, activation1001_1->state); -// EXPECT_EQ(0, activation1001_2->start_ns); -// EXPECT_EQ(kNotActive, activation1001_2->state); -// -// EXPECT_TRUE(metricProducer1002->isActive()); -// // }}}-------------------------------------------------------------------------------- -// -// // Trigger Activation 2 for Metric 1. -// auto screenOnEvent = CreateScreenStateChangedEvent( -// android::view::DISPLAY_STATE_ON, -// timeBase2 + 200 -// ); -// processor2->OnLogEvent(screenOnEvent.get()); -// -// // Metric 1 active; Activation 1 is active, Activation 2 is set to kActiveOnBoot -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducer1001->isActive()); -// EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns); -// EXPECT_EQ(kActive, activation1001_1->state); -// EXPECT_EQ(0, activation1001_2->start_ns); -// EXPECT_EQ(kActiveOnBoot, activation1001_2->state); -// -// EXPECT_TRUE(metricProducer1002->isActive()); -// // }}}--------------------------------------------------------------------------- -// -// // Simulate shutdown by saving state to disk -// shutDownTime = timeBase2 + 50 * NS_PER_SEC; -// processor2->SaveActiveConfigsToDisk(shutDownTime); -// EXPECT_TRUE(metricProducer1001->isActive()); -// EXPECT_TRUE(metricProducer1002->isActive()); -// ttl1 = timeBase2 + metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC - shutDownTime; -// int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC; -// -// // Simulate device restarted state by creating new instance of StatsLogProcessor with the -// // same config. -// long timeBase3 = timeBase2 + 120 * NS_PER_SEC; -// sp<StatsLogProcessor> processor3 = -// CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1); -// -// // Metric 1 is not active. -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor3->mMetricsManagers.size()); -// it = processor3->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor3->mMetricsManagers.end()); -// auto& metricsManagerTimeBase3 = it->second; -// EXPECT_TRUE(metricsManagerTimeBase3->isActive()); -// -// metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin(); -// for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end()); -// auto& metricProducerTimeBase3_1 = *metricIt; -// EXPECT_FALSE(metricProducerTimeBase3_1->isActive()); -// -// metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin(); -// for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end()); -// auto& metricProducerTimeBase3_2 = *metricIt; -// EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); -// -// i = 0; -// for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) { -// if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger1->atom_matcher_id()) { -// break; -// } -// } -// const auto& activationTimeBase3_1 = metricProducerTimeBase3_1->mEventActivationMap.at(i); -// EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase3_1->ttl_ns); -// EXPECT_EQ(0, activationTimeBase3_1->start_ns); -// EXPECT_EQ(kNotActive, activationTimeBase3_1->state); -// -// i = 0; -// for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) { -// if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger2->atom_matcher_id()) { -// break; -// } -// } -// -// const auto& activationTimeBase3_2 = metricProducerTimeBase3_1->mEventActivationMap.at(i); -// EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase3_2->ttl_ns); -// EXPECT_EQ(0, activationTimeBase3_2->start_ns); -// EXPECT_EQ(kNotActive, activationTimeBase3_2->state); -// -// EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); -// // }}}---------------------------------------------------------------------------------- -// -// // Load saved state from disk. -// processor3->LoadActiveConfigsFromDisk(); -// -// // Metric 1 active: Activation 1 is active, Activation 2 is active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducerTimeBase3_1->isActive()); -// EXPECT_EQ(timeBase3 + ttl1 - activationTimeBase3_1->ttl_ns, activationTimeBase3_1->start_ns); -// EXPECT_EQ(kActive, activationTimeBase3_1->state); -// EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns); -// EXPECT_EQ(kActive, activationTimeBase3_2->state); -// -// EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); -// // }}}------------------------------------------------------------------------------- -// -// // Trigger Activation 2 for Metric 1 again. -// screenOnEvent = CreateScreenStateChangedEvent( -// android::view::DISPLAY_STATE_ON, -// timeBase3 + 100 * NS_PER_SEC -// ); -// processor3->OnLogEvent(screenOnEvent.get()); -// -// // Metric 1 active; Activation 1 is not active, Activation 2 is set to active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducerTimeBase3_1->isActive()); -// EXPECT_EQ(kNotActive, activationTimeBase3_1->state); -// EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns); -// EXPECT_EQ(kActive, activationTimeBase3_2->state); -// -// EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); -// // }}}--------------------------------------------------------------------------- -// -// // Simulate shutdown by saving state to disk. -// shutDownTime = timeBase3 + 500 * NS_PER_SEC; -// processor3->SaveActiveConfigsToDisk(shutDownTime); -// EXPECT_TRUE(metricProducer1001->isActive()); -// EXPECT_TRUE(metricProducer1002->isActive()); -// ttl1 = timeBase3 + ttl1 - shutDownTime; -// ttl2 = timeBase3 + metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - shutDownTime; -// -// // Simulate device restarted state by creating new instance of StatsLogProcessor with the -// // same config. -// long timeBase4 = timeBase3 + 600 * NS_PER_SEC; -// sp<StatsLogProcessor> processor4 = -// CreateStatsLogProcessor(timeBase4, timeBase4, config1, cfgKey1); -// -// // Metric 1 is not active. -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor4->mMetricsManagers.size()); -// it = processor4->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor4->mMetricsManagers.end()); -// auto& metricsManagerTimeBase4 = it->second; -// EXPECT_TRUE(metricsManagerTimeBase4->isActive()); -// -// metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin(); -// for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId1) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end()); -// auto& metricProducerTimeBase4_1 = *metricIt; -// EXPECT_FALSE(metricProducerTimeBase4_1->isActive()); -// -// metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin(); -// for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) { -// if ((*metricIt)->getMetricId() == metricId2) { -// break; -// } -// } -// EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end()); -// auto& metricProducerTimeBase4_2 = *metricIt; -// EXPECT_TRUE(metricProducerTimeBase4_2->isActive()); -// -// i = 0; -// for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) { -// if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger1->atom_matcher_id()) { -// break; -// } -// } -// const auto& activationTimeBase4_1 = metricProducerTimeBase4_1->mEventActivationMap.at(i); -// EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase4_1->ttl_ns); -// EXPECT_EQ(0, activationTimeBase4_1->start_ns); -// EXPECT_EQ(kNotActive, activationTimeBase4_1->state); -// -// i = 0; -// for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) { -// if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() == -// metric1ActivationTrigger2->atom_matcher_id()) { -// break; -// } -// } -// -// const auto& activationTimeBase4_2 = metricProducerTimeBase4_1->mEventActivationMap.at(i); -// EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase4_2->ttl_ns); -// EXPECT_EQ(0, activationTimeBase4_2->start_ns); -// EXPECT_EQ(kNotActive, activationTimeBase4_2->state); -// -// EXPECT_TRUE(metricProducerTimeBase4_2->isActive()); -// // }}}---------------------------------------------------------------------------------- -// -// // Load saved state from disk. -// processor4->LoadActiveConfigsFromDisk(); -// -// // Metric 1 active: Activation 1 is not active, Activation 2 is not active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_FALSE(metricProducerTimeBase4_1->isActive()); -// EXPECT_EQ(kNotActive, activationTimeBase4_1->state); -// EXPECT_EQ(kNotActive, activationTimeBase4_2->state); -// -// EXPECT_TRUE(metricProducerTimeBase4_2->isActive()); -// // }}}------------------------------------------------------------------------------- -//} -// -//TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActivationTypes) { -// int uid = 1111; -// -// // Create config with 2 metrics: -// // Metric 1: Activate on boot with 2 activations -// // Metric 2: Always active -// StatsdConfig config1; -// config1.set_id(12341); -// config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); -// auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher(); -// *config1.add_atom_matcher() = wakelockAcquireMatcher; -// *config1.add_atom_matcher() = screenOnMatcher; -// -// long metricId1 = 1234561; -// long metricId2 = 1234562; -// -// auto countMetric1 = config1.add_count_metric(); -// countMetric1->set_id(metricId1); -// countMetric1->set_what(wakelockAcquireMatcher.id()); -// countMetric1->set_bucket(FIVE_MINUTES); -// -// auto countMetric2 = config1.add_count_metric(); -// countMetric2->set_id(metricId2); -// countMetric2->set_what(wakelockAcquireMatcher.id()); -// countMetric2->set_bucket(FIVE_MINUTES); -// -// auto metric1Activation = config1.add_metric_activation(); -// metric1Activation->set_metric_id(metricId1); -// metric1Activation->set_activation_type(ACTIVATE_ON_BOOT); -// auto metric1ActivationTrigger1 = metric1Activation->add_event_activation(); -// metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id()); -// metric1ActivationTrigger1->set_ttl_seconds(100); -// auto metric1ActivationTrigger2 = metric1Activation->add_event_activation(); -// metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id()); -// metric1ActivationTrigger2->set_ttl_seconds(200); -// metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY); -// -// ConfigKey cfgKey1(uid, 12341); -// long timeBase1 = 1; -// sp<StatsLogProcessor> processor1 = -// CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1); -// -// // Metric 1 is not active. -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor1->mMetricsManagers.size()); -// auto it = processor1->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor1->mMetricsManagers.end()); -// auto& metricsManager1 = it->second; -// EXPECT_TRUE(metricsManager1->isActive()); -// -// EXPECT_EQ(metricsManager1->mAllMetricProducers.size(), 2); -// // We assume that the index of a MetricProducer within the mAllMetricProducers -// // array follows the order in which metrics are added to the config. -// auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0]; -// EXPECT_EQ(metricProducer1_1->getMetricId(), metricId1); -// EXPECT_FALSE(metricProducer1_1->isActive()); // inactive due to associated MetricActivation -// -// auto& metricProducer1_2 = metricsManager1->mAllMetricProducers[1]; -// EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2); -// EXPECT_TRUE(metricProducer1_2->isActive()); -// -// EXPECT_EQ(metricProducer1_1->mEventActivationMap.size(), 2); -// // The key in mEventActivationMap is the index of the associated atom matcher. We assume -// // that matchers are indexed in the order that they are added to the config. -// const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0); -// EXPECT_EQ(100 * NS_PER_SEC, activation1_1_1->ttl_ns); -// EXPECT_EQ(0, activation1_1_1->start_ns); -// EXPECT_EQ(kNotActive, activation1_1_1->state); -// EXPECT_EQ(ACTIVATE_ON_BOOT, activation1_1_1->activationType); -// -// const auto& activation1_1_2 = metricProducer1_1->mEventActivationMap.at(1); -// EXPECT_EQ(200 * NS_PER_SEC, activation1_1_2->ttl_ns); -// EXPECT_EQ(0, activation1_1_2->start_ns); -// EXPECT_EQ(kNotActive, activation1_1_2->state); -// EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1_1_2->activationType); -// // }}}------------------------------------------------------------------------------ -// -// // Trigger Activation 1 for Metric 1 -// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")}; -// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1); -// processor1->OnLogEvent(event.get()); -// -// // Metric 1 is not active; Activation 1 set to kActiveOnBoot -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_FALSE(metricProducer1_1->isActive()); -// EXPECT_EQ(0, activation1_1_1->start_ns); -// EXPECT_EQ(kActiveOnBoot, activation1_1_1->state); -// EXPECT_EQ(0, activation1_1_2->start_ns); -// EXPECT_EQ(kNotActive, activation1_1_2->state); -// -// EXPECT_TRUE(metricProducer1_2->isActive()); -// // }}}----------------------------------------------------------------------------- -// -// // Simulate shutdown by saving state to disk -// int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; -// processor1->SaveActiveConfigsToDisk(shutDownTime); -// EXPECT_FALSE(metricProducer1_1->isActive()); -// -// // Simulate device restarted state by creating new instance of StatsLogProcessor with the -// // same config. -// long timeBase2 = 1000; -// sp<StatsLogProcessor> processor2 = -// CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); -// -// // Metric 1 is not active. -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor2->mMetricsManagers.size()); -// it = processor2->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor2->mMetricsManagers.end()); -// auto& metricsManager2 = it->second; -// EXPECT_TRUE(metricsManager2->isActive()); -// -// EXPECT_EQ(metricsManager2->mAllMetricProducers.size(), 2); -// // We assume that the index of a MetricProducer within the mAllMetricProducers -// // array follows the order in which metrics are added to the config. -// auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0]; -// EXPECT_EQ(metricProducer2_1->getMetricId(), metricId1); -// EXPECT_FALSE(metricProducer2_1->isActive()); -// -// auto& metricProducer2_2 = metricsManager2->mAllMetricProducers[1]; -// EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2); -// EXPECT_TRUE(metricProducer2_2->isActive()); -// -// EXPECT_EQ(metricProducer2_1->mEventActivationMap.size(), 2); -// // The key in mEventActivationMap is the index of the associated atom matcher. We assume -// // that matchers are indexed in the order that they are added to the config. -// const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0); -// EXPECT_EQ(100 * NS_PER_SEC, activation2_1_1->ttl_ns); -// EXPECT_EQ(0, activation2_1_1->start_ns); -// EXPECT_EQ(kNotActive, activation2_1_1->state); -// EXPECT_EQ(ACTIVATE_ON_BOOT, activation2_1_1->activationType); -// -// const auto& activation2_1_2 = metricProducer2_1->mEventActivationMap.at(1); -// EXPECT_EQ(200 * NS_PER_SEC, activation2_1_2->ttl_ns); -// EXPECT_EQ(0, activation2_1_2->start_ns); -// EXPECT_EQ(kNotActive, activation2_1_2->state); -// EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2_1_2->activationType); -// // }}}----------------------------------------------------------------------------------- -// -// // Load saved state from disk. -// processor2->LoadActiveConfigsFromDisk(); -// -// // Metric 1 active; Activation 1 is active, Activation 2 is not active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducer2_1->isActive()); -// int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC; -// EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns); -// EXPECT_EQ(kActive, activation2_1_1->state); -// EXPECT_EQ(0, activation2_1_2->start_ns); -// EXPECT_EQ(kNotActive, activation2_1_2->state); -// -// EXPECT_TRUE(metricProducer2_2->isActive()); -// // }}}-------------------------------------------------------------------------------- -// -// // Trigger Activation 2 for Metric 1. -// auto screenOnEvent = CreateScreenStateChangedEvent( -// android::view::DISPLAY_STATE_ON, -// timeBase2 + 200 -// ); -// processor2->OnLogEvent(screenOnEvent.get()); -// -// // Metric 1 active; Activation 1 is active, Activation 2 is active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducer2_1->isActive()); -// EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns); -// EXPECT_EQ(kActive, activation2_1_1->state); -// EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation2_1_2->start_ns); -// EXPECT_EQ(kActive, activation2_1_2->state); -// -// EXPECT_TRUE(metricProducer2_2->isActive()); -// // }}}--------------------------------------------------------------------------- -// -// // Simulate shutdown by saving state to disk -// shutDownTime = timeBase2 + 50 * NS_PER_SEC; -// processor2->SaveActiveConfigsToDisk(shutDownTime); -// EXPECT_TRUE(metricProducer2_1->isActive()); -// EXPECT_TRUE(metricProducer2_2->isActive()); -// ttl1 -= shutDownTime - timeBase2; -// int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC -// - (shutDownTime - screenOnEvent->GetElapsedTimestampNs()); -// -// // Simulate device restarted state by creating new instance of StatsLogProcessor with the -// // same config. -// long timeBase3 = timeBase2 + 120 * NS_PER_SEC; -// sp<StatsLogProcessor> processor3 = -// CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1); -// -// // Metric 1 is not active. -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor3->mMetricsManagers.size()); -// it = processor3->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor3->mMetricsManagers.end()); -// auto& metricsManager3 = it->second; -// EXPECT_TRUE(metricsManager3->isActive()); -// -// EXPECT_EQ(metricsManager3->mAllMetricProducers.size(), 2); -// // We assume that the index of a MetricProducer within the mAllMetricProducers -// // array follows the order in which metrics are added to the config. -// auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0]; -// EXPECT_EQ(metricProducer3_1->getMetricId(), metricId1); -// EXPECT_FALSE(metricProducer3_1->isActive()); -// -// auto& metricProducer3_2 = metricsManager3->mAllMetricProducers[1]; -// EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2); -// EXPECT_TRUE(metricProducer3_2->isActive()); -// -// EXPECT_EQ(metricProducer3_1->mEventActivationMap.size(), 2); -// // The key in mEventActivationMap is the index of the associated atom matcher. We assume -// // that matchers are indexed in the order that they are added to the config. -// const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0); -// EXPECT_EQ(100 * NS_PER_SEC, activation3_1_1->ttl_ns); -// EXPECT_EQ(0, activation3_1_1->start_ns); -// EXPECT_EQ(kNotActive, activation3_1_1->state); -// EXPECT_EQ(ACTIVATE_ON_BOOT, activation3_1_1->activationType); -// -// const auto& activation3_1_2 = metricProducer3_1->mEventActivationMap.at(1); -// EXPECT_EQ(200 * NS_PER_SEC, activation3_1_2->ttl_ns); -// EXPECT_EQ(0, activation3_1_2->start_ns); -// EXPECT_EQ(kNotActive, activation3_1_2->state); -// EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation3_1_2->activationType); -// // }}}---------------------------------------------------------------------------------- -// -// // Load saved state from disk. -// processor3->LoadActiveConfigsFromDisk(); -// -// // Metric 1 active: Activation 1 is active, Activation 2 is active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducer3_1->isActive()); -// EXPECT_EQ(timeBase3 + ttl1 - activation3_1_1->ttl_ns, activation3_1_1->start_ns); -// EXPECT_EQ(kActive, activation3_1_1->state); -// EXPECT_EQ(timeBase3 + ttl2 - activation3_1_2->ttl_ns, activation3_1_2->start_ns); -// EXPECT_EQ(kActive, activation3_1_2->state); -// -// EXPECT_TRUE(metricProducer3_2->isActive()); -// // }}}------------------------------------------------------------------------------- -// -// -// // Trigger Activation 2 for Metric 1 again. -// screenOnEvent = CreateScreenStateChangedEvent( -// android::view::DISPLAY_STATE_ON, -// timeBase3 + 100 * NS_PER_SEC -// ); -// processor3->OnLogEvent(screenOnEvent.get()); -// -// // Metric 1 active; Activation 1 is inactive (above screenOnEvent causes ttl1 to expire), -// // Activation 2 is set to active -// // Metric 2 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_TRUE(metricProducer3_1->isActive()); -// EXPECT_EQ(kNotActive, activation3_1_1->state); -// EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation3_1_2->start_ns); -// EXPECT_EQ(kActive, activation3_1_2->state); -// -// EXPECT_TRUE(metricProducer3_2->isActive()); -// // }}}--------------------------------------------------------------------------- -//} -// -//TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) { -// int uid = 9876; -// long configId = 12341; -// -// // Create config with 3 metrics: -// // Metric 1: Activate on 2 activations, 1 on boot, 1 immediate. -// // Metric 2: Activate on 2 activations, 1 on boot, 1 immediate. -// // Metric 3: Always active -// StatsdConfig config1; -// config1.set_id(configId); -// config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. -// auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); -// auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher(); -// auto jobStartMatcher = CreateStartScheduledJobAtomMatcher(); -// auto jobFinishMatcher = CreateFinishScheduledJobAtomMatcher(); -// *config1.add_atom_matcher() = wakelockAcquireMatcher; -// *config1.add_atom_matcher() = screenOnMatcher; -// *config1.add_atom_matcher() = jobStartMatcher; -// *config1.add_atom_matcher() = jobFinishMatcher; -// -// long metricId1 = 1234561; -// long metricId2 = 1234562; -// long metricId3 = 1234563; -// -// auto countMetric1 = config1.add_count_metric(); -// countMetric1->set_id(metricId1); -// countMetric1->set_what(wakelockAcquireMatcher.id()); -// countMetric1->set_bucket(FIVE_MINUTES); -// -// auto countMetric2 = config1.add_count_metric(); -// countMetric2->set_id(metricId2); -// countMetric2->set_what(wakelockAcquireMatcher.id()); -// countMetric2->set_bucket(FIVE_MINUTES); -// -// auto countMetric3 = config1.add_count_metric(); -// countMetric3->set_id(metricId3); -// countMetric3->set_what(wakelockAcquireMatcher.id()); -// countMetric3->set_bucket(FIVE_MINUTES); -// -// // Metric 1 activates on boot for wakelock acquire, immediately for screen on. -// auto metric1Activation = config1.add_metric_activation(); -// metric1Activation->set_metric_id(metricId1); -// auto metric1ActivationTrigger1 = metric1Activation->add_event_activation(); -// metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id()); -// metric1ActivationTrigger1->set_ttl_seconds(100); -// metric1ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT); -// auto metric1ActivationTrigger2 = metric1Activation->add_event_activation(); -// metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id()); -// metric1ActivationTrigger2->set_ttl_seconds(200); -// metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY); -// -// // Metric 2 activates on boot for scheduled job start, immediately for scheduled job finish. -// auto metric2Activation = config1.add_metric_activation(); -// metric2Activation->set_metric_id(metricId2); -// auto metric2ActivationTrigger1 = metric2Activation->add_event_activation(); -// metric2ActivationTrigger1->set_atom_matcher_id(jobStartMatcher.id()); -// metric2ActivationTrigger1->set_ttl_seconds(100); -// metric2ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT); -// auto metric2ActivationTrigger2 = metric2Activation->add_event_activation(); -// metric2ActivationTrigger2->set_atom_matcher_id(jobFinishMatcher.id()); -// metric2ActivationTrigger2->set_ttl_seconds(200); -// metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY); -// -// // Send the config. -// shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); -// string serialized = config1.SerializeAsString(); -// service->addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()}); -// -// // Make sure the config is stored on disk. Otherwise, we will not reset on system server death. -// StatsdConfig tmpConfig; -// ConfigKey cfgKey1(uid, configId); -// EXPECT_TRUE(StorageManager::readConfigFromDisk(cfgKey1, &tmpConfig)); -// -// // Metric 1 is not active. -// // Metric 2 is not active. -// // Metric 3 is active. -// // {{{--------------------------------------------------------------------------- -// sp<StatsLogProcessor> processor = service->mProcessor; -// EXPECT_EQ(1, processor->mMetricsManagers.size()); -// auto it = processor->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor->mMetricsManagers.end()); -// auto& metricsManager1 = it->second; -// EXPECT_TRUE(metricsManager1->isActive()); -// EXPECT_EQ(3, metricsManager1->mAllMetricProducers.size()); -// -// auto& metricProducer1 = metricsManager1->mAllMetricProducers[0]; -// EXPECT_EQ(metricId1, metricProducer1->getMetricId()); -// EXPECT_FALSE(metricProducer1->isActive()); -// -// auto& metricProducer2 = metricsManager1->mAllMetricProducers[1]; -// EXPECT_EQ(metricId2, metricProducer2->getMetricId()); -// EXPECT_FALSE(metricProducer2->isActive()); -// -// auto& metricProducer3 = metricsManager1->mAllMetricProducers[2]; -// EXPECT_EQ(metricId3, metricProducer3->getMetricId()); -// EXPECT_TRUE(metricProducer3->isActive()); -// -// // Check event activations. -// EXPECT_EQ(metricsManager1->mAllAtomMatchers.size(), 4); -// EXPECT_EQ(metricsManager1->mAllAtomMatchers[0]->getId(), -// metric1ActivationTrigger1->atom_matcher_id()); -// const auto& activation1 = metricProducer1->mEventActivationMap.at(0); -// EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns); -// EXPECT_EQ(0, activation1->start_ns); -// EXPECT_EQ(kNotActive, activation1->state); -// EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType); -// -// EXPECT_EQ(metricsManager1->mAllAtomMatchers[1]->getId(), -// metric1ActivationTrigger2->atom_matcher_id()); -// const auto& activation2 = metricProducer1->mEventActivationMap.at(1); -// EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns); -// EXPECT_EQ(0, activation2->start_ns); -// EXPECT_EQ(kNotActive, activation2->state); -// EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType); -// -// EXPECT_EQ(metricsManager1->mAllAtomMatchers[2]->getId(), -// metric2ActivationTrigger1->atom_matcher_id()); -// const auto& activation3 = metricProducer2->mEventActivationMap.at(2); -// EXPECT_EQ(100 * NS_PER_SEC, activation3->ttl_ns); -// EXPECT_EQ(0, activation3->start_ns); -// EXPECT_EQ(kNotActive, activation3->state); -// EXPECT_EQ(ACTIVATE_ON_BOOT, activation3->activationType); -// -// EXPECT_EQ(metricsManager1->mAllAtomMatchers[3]->getId(), -// metric2ActivationTrigger2->atom_matcher_id()); -// const auto& activation4 = metricProducer2->mEventActivationMap.at(3); -// EXPECT_EQ(200 * NS_PER_SEC, activation4->ttl_ns); -// EXPECT_EQ(0, activation4->start_ns); -// EXPECT_EQ(kNotActive, activation4->state); -// EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation4->activationType); -// // }}}------------------------------------------------------------------------------ -// -// // Trigger Activation 1 for Metric 1. Should activate on boot. -// // Trigger Activation 4 for Metric 2. Should activate immediately. -// long configAddedTimeNs = metricsManager1->mLastReportTimeNs; -// std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")}; -// auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 1 + configAddedTimeNs); -// processor->OnLogEvent(event.get()); -// -// event = CreateFinishScheduledJobEvent(attributions1, "finish1", 2 + configAddedTimeNs); -// processor->OnLogEvent(event.get()); -// -// // Metric 1 is not active; Activation 1 set to kActiveOnBoot -// // Metric 2 is active. Activation 4 set to kActive -// // Metric 3 is active. -// // {{{--------------------------------------------------------------------------- -// EXPECT_FALSE(metricProducer1->isActive()); -// EXPECT_EQ(0, activation1->start_ns); -// EXPECT_EQ(kActiveOnBoot, activation1->state); -// EXPECT_EQ(0, activation2->start_ns); -// EXPECT_EQ(kNotActive, activation2->state); -// -// EXPECT_TRUE(metricProducer2->isActive()); -// EXPECT_EQ(0, activation3->start_ns); -// EXPECT_EQ(kNotActive, activation3->state); -// EXPECT_EQ(2 + configAddedTimeNs, activation4->start_ns); -// EXPECT_EQ(kActive, activation4->state); -// -// EXPECT_TRUE(metricProducer3->isActive()); -// // }}}----------------------------------------------------------------------------- -// -// // Can't fake time with StatsService. -// // Lets get a time close to the system server death time and make sure it's sane. -// int64_t approximateSystemServerDeath = getElapsedRealtimeNs(); -// EXPECT_TRUE(approximateSystemServerDeath > 2 + configAddedTimeNs); -// EXPECT_TRUE(approximateSystemServerDeath < NS_PER_SEC + configAddedTimeNs); -// -// // System server dies. -// service->statsCompanionServiceDiedImpl(); -// -// // We should have a new metrics manager. Lets get it and ensure activation status is restored. -// // {{{--------------------------------------------------------------------------- -// EXPECT_EQ(1, processor->mMetricsManagers.size()); -// it = processor->mMetricsManagers.find(cfgKey1); -// EXPECT_TRUE(it != processor->mMetricsManagers.end()); -// auto& metricsManager2 = it->second; -// EXPECT_TRUE(metricsManager2->isActive()); -// EXPECT_EQ(3, metricsManager2->mAllMetricProducers.size()); -// -// auto& metricProducer1001 = metricsManager2->mAllMetricProducers[0]; -// EXPECT_EQ(metricId1, metricProducer1001->getMetricId()); -// EXPECT_FALSE(metricProducer1001->isActive()); -// -// auto& metricProducer1002 = metricsManager2->mAllMetricProducers[1]; -// EXPECT_EQ(metricId2, metricProducer1002->getMetricId()); -// EXPECT_TRUE(metricProducer1002->isActive()); -// -// auto& metricProducer1003 = metricsManager2->mAllMetricProducers[2]; -// EXPECT_EQ(metricId3, metricProducer1003->getMetricId()); -// EXPECT_TRUE(metricProducer1003->isActive()); -// -// // Check event activations. -// // Activation 1 is kActiveOnBoot. -// // Activation 2 and 3 are not active. -// // Activation 4 is active. -// EXPECT_EQ(metricsManager2->mAllAtomMatchers.size(), 4); -// EXPECT_EQ(metricsManager2->mAllAtomMatchers[0]->getId(), -// metric1ActivationTrigger1->atom_matcher_id()); -// const auto& activation1001 = metricProducer1001->mEventActivationMap.at(0); -// EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns); -// EXPECT_EQ(0, activation1001->start_ns); -// EXPECT_EQ(kActiveOnBoot, activation1001->state); -// EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001->activationType); -// -// EXPECT_EQ(metricsManager2->mAllAtomMatchers[1]->getId(), -// metric1ActivationTrigger2->atom_matcher_id()); -// const auto& activation1002 = metricProducer1001->mEventActivationMap.at(1); -// EXPECT_EQ(200 * NS_PER_SEC, activation1002->ttl_ns); -// EXPECT_EQ(0, activation1002->start_ns); -// EXPECT_EQ(kNotActive, activation1002->state); -// EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1002->activationType); -// -// EXPECT_EQ(metricsManager2->mAllAtomMatchers[2]->getId(), -// metric2ActivationTrigger1->atom_matcher_id()); -// const auto& activation1003 = metricProducer1002->mEventActivationMap.at(2); -// EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns); -// EXPECT_EQ(0, activation1003->start_ns); -// EXPECT_EQ(kNotActive, activation1003->state); -// EXPECT_EQ(ACTIVATE_ON_BOOT, activation1003->activationType); -// -// EXPECT_EQ(metricsManager2->mAllAtomMatchers[3]->getId(), -// metric2ActivationTrigger2->atom_matcher_id()); -// const auto& activation1004 = metricProducer1002->mEventActivationMap.at(3); -// EXPECT_EQ(200 * NS_PER_SEC, activation1004->ttl_ns); -// EXPECT_EQ(2 + configAddedTimeNs, activation1004->start_ns); -// EXPECT_EQ(kActive, activation1004->state); -// EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1004->activationType); -// // }}}------------------------------------------------------------------------------ -// -// // Clear the data stored on disk as a result of the system server death. -// vector<uint8_t> buffer; -// processor->onDumpReport(cfgKey1, configAddedTimeNs + NS_PER_SEC, false, true, -// ADB_DUMP, FAST, &buffer); -//} +TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) { + // Setup a simple config. + StatsdConfig config; + config.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); + *config.add_atom_matcher() = wakelockAcquireMatcher; + + auto countMetric = config.add_count_metric(); + countMetric->set_id(123456); + countMetric->set_what(wakelockAcquireMatcher.id()); + countMetric->set_bucket(FIVE_MINUTES); + + ConfigKey cfgKey; + sp<StatsLogProcessor> processor = CreateStatsLogProcessor(1, 1, config, cfgKey); + + std::vector<int> attributionUids = {111}; + std::vector<string> attributionTags = {"App1"}; + std::unique_ptr<LogEvent> event = + CreateAcquireWakelockEvent(2 /*timestamp*/, attributionUids, attributionTags, "wl1"); + processor->OnLogEvent(event.get()); + + vector<uint8_t> bytes; + ConfigMetricsReportList output; + + // Dump report WITHOUT erasing data. + processor->onDumpReport(cfgKey, 3, true, false /* Do NOT erase data. */, ADB_DUMP, FAST, + &bytes); + output.ParseFromArray(bytes.data(), bytes.size()); + EXPECT_EQ(output.reports_size(), 1); + EXPECT_EQ(output.reports(0).metrics_size(), 1); + EXPECT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1); + + // Dump report WITH erasing data. There should be data since we didn't previously erase it. + processor->onDumpReport(cfgKey, 4, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes); + output.ParseFromArray(bytes.data(), bytes.size()); + EXPECT_EQ(output.reports_size(), 1); + EXPECT_EQ(output.reports(0).metrics_size(), 1); + EXPECT_EQ(output.reports(0).metrics(0).count_metrics().data_size(), 1); + + // Dump report again. There should be no data since we erased it. + processor->onDumpReport(cfgKey, 5, true, true /* DO erase data. */, ADB_DUMP, FAST, &bytes); + output.ParseFromArray(bytes.data(), bytes.size()); + // We don't care whether statsd has a report, as long as it has no count metrics in it. + bool noData = output.reports_size() == 0 || output.reports(0).metrics_size() == 0 || + output.reports(0).metrics(0).count_metrics().data_size() == 0; + EXPECT_TRUE(noData); +} + +TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) { + int uid = 1111; + + // Setup a simple config, no activation + StatsdConfig config1; + int64_t cfgId1 = 12341; + config1.set_id(cfgId1); + config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); + *config1.add_atom_matcher() = wakelockAcquireMatcher; + + long metricId1 = 1234561; + long metricId2 = 1234562; + auto countMetric1 = config1.add_count_metric(); + countMetric1->set_id(metricId1); + countMetric1->set_what(wakelockAcquireMatcher.id()); + countMetric1->set_bucket(FIVE_MINUTES); + + auto countMetric2 = config1.add_count_metric(); + countMetric2->set_id(metricId2); + countMetric2->set_what(wakelockAcquireMatcher.id()); + countMetric2->set_bucket(FIVE_MINUTES); + + ConfigKey cfgKey1(uid, cfgId1); + + // Add another config, with two metrics, one with activation + StatsdConfig config2; + int64_t cfgId2 = 12342; + config2.set_id(cfgId2); + config2.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + *config2.add_atom_matcher() = wakelockAcquireMatcher; + + long metricId3 = 1234561; + long metricId4 = 1234562; + + auto countMetric3 = config2.add_count_metric(); + countMetric3->set_id(metricId3); + countMetric3->set_what(wakelockAcquireMatcher.id()); + countMetric3->set_bucket(FIVE_MINUTES); + + auto countMetric4 = config2.add_count_metric(); + countMetric4->set_id(metricId4); + countMetric4->set_what(wakelockAcquireMatcher.id()); + countMetric4->set_bucket(FIVE_MINUTES); + + auto metric3Activation = config2.add_metric_activation(); + metric3Activation->set_metric_id(metricId3); + metric3Activation->set_activation_type(ACTIVATE_IMMEDIATELY); + auto metric3ActivationTrigger = metric3Activation->add_event_activation(); + metric3ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric3ActivationTrigger->set_ttl_seconds(100); + + ConfigKey cfgKey2(uid, cfgId2); + + // Add another config, with two metrics, both with activations + StatsdConfig config3; + int64_t cfgId3 = 12343; + config3.set_id(cfgId3); + config3.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + *config3.add_atom_matcher() = wakelockAcquireMatcher; + + long metricId5 = 1234565; + long metricId6 = 1234566; + auto countMetric5 = config3.add_count_metric(); + countMetric5->set_id(metricId5); + countMetric5->set_what(wakelockAcquireMatcher.id()); + countMetric5->set_bucket(FIVE_MINUTES); + + auto countMetric6 = config3.add_count_metric(); + countMetric6->set_id(metricId6); + countMetric6->set_what(wakelockAcquireMatcher.id()); + countMetric6->set_bucket(FIVE_MINUTES); + + auto metric5Activation = config3.add_metric_activation(); + metric5Activation->set_metric_id(metricId5); + metric5Activation->set_activation_type(ACTIVATE_IMMEDIATELY); + auto metric5ActivationTrigger = metric5Activation->add_event_activation(); + metric5ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric5ActivationTrigger->set_ttl_seconds(100); + + auto metric6Activation = config3.add_metric_activation(); + metric6Activation->set_metric_id(metricId6); + metric6Activation->set_activation_type(ACTIVATE_IMMEDIATELY); + auto metric6ActivationTrigger = metric6Activation->add_event_activation(); + metric6ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric6ActivationTrigger->set_ttl_seconds(200); + + ConfigKey cfgKey3(uid, cfgId3); + + sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> subscriberAlarmMonitor; + vector<int64_t> activeConfigsBroadcast; + + long timeBase1 = 1; + int broadcastCount = 0; + StatsLogProcessor processor( + m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, timeBase1, + [](const ConfigKey& key) { return true; }, + [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid, + const vector<int64_t>& activeConfigs) { + broadcastCount++; + EXPECT_EQ(broadcastUid, uid); + activeConfigsBroadcast.clear(); + activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(), + activeConfigs.end()); + return true; + }); + + processor.OnConfigUpdated(1, cfgKey1, config1); + processor.OnConfigUpdated(2, cfgKey2, config2); + processor.OnConfigUpdated(3, cfgKey3, config3); + + EXPECT_EQ(3, processor.mMetricsManagers.size()); + + // Expect the first config and both metrics in it to be active. + auto it = processor.mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor.mMetricsManagers.end()); + auto& metricsManager1 = it->second; + EXPECT_TRUE(metricsManager1->isActive()); + + auto metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer1 = *metricIt; + EXPECT_TRUE(metricProducer1->isActive()); + + metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer2 = *metricIt; + EXPECT_TRUE(metricProducer2->isActive()); + + // Expect config 2 to be active. Metric 3 shouldn't be active, metric 4 should be active. + it = processor.mMetricsManagers.find(cfgKey2); + EXPECT_TRUE(it != processor.mMetricsManagers.end()); + auto& metricsManager2 = it->second; + EXPECT_TRUE(metricsManager2->isActive()); + + metricIt = metricsManager2->mAllMetricProducers.begin(); + for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId3) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end()); + auto& metricProducer3 = *metricIt; + EXPECT_FALSE(metricProducer3->isActive()); + + metricIt = metricsManager2->mAllMetricProducers.begin(); + for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId4) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager2->mAllMetricProducers.end()); + auto& metricProducer4 = *metricIt; + EXPECT_TRUE(metricProducer4->isActive()); + + // Expect the third config and both metrics in it to be inactive. + it = processor.mMetricsManagers.find(cfgKey3); + EXPECT_TRUE(it != processor.mMetricsManagers.end()); + auto& metricsManager3 = it->second; + EXPECT_FALSE(metricsManager3->isActive()); + + metricIt = metricsManager3->mAllMetricProducers.begin(); + for (; metricIt != metricsManager2->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId5) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end()); + auto& metricProducer5 = *metricIt; + EXPECT_FALSE(metricProducer5->isActive()); + + metricIt = metricsManager3->mAllMetricProducers.begin(); + for (; metricIt != metricsManager3->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId6) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager3->mAllMetricProducers.end()); + auto& metricProducer6 = *metricIt; + EXPECT_FALSE(metricProducer6->isActive()); + + // No broadcast for active configs should have happened yet. + EXPECT_EQ(broadcastCount, 0); + + // Activate all 3 metrics that were not active. + std::vector<int> attributionUids = {111}; + std::vector<string> attributionTags = {"App1"}; + std::unique_ptr<LogEvent> event = + CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1"); + processor.OnLogEvent(event.get()); + + // Assert that all 3 configs are active. + EXPECT_TRUE(metricsManager1->isActive()); + EXPECT_TRUE(metricsManager2->isActive()); + EXPECT_TRUE(metricsManager3->isActive()); + + // A broadcast should have happened, and all 3 configs should be active in the broadcast. + EXPECT_EQ(broadcastCount, 1); + EXPECT_EQ(activeConfigsBroadcast.size(), 3); + EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId1) != + activeConfigsBroadcast.end()); + EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId2) != + activeConfigsBroadcast.end()); + EXPECT_TRUE(std::find(activeConfigsBroadcast.begin(), activeConfigsBroadcast.end(), cfgId3) != + activeConfigsBroadcast.end()); + + // When we shut down, metrics 3 & 5 have 100ns remaining, metric 6 has 100s + 100ns. + int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; + processor.SaveActiveConfigsToDisk(shutDownTime); + const int64_t ttl3 = event->GetElapsedTimestampNs() + + metric3ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime; + const int64_t ttl5 = event->GetElapsedTimestampNs() + + metric5ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime; + const int64_t ttl6 = event->GetElapsedTimestampNs() + + metric6ActivationTrigger->ttl_seconds() * NS_PER_SEC - shutDownTime; + + // Create a second StatsLogProcessor and push the same 3 configs. + long timeBase2 = 1000; + sp<StatsLogProcessor> processor2 = + CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); + processor2->OnConfigUpdated(timeBase2, cfgKey2, config2); + processor2->OnConfigUpdated(timeBase2, cfgKey3, config3); + + EXPECT_EQ(3, processor2->mMetricsManagers.size()); + + // First config and both metrics are active. + it = processor2->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor2->mMetricsManagers.end()); + auto& metricsManager1001 = it->second; + EXPECT_TRUE(metricsManager1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1001 = *metricIt; + EXPECT_TRUE(metricProducer1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1002 = *metricIt; + EXPECT_TRUE(metricProducer1002->isActive()); + + // Second config is active. Metric 3 is inactive, metric 4 is active. + it = processor2->mMetricsManagers.find(cfgKey2); + EXPECT_TRUE(it != processor2->mMetricsManagers.end()); + auto& metricsManager1002 = it->second; + EXPECT_TRUE(metricsManager1002->isActive()); + + metricIt = metricsManager1002->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId3) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end()); + auto& metricProducer1003 = *metricIt; + EXPECT_FALSE(metricProducer1003->isActive()); + + metricIt = metricsManager1002->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId4) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1002->mAllMetricProducers.end()); + auto& metricProducer1004 = *metricIt; + EXPECT_TRUE(metricProducer1004->isActive()); + + // Config 3 is inactive. both metrics are inactive. + it = processor2->mMetricsManagers.find(cfgKey3); + EXPECT_TRUE(it != processor2->mMetricsManagers.end()); + auto& metricsManager1003 = it->second; + EXPECT_FALSE(metricsManager1003->isActive()); + EXPECT_EQ(2, metricsManager1003->mAllMetricProducers.size()); + + metricIt = metricsManager1003->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1002->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId5) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end()); + auto& metricProducer1005 = *metricIt; + EXPECT_FALSE(metricProducer1005->isActive()); + + metricIt = metricsManager1003->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1003->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId6) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1003->mAllMetricProducers.end()); + auto& metricProducer1006 = *metricIt; + EXPECT_FALSE(metricProducer1006->isActive()); + + // Assert that all 3 metrics with activation are inactive and that the ttls were properly set. + EXPECT_FALSE(metricProducer1003->isActive()); + const auto& activation1003 = metricProducer1003->mEventActivationMap.begin()->second; + EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns); + EXPECT_EQ(0, activation1003->start_ns); + EXPECT_FALSE(metricProducer1005->isActive()); + const auto& activation1005 = metricProducer1005->mEventActivationMap.begin()->second; + EXPECT_EQ(100 * NS_PER_SEC, activation1005->ttl_ns); + EXPECT_EQ(0, activation1005->start_ns); + EXPECT_FALSE(metricProducer1006->isActive()); + const auto& activation1006 = metricProducer1006->mEventActivationMap.begin()->second; + EXPECT_EQ(200 * NS_PER_SEC, activation1006->ttl_ns); + EXPECT_EQ(0, activation1006->start_ns); + + processor2->LoadActiveConfigsFromDisk(); + + // After loading activations from disk, assert that all 3 metrics are active. + EXPECT_TRUE(metricProducer1003->isActive()); + EXPECT_EQ(timeBase2 + ttl3 - activation1003->ttl_ns, activation1003->start_ns); + EXPECT_TRUE(metricProducer1005->isActive()); + EXPECT_EQ(timeBase2 + ttl5 - activation1005->ttl_ns, activation1005->start_ns); + EXPECT_TRUE(metricProducer1006->isActive()); + EXPECT_EQ(timeBase2 + ttl6 - activation1006->ttl_ns, activation1003->start_ns); + + // Make sure no more broadcasts have happened. + EXPECT_EQ(broadcastCount, 1); +} + +TEST(StatsLogProcessorTest, TestActivationOnBoot) { + int uid = 1111; + + StatsdConfig config1; + config1.set_id(12341); + config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); + *config1.add_atom_matcher() = wakelockAcquireMatcher; + + long metricId1 = 1234561; + long metricId2 = 1234562; + auto countMetric1 = config1.add_count_metric(); + countMetric1->set_id(metricId1); + countMetric1->set_what(wakelockAcquireMatcher.id()); + countMetric1->set_bucket(FIVE_MINUTES); + + auto countMetric2 = config1.add_count_metric(); + countMetric2->set_id(metricId2); + countMetric2->set_what(wakelockAcquireMatcher.id()); + countMetric2->set_bucket(FIVE_MINUTES); + + auto metric1Activation = config1.add_metric_activation(); + metric1Activation->set_metric_id(metricId1); + metric1Activation->set_activation_type(ACTIVATE_ON_BOOT); + auto metric1ActivationTrigger = metric1Activation->add_event_activation(); + metric1ActivationTrigger->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric1ActivationTrigger->set_ttl_seconds(100); + + ConfigKey cfgKey1(uid, 12341); + long timeBase1 = 1; + sp<StatsLogProcessor> processor = + CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1); + + EXPECT_EQ(1, processor->mMetricsManagers.size()); + auto it = processor->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor->mMetricsManagers.end()); + auto& metricsManager1 = it->second; + EXPECT_TRUE(metricsManager1->isActive()); + + auto metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer1 = *metricIt; + EXPECT_FALSE(metricProducer1->isActive()); + + metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer2 = *metricIt; + EXPECT_TRUE(metricProducer2->isActive()); + + const auto& activation1 = metricProducer1->mEventActivationMap.begin()->second; + EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns); + EXPECT_EQ(0, activation1->start_ns); + EXPECT_EQ(kNotActive, activation1->state); + + std::vector<int> attributionUids = {111}; + std::vector<string> attributionTags = {"App1"}; + std::unique_ptr<LogEvent> event = + CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1"); + processor->OnLogEvent(event.get()); + + EXPECT_FALSE(metricProducer1->isActive()); + EXPECT_EQ(0, activation1->start_ns); + EXPECT_EQ(kActiveOnBoot, activation1->state); + + int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; + processor->SaveActiveConfigsToDisk(shutDownTime); + EXPECT_FALSE(metricProducer1->isActive()); + const int64_t ttl1 = metric1ActivationTrigger->ttl_seconds() * NS_PER_SEC; + + long timeBase2 = 1000; + sp<StatsLogProcessor> processor2 = + CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); + + EXPECT_EQ(1, processor2->mMetricsManagers.size()); + it = processor2->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor2->mMetricsManagers.end()); + auto& metricsManager1001 = it->second; + EXPECT_TRUE(metricsManager1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1001 = *metricIt; + EXPECT_FALSE(metricProducer1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1002 = *metricIt; + EXPECT_TRUE(metricProducer1002->isActive()); + + const auto& activation1001 = metricProducer1001->mEventActivationMap.begin()->second; + EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns); + EXPECT_EQ(0, activation1001->start_ns); + EXPECT_EQ(kNotActive, activation1001->state); + + processor2->LoadActiveConfigsFromDisk(); + + EXPECT_TRUE(metricProducer1001->isActive()); + EXPECT_EQ(timeBase2 + ttl1 - activation1001->ttl_ns, activation1001->start_ns); + EXPECT_EQ(kActive, activation1001->state); +} + +TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations) { + int uid = 1111; + + // Create config with 2 metrics: + // Metric 1: Activate on boot with 2 activations + // Metric 2: Always active + StatsdConfig config1; + config1.set_id(12341); + config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); + auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher(); + *config1.add_atom_matcher() = wakelockAcquireMatcher; + *config1.add_atom_matcher() = screenOnMatcher; + + long metricId1 = 1234561; + long metricId2 = 1234562; + + auto countMetric1 = config1.add_count_metric(); + countMetric1->set_id(metricId1); + countMetric1->set_what(wakelockAcquireMatcher.id()); + countMetric1->set_bucket(FIVE_MINUTES); + + auto countMetric2 = config1.add_count_metric(); + countMetric2->set_id(metricId2); + countMetric2->set_what(wakelockAcquireMatcher.id()); + countMetric2->set_bucket(FIVE_MINUTES); + + auto metric1Activation = config1.add_metric_activation(); + metric1Activation->set_metric_id(metricId1); + metric1Activation->set_activation_type(ACTIVATE_ON_BOOT); + auto metric1ActivationTrigger1 = metric1Activation->add_event_activation(); + metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric1ActivationTrigger1->set_ttl_seconds(100); + auto metric1ActivationTrigger2 = metric1Activation->add_event_activation(); + metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id()); + metric1ActivationTrigger2->set_ttl_seconds(200); + + ConfigKey cfgKey1(uid, 12341); + long timeBase1 = 1; + sp<StatsLogProcessor> processor = + CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1); + + // Metric 1 is not active. + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor->mMetricsManagers.size()); + auto it = processor->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor->mMetricsManagers.end()); + auto& metricsManager1 = it->second; + EXPECT_TRUE(metricsManager1->isActive()); + + auto metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer1 = *metricIt; + EXPECT_FALSE(metricProducer1->isActive()); + + metricIt = metricsManager1->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end()); + auto& metricProducer2 = *metricIt; + EXPECT_TRUE(metricProducer2->isActive()); + + int i = 0; + for (; i < metricsManager1->mAllAtomMatchers.size(); i++) { + if (metricsManager1->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger1->atom_matcher_id()) { + break; + } + } + const auto& activation1 = metricProducer1->mEventActivationMap.at(i); + EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns); + EXPECT_EQ(0, activation1->start_ns); + EXPECT_EQ(kNotActive, activation1->state); + + i = 0; + for (; i < metricsManager1->mAllAtomMatchers.size(); i++) { + if (metricsManager1->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger2->atom_matcher_id()) { + break; + } + } + const auto& activation2 = metricProducer1->mEventActivationMap.at(i); + EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns); + EXPECT_EQ(0, activation2->start_ns); + EXPECT_EQ(kNotActive, activation2->state); + // }}}------------------------------------------------------------------------------ + + // Trigger Activation 1 for Metric 1 + std::vector<int> attributionUids = {111}; + std::vector<string> attributionTags = {"App1"}; + std::unique_ptr<LogEvent> event = + CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1"); + processor->OnLogEvent(event.get()); + + // Metric 1 is not active; Activation 1 set to kActiveOnBoot + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_FALSE(metricProducer1->isActive()); + EXPECT_EQ(0, activation1->start_ns); + EXPECT_EQ(kActiveOnBoot, activation1->state); + EXPECT_EQ(0, activation2->start_ns); + EXPECT_EQ(kNotActive, activation2->state); + + EXPECT_TRUE(metricProducer2->isActive()); + // }}}----------------------------------------------------------------------------- + + // Simulate shutdown by saving state to disk + int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; + processor->SaveActiveConfigsToDisk(shutDownTime); + EXPECT_FALSE(metricProducer1->isActive()); + int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC; + + // Simulate device restarted state by creating new instance of StatsLogProcessor with the + // same config. + long timeBase2 = 1000; + sp<StatsLogProcessor> processor2 = + CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); + + // Metric 1 is not active. + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor2->mMetricsManagers.size()); + it = processor2->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor2->mMetricsManagers.end()); + auto& metricsManager1001 = it->second; + EXPECT_TRUE(metricsManager1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1001 = *metricIt; + EXPECT_FALSE(metricProducer1001->isActive()); + + metricIt = metricsManager1001->mAllMetricProducers.begin(); + for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end()); + auto& metricProducer1002 = *metricIt; + EXPECT_TRUE(metricProducer1002->isActive()); + + i = 0; + for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) { + if (metricsManager1001->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger1->atom_matcher_id()) { + break; + } + } + const auto& activation1001_1 = metricProducer1001->mEventActivationMap.at(i); + EXPECT_EQ(100 * NS_PER_SEC, activation1001_1->ttl_ns); + EXPECT_EQ(0, activation1001_1->start_ns); + EXPECT_EQ(kNotActive, activation1001_1->state); + + i = 0; + for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) { + if (metricsManager1001->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger2->atom_matcher_id()) { + break; + } + } + + const auto& activation1001_2 = metricProducer1001->mEventActivationMap.at(i); + EXPECT_EQ(200 * NS_PER_SEC, activation1001_2->ttl_ns); + EXPECT_EQ(0, activation1001_2->start_ns); + EXPECT_EQ(kNotActive, activation1001_2->state); + // }}}----------------------------------------------------------------------------------- + + // Load saved state from disk. + processor2->LoadActiveConfigsFromDisk(); + + // Metric 1 active; Activation 1 is active, Activation 2 is not active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducer1001->isActive()); + EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns); + EXPECT_EQ(kActive, activation1001_1->state); + EXPECT_EQ(0, activation1001_2->start_ns); + EXPECT_EQ(kNotActive, activation1001_2->state); + + EXPECT_TRUE(metricProducer1002->isActive()); + // }}}-------------------------------------------------------------------------------- + + // Trigger Activation 2 for Metric 1. + auto screenOnEvent = + CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON); + processor2->OnLogEvent(screenOnEvent.get()); + + // Metric 1 active; Activation 1 is active, Activation 2 is set to kActiveOnBoot + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducer1001->isActive()); + EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns); + EXPECT_EQ(kActive, activation1001_1->state); + EXPECT_EQ(0, activation1001_2->start_ns); + EXPECT_EQ(kActiveOnBoot, activation1001_2->state); + + EXPECT_TRUE(metricProducer1002->isActive()); + // }}}--------------------------------------------------------------------------- + + // Simulate shutdown by saving state to disk + shutDownTime = timeBase2 + 50 * NS_PER_SEC; + processor2->SaveActiveConfigsToDisk(shutDownTime); + EXPECT_TRUE(metricProducer1001->isActive()); + EXPECT_TRUE(metricProducer1002->isActive()); + ttl1 = timeBase2 + metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC - shutDownTime; + int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC; + + // Simulate device restarted state by creating new instance of StatsLogProcessor with the + // same config. + long timeBase3 = timeBase2 + 120 * NS_PER_SEC; + sp<StatsLogProcessor> processor3 = + CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1); + + // Metric 1 is not active. + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor3->mMetricsManagers.size()); + it = processor3->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor3->mMetricsManagers.end()); + auto& metricsManagerTimeBase3 = it->second; + EXPECT_TRUE(metricsManagerTimeBase3->isActive()); + + metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin(); + for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end()); + auto& metricProducerTimeBase3_1 = *metricIt; + EXPECT_FALSE(metricProducerTimeBase3_1->isActive()); + + metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin(); + for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end()); + auto& metricProducerTimeBase3_2 = *metricIt; + EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); + + i = 0; + for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) { + if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger1->atom_matcher_id()) { + break; + } + } + const auto& activationTimeBase3_1 = metricProducerTimeBase3_1->mEventActivationMap.at(i); + EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase3_1->ttl_ns); + EXPECT_EQ(0, activationTimeBase3_1->start_ns); + EXPECT_EQ(kNotActive, activationTimeBase3_1->state); + + i = 0; + for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) { + if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger2->atom_matcher_id()) { + break; + } + } + + const auto& activationTimeBase3_2 = metricProducerTimeBase3_1->mEventActivationMap.at(i); + EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase3_2->ttl_ns); + EXPECT_EQ(0, activationTimeBase3_2->start_ns); + EXPECT_EQ(kNotActive, activationTimeBase3_2->state); + + EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); + // }}}---------------------------------------------------------------------------------- + + // Load saved state from disk. + processor3->LoadActiveConfigsFromDisk(); + + // Metric 1 active: Activation 1 is active, Activation 2 is active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducerTimeBase3_1->isActive()); + EXPECT_EQ(timeBase3 + ttl1 - activationTimeBase3_1->ttl_ns, activationTimeBase3_1->start_ns); + EXPECT_EQ(kActive, activationTimeBase3_1->state); + EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns); + EXPECT_EQ(kActive, activationTimeBase3_2->state); + + EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); + // }}}------------------------------------------------------------------------------- + + // Trigger Activation 2 for Metric 1 again. + screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC, + android::view::DISPLAY_STATE_ON); + processor3->OnLogEvent(screenOnEvent.get()); + + // Metric 1 active; Activation 1 is not active, Activation 2 is set to active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducerTimeBase3_1->isActive()); + EXPECT_EQ(kNotActive, activationTimeBase3_1->state); + EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns); + EXPECT_EQ(kActive, activationTimeBase3_2->state); + + EXPECT_TRUE(metricProducerTimeBase3_2->isActive()); + // }}}--------------------------------------------------------------------------- + + // Simulate shutdown by saving state to disk. + shutDownTime = timeBase3 + 500 * NS_PER_SEC; + processor3->SaveActiveConfigsToDisk(shutDownTime); + EXPECT_TRUE(metricProducer1001->isActive()); + EXPECT_TRUE(metricProducer1002->isActive()); + ttl1 = timeBase3 + ttl1 - shutDownTime; + ttl2 = timeBase3 + metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - shutDownTime; + + // Simulate device restarted state by creating new instance of StatsLogProcessor with the + // same config. + long timeBase4 = timeBase3 + 600 * NS_PER_SEC; + sp<StatsLogProcessor> processor4 = + CreateStatsLogProcessor(timeBase4, timeBase4, config1, cfgKey1); + + // Metric 1 is not active. + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor4->mMetricsManagers.size()); + it = processor4->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor4->mMetricsManagers.end()); + auto& metricsManagerTimeBase4 = it->second; + EXPECT_TRUE(metricsManagerTimeBase4->isActive()); + + metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin(); + for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId1) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end()); + auto& metricProducerTimeBase4_1 = *metricIt; + EXPECT_FALSE(metricProducerTimeBase4_1->isActive()); + + metricIt = metricsManagerTimeBase4->mAllMetricProducers.begin(); + for (; metricIt != metricsManagerTimeBase4->mAllMetricProducers.end(); metricIt++) { + if ((*metricIt)->getMetricId() == metricId2) { + break; + } + } + EXPECT_TRUE(metricIt != metricsManagerTimeBase4->mAllMetricProducers.end()); + auto& metricProducerTimeBase4_2 = *metricIt; + EXPECT_TRUE(metricProducerTimeBase4_2->isActive()); + + i = 0; + for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) { + if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger1->atom_matcher_id()) { + break; + } + } + const auto& activationTimeBase4_1 = metricProducerTimeBase4_1->mEventActivationMap.at(i); + EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase4_1->ttl_ns); + EXPECT_EQ(0, activationTimeBase4_1->start_ns); + EXPECT_EQ(kNotActive, activationTimeBase4_1->state); + + i = 0; + for (; i < metricsManagerTimeBase4->mAllAtomMatchers.size(); i++) { + if (metricsManagerTimeBase4->mAllAtomMatchers[i]->getId() == + metric1ActivationTrigger2->atom_matcher_id()) { + break; + } + } + + const auto& activationTimeBase4_2 = metricProducerTimeBase4_1->mEventActivationMap.at(i); + EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase4_2->ttl_ns); + EXPECT_EQ(0, activationTimeBase4_2->start_ns); + EXPECT_EQ(kNotActive, activationTimeBase4_2->state); + + EXPECT_TRUE(metricProducerTimeBase4_2->isActive()); + // }}}---------------------------------------------------------------------------------- + + // Load saved state from disk. + processor4->LoadActiveConfigsFromDisk(); + + // Metric 1 active: Activation 1 is not active, Activation 2 is not active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_FALSE(metricProducerTimeBase4_1->isActive()); + EXPECT_EQ(kNotActive, activationTimeBase4_1->state); + EXPECT_EQ(kNotActive, activationTimeBase4_2->state); + + EXPECT_TRUE(metricProducerTimeBase4_2->isActive()); + // }}}------------------------------------------------------------------------------- +} + +TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActivationTypes) { + int uid = 1111; + + // Create config with 2 metrics: + // Metric 1: Activate on boot with 2 activations + // Metric 2: Always active + StatsdConfig config1; + config1.set_id(12341); + config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); + auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher(); + *config1.add_atom_matcher() = wakelockAcquireMatcher; + *config1.add_atom_matcher() = screenOnMatcher; + + long metricId1 = 1234561; + long metricId2 = 1234562; + + auto countMetric1 = config1.add_count_metric(); + countMetric1->set_id(metricId1); + countMetric1->set_what(wakelockAcquireMatcher.id()); + countMetric1->set_bucket(FIVE_MINUTES); + + auto countMetric2 = config1.add_count_metric(); + countMetric2->set_id(metricId2); + countMetric2->set_what(wakelockAcquireMatcher.id()); + countMetric2->set_bucket(FIVE_MINUTES); + + auto metric1Activation = config1.add_metric_activation(); + metric1Activation->set_metric_id(metricId1); + metric1Activation->set_activation_type(ACTIVATE_ON_BOOT); + auto metric1ActivationTrigger1 = metric1Activation->add_event_activation(); + metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric1ActivationTrigger1->set_ttl_seconds(100); + auto metric1ActivationTrigger2 = metric1Activation->add_event_activation(); + metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id()); + metric1ActivationTrigger2->set_ttl_seconds(200); + metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY); + + ConfigKey cfgKey1(uid, 12341); + long timeBase1 = 1; + sp<StatsLogProcessor> processor1 = + CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1); + + // Metric 1 is not active. + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor1->mMetricsManagers.size()); + auto it = processor1->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor1->mMetricsManagers.end()); + auto& metricsManager1 = it->second; + EXPECT_TRUE(metricsManager1->isActive()); + + EXPECT_EQ(metricsManager1->mAllMetricProducers.size(), 2); + // We assume that the index of a MetricProducer within the mAllMetricProducers + // array follows the order in which metrics are added to the config. + auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0]; + EXPECT_EQ(metricProducer1_1->getMetricId(), metricId1); + EXPECT_FALSE(metricProducer1_1->isActive()); // inactive due to associated MetricActivation + + auto& metricProducer1_2 = metricsManager1->mAllMetricProducers[1]; + EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2); + EXPECT_TRUE(metricProducer1_2->isActive()); + + EXPECT_EQ(metricProducer1_1->mEventActivationMap.size(), 2); + // The key in mEventActivationMap is the index of the associated atom matcher. We assume + // that matchers are indexed in the order that they are added to the config. + const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0); + EXPECT_EQ(100 * NS_PER_SEC, activation1_1_1->ttl_ns); + EXPECT_EQ(0, activation1_1_1->start_ns); + EXPECT_EQ(kNotActive, activation1_1_1->state); + EXPECT_EQ(ACTIVATE_ON_BOOT, activation1_1_1->activationType); + + const auto& activation1_1_2 = metricProducer1_1->mEventActivationMap.at(1); + EXPECT_EQ(200 * NS_PER_SEC, activation1_1_2->ttl_ns); + EXPECT_EQ(0, activation1_1_2->start_ns); + EXPECT_EQ(kNotActive, activation1_1_2->state); + EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1_1_2->activationType); + // }}}------------------------------------------------------------------------------ + + // Trigger Activation 1 for Metric 1 + std::vector<int> attributionUids = {111}; + std::vector<string> attributionTags = {"App1"}; + std::unique_ptr<LogEvent> event = + CreateAcquireWakelockEvent(timeBase1 + 100, attributionUids, attributionTags, "wl1"); + processor1->OnLogEvent(event.get()); + + // Metric 1 is not active; Activation 1 set to kActiveOnBoot + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_FALSE(metricProducer1_1->isActive()); + EXPECT_EQ(0, activation1_1_1->start_ns); + EXPECT_EQ(kActiveOnBoot, activation1_1_1->state); + EXPECT_EQ(0, activation1_1_2->start_ns); + EXPECT_EQ(kNotActive, activation1_1_2->state); + + EXPECT_TRUE(metricProducer1_2->isActive()); + // }}}----------------------------------------------------------------------------- + + // Simulate shutdown by saving state to disk + int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC; + processor1->SaveActiveConfigsToDisk(shutDownTime); + EXPECT_FALSE(metricProducer1_1->isActive()); + + // Simulate device restarted state by creating new instance of StatsLogProcessor with the + // same config. + long timeBase2 = 1000; + sp<StatsLogProcessor> processor2 = + CreateStatsLogProcessor(timeBase2, timeBase2, config1, cfgKey1); + + // Metric 1 is not active. + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor2->mMetricsManagers.size()); + it = processor2->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor2->mMetricsManagers.end()); + auto& metricsManager2 = it->second; + EXPECT_TRUE(metricsManager2->isActive()); + + EXPECT_EQ(metricsManager2->mAllMetricProducers.size(), 2); + // We assume that the index of a MetricProducer within the mAllMetricProducers + // array follows the order in which metrics are added to the config. + auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0]; + EXPECT_EQ(metricProducer2_1->getMetricId(), metricId1); + EXPECT_FALSE(metricProducer2_1->isActive()); + + auto& metricProducer2_2 = metricsManager2->mAllMetricProducers[1]; + EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2); + EXPECT_TRUE(metricProducer2_2->isActive()); + + EXPECT_EQ(metricProducer2_1->mEventActivationMap.size(), 2); + // The key in mEventActivationMap is the index of the associated atom matcher. We assume + // that matchers are indexed in the order that they are added to the config. + const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0); + EXPECT_EQ(100 * NS_PER_SEC, activation2_1_1->ttl_ns); + EXPECT_EQ(0, activation2_1_1->start_ns); + EXPECT_EQ(kNotActive, activation2_1_1->state); + EXPECT_EQ(ACTIVATE_ON_BOOT, activation2_1_1->activationType); + + const auto& activation2_1_2 = metricProducer2_1->mEventActivationMap.at(1); + EXPECT_EQ(200 * NS_PER_SEC, activation2_1_2->ttl_ns); + EXPECT_EQ(0, activation2_1_2->start_ns); + EXPECT_EQ(kNotActive, activation2_1_2->state); + EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2_1_2->activationType); + // }}}----------------------------------------------------------------------------------- + + // Load saved state from disk. + processor2->LoadActiveConfigsFromDisk(); + + // Metric 1 active; Activation 1 is active, Activation 2 is not active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducer2_1->isActive()); + int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC; + EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns); + EXPECT_EQ(kActive, activation2_1_1->state); + EXPECT_EQ(0, activation2_1_2->start_ns); + EXPECT_EQ(kNotActive, activation2_1_2->state); + + EXPECT_TRUE(metricProducer2_2->isActive()); + // }}}-------------------------------------------------------------------------------- + + // Trigger Activation 2 for Metric 1. + auto screenOnEvent = + CreateScreenStateChangedEvent(timeBase2 + 200, android::view::DISPLAY_STATE_ON); + processor2->OnLogEvent(screenOnEvent.get()); + + // Metric 1 active; Activation 1 is active, Activation 2 is active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducer2_1->isActive()); + EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns); + EXPECT_EQ(kActive, activation2_1_1->state); + EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation2_1_2->start_ns); + EXPECT_EQ(kActive, activation2_1_2->state); + + EXPECT_TRUE(metricProducer2_2->isActive()); + // }}}--------------------------------------------------------------------------- + + // Simulate shutdown by saving state to disk + shutDownTime = timeBase2 + 50 * NS_PER_SEC; + processor2->SaveActiveConfigsToDisk(shutDownTime); + EXPECT_TRUE(metricProducer2_1->isActive()); + EXPECT_TRUE(metricProducer2_2->isActive()); + ttl1 -= shutDownTime - timeBase2; + int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - + (shutDownTime - screenOnEvent->GetElapsedTimestampNs()); + + // Simulate device restarted state by creating new instance of StatsLogProcessor with the + // same config. + long timeBase3 = timeBase2 + 120 * NS_PER_SEC; + sp<StatsLogProcessor> processor3 = + CreateStatsLogProcessor(timeBase3, timeBase3, config1, cfgKey1); + + // Metric 1 is not active. + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor3->mMetricsManagers.size()); + it = processor3->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor3->mMetricsManagers.end()); + auto& metricsManager3 = it->second; + EXPECT_TRUE(metricsManager3->isActive()); + + EXPECT_EQ(metricsManager3->mAllMetricProducers.size(), 2); + // We assume that the index of a MetricProducer within the mAllMetricProducers + // array follows the order in which metrics are added to the config. + auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0]; + EXPECT_EQ(metricProducer3_1->getMetricId(), metricId1); + EXPECT_FALSE(metricProducer3_1->isActive()); + + auto& metricProducer3_2 = metricsManager3->mAllMetricProducers[1]; + EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2); + EXPECT_TRUE(metricProducer3_2->isActive()); + + EXPECT_EQ(metricProducer3_1->mEventActivationMap.size(), 2); + // The key in mEventActivationMap is the index of the associated atom matcher. We assume + // that matchers are indexed in the order that they are added to the config. + const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0); + EXPECT_EQ(100 * NS_PER_SEC, activation3_1_1->ttl_ns); + EXPECT_EQ(0, activation3_1_1->start_ns); + EXPECT_EQ(kNotActive, activation3_1_1->state); + EXPECT_EQ(ACTIVATE_ON_BOOT, activation3_1_1->activationType); + + const auto& activation3_1_2 = metricProducer3_1->mEventActivationMap.at(1); + EXPECT_EQ(200 * NS_PER_SEC, activation3_1_2->ttl_ns); + EXPECT_EQ(0, activation3_1_2->start_ns); + EXPECT_EQ(kNotActive, activation3_1_2->state); + EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation3_1_2->activationType); + // }}}---------------------------------------------------------------------------------- + + // Load saved state from disk. + processor3->LoadActiveConfigsFromDisk(); + + // Metric 1 active: Activation 1 is active, Activation 2 is active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducer3_1->isActive()); + EXPECT_EQ(timeBase3 + ttl1 - activation3_1_1->ttl_ns, activation3_1_1->start_ns); + EXPECT_EQ(kActive, activation3_1_1->state); + EXPECT_EQ(timeBase3 + ttl2 - activation3_1_2->ttl_ns, activation3_1_2->start_ns); + EXPECT_EQ(kActive, activation3_1_2->state); + + EXPECT_TRUE(metricProducer3_2->isActive()); + // }}}------------------------------------------------------------------------------- + + // Trigger Activation 2 for Metric 1 again. + screenOnEvent = CreateScreenStateChangedEvent(timeBase3 + 100 * NS_PER_SEC, + android::view::DISPLAY_STATE_ON); + processor3->OnLogEvent(screenOnEvent.get()); + + // Metric 1 active; Activation 1 is inactive (above screenOnEvent causes ttl1 to expire), + // Activation 2 is set to active + // Metric 2 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_TRUE(metricProducer3_1->isActive()); + EXPECT_EQ(kNotActive, activation3_1_1->state); + EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation3_1_2->start_ns); + EXPECT_EQ(kActive, activation3_1_2->state); + + EXPECT_TRUE(metricProducer3_2->isActive()); + // }}}--------------------------------------------------------------------------- +} + +TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) { + int uid = 9876; + long configId = 12341; + + // Create config with 3 metrics: + // Metric 1: Activate on 2 activations, 1 on boot, 1 immediate. + // Metric 2: Activate on 2 activations, 1 on boot, 1 immediate. + // Metric 3: Always active + StatsdConfig config1; + config1.set_id(configId); + config1.add_allowed_log_source("AID_ROOT"); // LogEvent defaults to UID of root. + auto wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher(); + auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher(); + auto jobStartMatcher = CreateStartScheduledJobAtomMatcher(); + auto jobFinishMatcher = CreateFinishScheduledJobAtomMatcher(); + *config1.add_atom_matcher() = wakelockAcquireMatcher; + *config1.add_atom_matcher() = screenOnMatcher; + *config1.add_atom_matcher() = jobStartMatcher; + *config1.add_atom_matcher() = jobFinishMatcher; + + long metricId1 = 1234561; + long metricId2 = 1234562; + long metricId3 = 1234563; + + auto countMetric1 = config1.add_count_metric(); + countMetric1->set_id(metricId1); + countMetric1->set_what(wakelockAcquireMatcher.id()); + countMetric1->set_bucket(FIVE_MINUTES); + + auto countMetric2 = config1.add_count_metric(); + countMetric2->set_id(metricId2); + countMetric2->set_what(wakelockAcquireMatcher.id()); + countMetric2->set_bucket(FIVE_MINUTES); + + auto countMetric3 = config1.add_count_metric(); + countMetric3->set_id(metricId3); + countMetric3->set_what(wakelockAcquireMatcher.id()); + countMetric3->set_bucket(FIVE_MINUTES); + + // Metric 1 activates on boot for wakelock acquire, immediately for screen on. + auto metric1Activation = config1.add_metric_activation(); + metric1Activation->set_metric_id(metricId1); + auto metric1ActivationTrigger1 = metric1Activation->add_event_activation(); + metric1ActivationTrigger1->set_atom_matcher_id(wakelockAcquireMatcher.id()); + metric1ActivationTrigger1->set_ttl_seconds(100); + metric1ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT); + auto metric1ActivationTrigger2 = metric1Activation->add_event_activation(); + metric1ActivationTrigger2->set_atom_matcher_id(screenOnMatcher.id()); + metric1ActivationTrigger2->set_ttl_seconds(200); + metric1ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY); + + // Metric 2 activates on boot for scheduled job start, immediately for scheduled job finish. + auto metric2Activation = config1.add_metric_activation(); + metric2Activation->set_metric_id(metricId2); + auto metric2ActivationTrigger1 = metric2Activation->add_event_activation(); + metric2ActivationTrigger1->set_atom_matcher_id(jobStartMatcher.id()); + metric2ActivationTrigger1->set_ttl_seconds(100); + metric2ActivationTrigger1->set_activation_type(ACTIVATE_ON_BOOT); + auto metric2ActivationTrigger2 = metric2Activation->add_event_activation(); + metric2ActivationTrigger2->set_atom_matcher_id(jobFinishMatcher.id()); + metric2ActivationTrigger2->set_ttl_seconds(200); + metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY); + + // Send the config. + shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr); + string serialized = config1.SerializeAsString(); + service->addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()}); + + // Make sure the config is stored on disk. Otherwise, we will not reset on system server death. + StatsdConfig tmpConfig; + ConfigKey cfgKey1(uid, configId); + EXPECT_TRUE(StorageManager::readConfigFromDisk(cfgKey1, &tmpConfig)); + + // Metric 1 is not active. + // Metric 2 is not active. + // Metric 3 is active. + // {{{--------------------------------------------------------------------------- + sp<StatsLogProcessor> processor = service->mProcessor; + EXPECT_EQ(1, processor->mMetricsManagers.size()); + auto it = processor->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor->mMetricsManagers.end()); + auto& metricsManager1 = it->second; + EXPECT_TRUE(metricsManager1->isActive()); + EXPECT_EQ(3, metricsManager1->mAllMetricProducers.size()); + + auto& metricProducer1 = metricsManager1->mAllMetricProducers[0]; + EXPECT_EQ(metricId1, metricProducer1->getMetricId()); + EXPECT_FALSE(metricProducer1->isActive()); + + auto& metricProducer2 = metricsManager1->mAllMetricProducers[1]; + EXPECT_EQ(metricId2, metricProducer2->getMetricId()); + EXPECT_FALSE(metricProducer2->isActive()); + + auto& metricProducer3 = metricsManager1->mAllMetricProducers[2]; + EXPECT_EQ(metricId3, metricProducer3->getMetricId()); + EXPECT_TRUE(metricProducer3->isActive()); + + // Check event activations. + EXPECT_EQ(metricsManager1->mAllAtomMatchers.size(), 4); + EXPECT_EQ(metricsManager1->mAllAtomMatchers[0]->getId(), + metric1ActivationTrigger1->atom_matcher_id()); + const auto& activation1 = metricProducer1->mEventActivationMap.at(0); + EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns); + EXPECT_EQ(0, activation1->start_ns); + EXPECT_EQ(kNotActive, activation1->state); + EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType); + + EXPECT_EQ(metricsManager1->mAllAtomMatchers[1]->getId(), + metric1ActivationTrigger2->atom_matcher_id()); + const auto& activation2 = metricProducer1->mEventActivationMap.at(1); + EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns); + EXPECT_EQ(0, activation2->start_ns); + EXPECT_EQ(kNotActive, activation2->state); + EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType); + + EXPECT_EQ(metricsManager1->mAllAtomMatchers[2]->getId(), + metric2ActivationTrigger1->atom_matcher_id()); + const auto& activation3 = metricProducer2->mEventActivationMap.at(2); + EXPECT_EQ(100 * NS_PER_SEC, activation3->ttl_ns); + EXPECT_EQ(0, activation3->start_ns); + EXPECT_EQ(kNotActive, activation3->state); + EXPECT_EQ(ACTIVATE_ON_BOOT, activation3->activationType); + + EXPECT_EQ(metricsManager1->mAllAtomMatchers[3]->getId(), + metric2ActivationTrigger2->atom_matcher_id()); + const auto& activation4 = metricProducer2->mEventActivationMap.at(3); + EXPECT_EQ(200 * NS_PER_SEC, activation4->ttl_ns); + EXPECT_EQ(0, activation4->start_ns); + EXPECT_EQ(kNotActive, activation4->state); + EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation4->activationType); + // }}}------------------------------------------------------------------------------ + + // Trigger Activation 1 for Metric 1. Should activate on boot. + // Trigger Activation 4 for Metric 2. Should activate immediately. + long configAddedTimeNs = metricsManager1->mLastReportTimeNs; + std::vector<int> attributionUids = {111}; + std::vector<string> attributionTags = {"App1"}; + std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent( + 1 + configAddedTimeNs, attributionUids, attributionTags, "wl1"); + processor->OnLogEvent(event1.get()); + + std::unique_ptr<LogEvent> event2 = CreateFinishScheduledJobEvent( + 2 + configAddedTimeNs, attributionUids, attributionTags, "finish1"); + processor->OnLogEvent(event2.get()); + + // Metric 1 is not active; Activation 1 set to kActiveOnBoot + // Metric 2 is active. Activation 4 set to kActive + // Metric 3 is active. + // {{{--------------------------------------------------------------------------- + EXPECT_FALSE(metricProducer1->isActive()); + EXPECT_EQ(0, activation1->start_ns); + EXPECT_EQ(kActiveOnBoot, activation1->state); + EXPECT_EQ(0, activation2->start_ns); + EXPECT_EQ(kNotActive, activation2->state); + + EXPECT_TRUE(metricProducer2->isActive()); + EXPECT_EQ(0, activation3->start_ns); + EXPECT_EQ(kNotActive, activation3->state); + EXPECT_EQ(2 + configAddedTimeNs, activation4->start_ns); + EXPECT_EQ(kActive, activation4->state); + + EXPECT_TRUE(metricProducer3->isActive()); + // }}}----------------------------------------------------------------------------- + + // Can't fake time with StatsService. + // Lets get a time close to the system server death time and make sure it's sane. + int64_t approximateSystemServerDeath = getElapsedRealtimeNs(); + EXPECT_TRUE(approximateSystemServerDeath > 2 + configAddedTimeNs); + EXPECT_TRUE(approximateSystemServerDeath < NS_PER_SEC + configAddedTimeNs); + + // System server dies. + service->statsCompanionServiceDiedImpl(); + + // We should have a new metrics manager. Lets get it and ensure activation status is restored. + // {{{--------------------------------------------------------------------------- + EXPECT_EQ(1, processor->mMetricsManagers.size()); + it = processor->mMetricsManagers.find(cfgKey1); + EXPECT_TRUE(it != processor->mMetricsManagers.end()); + auto& metricsManager2 = it->second; + EXPECT_TRUE(metricsManager2->isActive()); + EXPECT_EQ(3, metricsManager2->mAllMetricProducers.size()); + + auto& metricProducer1001 = metricsManager2->mAllMetricProducers[0]; + EXPECT_EQ(metricId1, metricProducer1001->getMetricId()); + EXPECT_FALSE(metricProducer1001->isActive()); + + auto& metricProducer1002 = metricsManager2->mAllMetricProducers[1]; + EXPECT_EQ(metricId2, metricProducer1002->getMetricId()); + EXPECT_TRUE(metricProducer1002->isActive()); + + auto& metricProducer1003 = metricsManager2->mAllMetricProducers[2]; + EXPECT_EQ(metricId3, metricProducer1003->getMetricId()); + EXPECT_TRUE(metricProducer1003->isActive()); + + // Check event activations. + // Activation 1 is kActiveOnBoot. + // Activation 2 and 3 are not active. + // Activation 4 is active. + EXPECT_EQ(metricsManager2->mAllAtomMatchers.size(), 4); + EXPECT_EQ(metricsManager2->mAllAtomMatchers[0]->getId(), + metric1ActivationTrigger1->atom_matcher_id()); + const auto& activation1001 = metricProducer1001->mEventActivationMap.at(0); + EXPECT_EQ(100 * NS_PER_SEC, activation1001->ttl_ns); + EXPECT_EQ(0, activation1001->start_ns); + EXPECT_EQ(kActiveOnBoot, activation1001->state); + EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001->activationType); + + EXPECT_EQ(metricsManager2->mAllAtomMatchers[1]->getId(), + metric1ActivationTrigger2->atom_matcher_id()); + const auto& activation1002 = metricProducer1001->mEventActivationMap.at(1); + EXPECT_EQ(200 * NS_PER_SEC, activation1002->ttl_ns); + EXPECT_EQ(0, activation1002->start_ns); + EXPECT_EQ(kNotActive, activation1002->state); + EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1002->activationType); + + EXPECT_EQ(metricsManager2->mAllAtomMatchers[2]->getId(), + metric2ActivationTrigger1->atom_matcher_id()); + const auto& activation1003 = metricProducer1002->mEventActivationMap.at(2); + EXPECT_EQ(100 * NS_PER_SEC, activation1003->ttl_ns); + EXPECT_EQ(0, activation1003->start_ns); + EXPECT_EQ(kNotActive, activation1003->state); + EXPECT_EQ(ACTIVATE_ON_BOOT, activation1003->activationType); + + EXPECT_EQ(metricsManager2->mAllAtomMatchers[3]->getId(), + metric2ActivationTrigger2->atom_matcher_id()); + const auto& activation1004 = metricProducer1002->mEventActivationMap.at(3); + EXPECT_EQ(200 * NS_PER_SEC, activation1004->ttl_ns); + EXPECT_EQ(2 + configAddedTimeNs, activation1004->start_ns); + EXPECT_EQ(kActive, activation1004->state); + EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1004->activationType); + // }}}------------------------------------------------------------------------------ + + // Clear the data stored on disk as a result of the system server death. + vector<uint8_t> buffer; + processor->onDumpReport(cfgKey1, configAddedTimeNs + NS_PER_SEC, false, true, ADB_DUMP, FAST, + &buffer); +} #else GTEST_LOG_(INFO) << "This test does nothing.\n"; diff --git a/cmds/statsd/tests/UidMap_test.cpp b/cmds/statsd/tests/UidMap_test.cpp index a49c18fb9857..29005a2070fe 100644 --- a/cmds/statsd/tests/UidMap_test.cpp +++ b/cmds/statsd/tests/UidMap_test.cpp @@ -39,35 +39,28 @@ using android::util::ProtoReader; const string kApp1 = "app1.sharing.1"; const string kApp2 = "app2.sharing.1"; -// TODO(b/149590301): Update this test to use new socket schema. -//TEST(UidMapTest, TestIsolatedUID) { -// sp<UidMap> m = new UidMap(); -// sp<StatsPullerManager> pullerManager = new StatsPullerManager(); -// sp<AlarmMonitor> anomalyAlarmMonitor; -// sp<AlarmMonitor> subscriberAlarmMonitor; -// // Construct the processor with a dummy sendBroadcast function that does nothing. -// StatsLogProcessor p(m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, -// [](const ConfigKey& key) { return true; }, -// [](const int&, const vector<int64_t>&) {return true;}); -// LogEvent addEvent(util::ISOLATED_UID_CHANGED, 1); -// addEvent.write(100); // parent UID -// addEvent.write(101); // isolated UID -// addEvent.write(1); // Indicates creation. -// addEvent.init(); -// -// EXPECT_EQ(101, m->getHostUidOrSelf(101)); -// -// p.OnLogEvent(&addEvent); -// EXPECT_EQ(100, m->getHostUidOrSelf(101)); -// -// LogEvent removeEvent(util::ISOLATED_UID_CHANGED, 1); -// removeEvent.write(100); // parent UID -// removeEvent.write(101); // isolated UID -// removeEvent.write(0); // Indicates removal. -// removeEvent.init(); -// p.OnLogEvent(&removeEvent); -// EXPECT_EQ(101, m->getHostUidOrSelf(101)); -//} +TEST(UidMapTest, TestIsolatedUID) { + sp<UidMap> m = new UidMap(); + sp<StatsPullerManager> pullerManager = new StatsPullerManager(); + sp<AlarmMonitor> anomalyAlarmMonitor; + sp<AlarmMonitor> subscriberAlarmMonitor; + // Construct the processor with a dummy sendBroadcast function that does nothing. + StatsLogProcessor p( + m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, 0, + [](const ConfigKey& key) { return true; }, + [](const int&, const vector<int64_t>&) { return true; }); + + std::unique_ptr<LogEvent> addEvent = CreateIsolatedUidChangedEvent( + 1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 1 /*is_create*/); + EXPECT_EQ(101, m->getHostUidOrSelf(101)); + p.OnLogEvent(addEvent.get()); + EXPECT_EQ(100, m->getHostUidOrSelf(101)); + + std::unique_ptr<LogEvent> removeEvent = CreateIsolatedUidChangedEvent( + 1 /*timestamp*/, 100 /*hostUid*/, 101 /*isolatedUid*/, 0 /*is_create*/); + p.OnLogEvent(removeEvent.get()); + EXPECT_EQ(101, m->getHostUidOrSelf(101)); +} TEST(UidMapTest, TestMatching) { UidMap m; diff --git a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp index 4c55683d909c..5eef92e12ba9 100644 --- a/cmds/statsd/tests/shell/ShellSubscriber_test.cpp +++ b/cmds/statsd/tests/shell/ShellSubscriber_test.cpp @@ -12,18 +12,20 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include <gtest/gtest.h> +#include "src/shell/ShellSubscriber.h" +#include <gtest/gtest.h> +#include <stdio.h> #include <unistd.h> + +#include <vector> + #include "frameworks/base/cmds/statsd/src/atoms.pb.h" #include "frameworks/base/cmds/statsd/src/shell/shell_config.pb.h" #include "frameworks/base/cmds/statsd/src/shell/shell_data.pb.h" -#include "src/shell/ShellSubscriber.h" #include "stats_event.h" #include "tests/metrics/metrics_test_helper.h" - -#include <stdio.h> -#include <vector> +#include "tests/statsd_test_util.h" using namespace android::os::statsd; using android::sp; @@ -118,18 +120,9 @@ TEST(ShellSubscriberTest, testPushedSubscription) { vector<std::shared_ptr<LogEvent>> pushedList; // Create the LogEvent from an AStatsEvent - AStatsEvent* statsEvent = AStatsEvent_obtain(); - AStatsEvent_setAtomId(statsEvent, 29 /*screen_state_atom_id*/); - AStatsEvent_overwriteTimestamp(statsEvent, 1000); - AStatsEvent_writeInt32(statsEvent, ::android::view::DisplayStateEnum::DISPLAY_STATE_ON); - AStatsEvent_build(statsEvent); - size_t size; - uint8_t* buffer = AStatsEvent_getBuffer(statsEvent, &size); - std::shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0); - logEvent->parseBuffer(buffer, size); - AStatsEvent_release(statsEvent); - - pushedList.push_back(logEvent); + std::unique_ptr<LogEvent> logEvent = CreateScreenStateChangedEvent( + 1000 /*timestamp*/, ::android::view::DisplayStateEnum::DISPLAY_STATE_ON); + pushedList.push_back(std::move(logEvent)); // create a simple config to get screen events ShellSubscription config; diff --git a/cmds/statsd/tests/state/StateTracker_test.cpp b/cmds/statsd/tests/state/StateTracker_test.cpp index b1633c63028d..a0e00954531f 100644 --- a/cmds/statsd/tests/state/StateTracker_test.cpp +++ b/cmds/statsd/tests/state/StateTracker_test.cpp @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include <gtest/gtest.h> -#include "state/StateManager.h" #include "state/StateTracker.h" -#include "state/StateListener.h" +#include <gtest/gtest.h> + +#include "state/StateListener.h" +#include "state/StateManager.h" +#include "stats_event.h" #include "tests/statsd_test_util.h" #ifdef __ANDROID__ @@ -26,6 +28,8 @@ namespace android { namespace os { namespace statsd { +const int32_t timestampNs = 1000; + /** * Mock StateListener class for testing. * Stores primary key and state pairs. @@ -56,95 +60,49 @@ int getStateInt(StateManager& mgr, int atomId, const HashableDimensionKey& query return output.mValue.int_value; } -// TODO(b/149590301): Update these helpers to use new socket schema. -//// START: build event functions. -//// State with no primary fields - ScreenStateChanged -//std::shared_ptr<LogEvent> buildScreenEvent(int state) { -// std::shared_ptr<LogEvent> event = -// std::make_shared<LogEvent>(util::SCREEN_STATE_CHANGED, 1000 /*timestamp*/); -// event->write((int32_t)state); -// event->init(); -// return event; -//} -// -//// State with one primary field - UidProcessStateChanged -//std::shared_ptr<LogEvent> buildUidProcessEvent(int uid, int state) { -// std::shared_ptr<LogEvent> event = -// std::make_shared<LogEvent>(util::UID_PROCESS_STATE_CHANGED, 1000 /*timestamp*/); -// event->write((int32_t)uid); -// event->write((int32_t)state); -// event->init(); -// return event; -//} -// -//// State with first uid in attribution chain as primary field - WakelockStateChanged -//std::shared_ptr<LogEvent> buildPartialWakelockEvent(int uid, const std::string& tag, bool acquire) { -// std::vector<AttributionNodeInternal> chain; -// chain.push_back(AttributionNodeInternal()); -// AttributionNodeInternal& attr = chain.back(); -// attr.set_uid(uid); -// -// std::shared_ptr<LogEvent> event = -// std::make_shared<LogEvent>(util::WAKELOCK_STATE_CHANGED, 1000 /* timestamp */); -// event->write(chain); -// event->write((int32_t)1); // PARTIAL_WAKE_LOCK -// event->write(tag); -// event->write(acquire ? 1 : 0); -// event->init(); -// return event; -//} -// -//// State with multiple primary fields - OverlayStateChanged -//std::shared_ptr<LogEvent> buildOverlayEvent(int uid, const std::string& packageName, int state) { -// std::shared_ptr<LogEvent> event = -// std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/); -// event->write((int32_t)uid); -// event->write(packageName); -// event->write(true); // using_alert_window -// event->write((int32_t)state); -// event->init(); -// return event; -//} -// -//// Incorrect event - missing fields -//std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, int state) { -// std::shared_ptr<LogEvent> event = -// std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/); -// event->write((int32_t)uid); -// event->write(packageName); -// event->write((int32_t)state); -// event->init(); -// return event; -//} -// -//// Incorrect event - exclusive state has wrong type -//std::shared_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) { -// std::shared_ptr<LogEvent> event = -// std::make_shared<LogEvent>(util::OVERLAY_STATE_CHANGED, 1000 /*timestamp*/); -// event->write((int32_t)uid); -// event->write(packageName); -// event->write(true); -// event->write("string"); // exclusive state: string instead of int -// event->init(); -// return event; -//} -// -//std::shared_ptr<LogEvent> buildBleScanEvent(int uid, bool acquire, bool reset) { -// std::vector<AttributionNodeInternal> chain; -// chain.push_back(AttributionNodeInternal()); -// AttributionNodeInternal& attr = chain.back(); -// attr.set_uid(uid); -// -// std::shared_ptr<LogEvent> event = -// std::make_shared<LogEvent>(util::BLE_SCAN_STATE_CHANGED, 1000); -// event->write(chain); -// event->write(reset ? 2 : acquire ? 1 : 0); // PARTIAL_WAKE_LOCK -// event->write(0); // filtered -// event->write(0); // first match -// event->write(0); // opportunistic -// event->init(); -// return event; -//} +// START: build event functions. +// Incorrect event - missing fields +std::shared_ptr<LogEvent> buildIncorrectOverlayEvent(int uid, const std::string& packageName, + int state) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED); + AStatsEvent_overwriteTimestamp(statsEvent, 1000); + + AStatsEvent_writeInt32(statsEvent, uid); + AStatsEvent_writeString(statsEvent, packageName.c_str()); + // Missing field 3 - using_alert_window. + AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + + std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); + logEvent->parseBuffer(buf, size); + AStatsEvent_release(statsEvent); + return logEvent; +} + +// Incorrect event - exclusive state has wrong type +std::unique_ptr<LogEvent> buildOverlayEventBadStateType(int uid, const std::string& packageName) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED); + AStatsEvent_overwriteTimestamp(statsEvent, 1000); + + AStatsEvent_writeInt32(statsEvent, uid); + AStatsEvent_writeString(statsEvent, packageName.c_str()); + AStatsEvent_writeInt32(statsEvent, true); // using_alert_window + AStatsEvent_writeString(statsEvent, "string"); // exclusive state: string instead of int + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + + std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); + logEvent->parseBuffer(buf, size); + AStatsEvent_release(statsEvent); + return logEvent; +} // END: build event functions. // START: get primary key functions @@ -293,302 +251,323 @@ TEST(StateTrackerTest, TestUnregisterListener) { EXPECT_EQ(0, mgr.getStateTrackersCount()); EXPECT_EQ(-1, mgr.getListenersCount(util::SCREEN_STATE_CHANGED)); } -// TODO(b/149590301): Update these tests to use new socket schema. -///** -// * Test a binary state atom with nested counting. -// * -// * To go from an "ON" state to an "OFF" state with nested counting, we must see -// * an equal number of "OFF" events as "ON" events. -// * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state. -// * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state. -// */ -//TEST(StateTrackerTest, TestStateChangeNested) { -// sp<TestStateListener> listener = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener); -// -// std::shared_ptr<LogEvent> event1 = -// buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/); -// mgr.onLogEvent(*event1); -// EXPECT_EQ(1, listener->updates.size()); -// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); -// EXPECT_EQ(1, listener->updates[0].mState); -// listener->updates.clear(); -// -// std::shared_ptr<LogEvent> event2 = -// buildPartialWakelockEvent(1000 /* uid */, "tag", true /*acquire*/); -// mgr.onLogEvent(*event2); -// EXPECT_EQ(0, listener->updates.size()); -// -// std::shared_ptr<LogEvent> event3 = -// buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/); -// mgr.onLogEvent(*event3); -// EXPECT_EQ(0, listener->updates.size()); -// -// std::shared_ptr<LogEvent> event4 = -// buildPartialWakelockEvent(1000 /* uid */, "tag", false /*release*/); -// mgr.onLogEvent(*event4); -// EXPECT_EQ(1, listener->updates.size()); -// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); -// EXPECT_EQ(0, listener->updates[0].mState); -//} -// -///** -// * Test a state atom with a reset state. -// * -// * If the reset state value is seen, every state in the map is set to the default -// * state and every listener is notified. -// */ -//TEST(StateTrackerTest, TestStateChangeReset) { -// sp<TestStateListener> listener = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener); -// -// std::shared_ptr<LogEvent> event1 = -// buildBleScanEvent(1000 /* uid */, true /*acquire*/, false /*reset*/); -// mgr.onLogEvent(*event1); -// EXPECT_EQ(1, listener->updates.size()); -// EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); -// EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); -// listener->updates.clear(); -// -// std::shared_ptr<LogEvent> event2 = -// buildBleScanEvent(2000 /* uid */, true /*acquire*/, false /*reset*/); -// mgr.onLogEvent(*event2); -// EXPECT_EQ(1, listener->updates.size()); -// EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value); -// EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); -// listener->updates.clear(); -// -// std::shared_ptr<LogEvent> event3 = -// buildBleScanEvent(2000 /* uid */, false /*acquire*/, true /*reset*/); -// mgr.onLogEvent(*event3); -// EXPECT_EQ(2, listener->updates.size()); -// EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState); -// EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState); -//} -// -///** -// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly -// * updates listener for states without primary keys. -// */ -//TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) { -// sp<TestStateListener> listener1 = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1); -// -// // log event -// std::shared_ptr<LogEvent> event = -// buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON); -// mgr.onLogEvent(*event); -// -// // check listener was updated -// EXPECT_EQ(1, listener1->updates.size()); -// EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey); -// EXPECT_EQ(2, listener1->updates[0].mState); -// -// // check StateTracker was updated by querying for state -// HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY; -// EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, -// getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); -//} -// -///** -// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly -// * updates listener for states with one primary key. -// */ -//TEST(StateTrackerTest, TestStateChangeOnePrimaryField) { -// sp<TestStateListener> listener1 = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1); -// -// // log event -// std::shared_ptr<LogEvent> event = -// buildUidProcessEvent(1000 /* uid */, android::app::ProcessStateEnum::PROCESS_STATE_TOP); -// mgr.onLogEvent(*event); -// -// // check listener was updated -// EXPECT_EQ(1, listener1->updates.size()); -// EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value); -// EXPECT_EQ(1002, listener1->updates[0].mState); -// -// // check StateTracker was updated by querying for state -// HashableDimensionKey queryKey; -// getUidProcessKey(1000 /* uid */, &queryKey); -// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP, -// getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey)); -//} -// -//TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) { -// sp<TestStateListener> listener1 = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1); -// -// // Log event. -// std::shared_ptr<LogEvent> event = -// buildPartialWakelockEvent(1001 /* uid */, "tag1", true /* acquire */); -// mgr.onLogEvent(*event); -// -// EXPECT_EQ(1, mgr.getStateTrackersCount()); -// EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED)); -// -// // Check listener was updated. -// EXPECT_EQ(1, listener1->updates.size()); -// EXPECT_EQ(3, listener1->updates[0].mKey.getValues().size()); -// EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value); -// EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value); -// EXPECT_EQ("tag1", listener1->updates[0].mKey.getValues()[2].mValue.str_value); -// EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState); -// -// // Check StateTracker was updated by querying for state. -// HashableDimensionKey queryKey; -// getPartialWakelockKey(1001 /* uid */, "tag1", &queryKey); -// EXPECT_EQ(WakelockStateChanged::ACQUIRE, -// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey)); -// -// // No state stored for this query key. -// HashableDimensionKey queryKey2; -// getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2); -// EXPECT_EQ(WakelockStateChanged::RELEASE, -// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2)); -// -// // Partial query fails. -// HashableDimensionKey queryKey3; -// getPartialWakelockKey(1001 /* uid */, &queryKey3); -// EXPECT_EQ(WakelockStateChanged::RELEASE, -// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3)); -//} -// -///** -// * Test StateManager's onLogEvent and StateListener's onStateChanged correctly -// * updates listener for states with multiple primary keys. -// */ -//TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) { -// sp<TestStateListener> listener1 = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1); -// -// // log event -// std::shared_ptr<LogEvent> event = -// buildOverlayEvent(1000 /* uid */, "package1", 1); // state: ENTERED -// mgr.onLogEvent(*event); -// -// // check listener was updated -// EXPECT_EQ(1, listener1->updates.size()); -// EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value); -// EXPECT_EQ(1, listener1->updates[0].mState); -// -// // check StateTracker was updated by querying for state -// HashableDimensionKey queryKey; -// getOverlayKey(1000 /* uid */, "package1", &queryKey); -// EXPECT_EQ(OverlayStateChanged::ENTERED, -// getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey)); -//} -// -///** -// * Test StateManager's onLogEvent and StateListener's onStateChanged -// * when there is an error extracting state from log event. Listener is not -// * updated of state change. -// */ -//TEST(StateTrackerTest, TestStateChangeEventError) { -// sp<TestStateListener> listener1 = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1); -// -// // log event -// std::shared_ptr<LogEvent> event1 = -// buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */); -// std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2"); -// -// // check listener was updated -// mgr.onLogEvent(*event1); -// EXPECT_EQ(0, listener1->updates.size()); -// mgr.onLogEvent(*event2); -// EXPECT_EQ(0, listener1->updates.size()); -//} -// -//TEST(StateTrackerTest, TestStateQuery) { -// sp<TestStateListener> listener1 = new TestStateListener(); -// sp<TestStateListener> listener2 = new TestStateListener(); -// sp<TestStateListener> listener3 = new TestStateListener(); -// sp<TestStateListener> listener4 = new TestStateListener(); -// StateManager mgr; -// mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1); -// mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2); -// mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3); -// mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4); -// -// std::shared_ptr<LogEvent> event1 = buildUidProcessEvent( -// 1000, -// android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002 -// std::shared_ptr<LogEvent> event2 = buildUidProcessEvent( -// 1001, -// android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value: -// // 1003 -// std::shared_ptr<LogEvent> event3 = buildUidProcessEvent( -// 1002, -// android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000 -// std::shared_ptr<LogEvent> event4 = buildUidProcessEvent( -// 1001, -// android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002 -// std::shared_ptr<LogEvent> event5 = -// buildScreenEvent(android::view::DisplayStateEnum::DISPLAY_STATE_ON); -// std::shared_ptr<LogEvent> event6 = -// buildOverlayEvent(1000, "package1", OverlayStateChanged::ENTERED); -// std::shared_ptr<LogEvent> event7 = -// buildOverlayEvent(1000, "package2", OverlayStateChanged::EXITED); -// std::shared_ptr<LogEvent> event8 = buildPartialWakelockEvent(1005, "tag1", true); -// std::shared_ptr<LogEvent> event9 = buildPartialWakelockEvent(1005, "tag2", false); -// -// mgr.onLogEvent(*event1); -// mgr.onLogEvent(*event2); -// mgr.onLogEvent(*event3); -// mgr.onLogEvent(*event5); -// mgr.onLogEvent(*event5); -// mgr.onLogEvent(*event6); -// mgr.onLogEvent(*event7); -// mgr.onLogEvent(*event8); -// mgr.onLogEvent(*event9); -// -// // Query for UidProcessState of uid 1001 -// HashableDimensionKey queryKey1; -// getUidProcessKey(1001, &queryKey1); -// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE, -// getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1)); -// -// // Query for UidProcessState of uid 1004 - not in state map -// HashableDimensionKey queryKey2; -// getUidProcessKey(1004, &queryKey2); -// EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, -// queryKey2)); // default state -// -// // Query for UidProcessState of uid 1001 - after change in state -// mgr.onLogEvent(*event4); -// EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP, -// getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1)); -// -// // Query for ScreenState -// EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, -// getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY)); -// -// // Query for OverlayState of uid 1000, package name "package2" -// HashableDimensionKey queryKey3; -// getOverlayKey(1000, "package2", &queryKey3); -// EXPECT_EQ(OverlayStateChanged::EXITED, -// getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3)); -// -// // Query for WakelockState of uid 1005, tag 2 -// HashableDimensionKey queryKey4; -// getPartialWakelockKey(1005, "tag2", &queryKey4); -// EXPECT_EQ(WakelockStateChanged::RELEASE, -// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4)); -// -// // Query for WakelockState of uid 1005, tag 1 -// HashableDimensionKey queryKey5; -// getPartialWakelockKey(1005, "tag1", &queryKey5); -// EXPECT_EQ(WakelockStateChanged::ACQUIRE, -// getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5)); -//} + +/** + * Test a binary state atom with nested counting. + * + * To go from an "ON" state to an "OFF" state with nested counting, we must see + * an equal number of "OFF" events as "ON" events. + * For example, ACQUIRE, ACQUIRE, RELEASE will still be in the ACQUIRE state. + * ACQUIRE, ACQUIRE, RELEASE, RELEASE will be in the RELEASE state. + */ +TEST(StateTrackerTest, TestStateChangeNested) { + sp<TestStateListener> listener = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener); + + std::vector<int> attributionUids1 = {1000}; + std::vector<string> attributionTags1 = {"tag"}; + + std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(timestampNs, attributionUids1, + attributionTags1, "wakelockName"); + mgr.onLogEvent(*event1); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(1, listener->updates[0].mState); + listener->updates.clear(); + + std::unique_ptr<LogEvent> event2 = CreateAcquireWakelockEvent( + timestampNs + 1000, attributionUids1, attributionTags1, "wakelockName"); + mgr.onLogEvent(*event2); + EXPECT_EQ(0, listener->updates.size()); + + std::unique_ptr<LogEvent> event3 = CreateReleaseWakelockEvent( + timestampNs + 2000, attributionUids1, attributionTags1, "wakelockName"); + mgr.onLogEvent(*event3); + EXPECT_EQ(0, listener->updates.size()); + + std::unique_ptr<LogEvent> event4 = CreateReleaseWakelockEvent( + timestampNs + 3000, attributionUids1, attributionTags1, "wakelockName"); + mgr.onLogEvent(*event4); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(0, listener->updates[0].mState); +} + +/** + * Test a state atom with a reset state. + * + * If the reset state value is seen, every state in the map is set to the default + * state and every listener is notified. + */ +TEST(StateTrackerTest, TestStateChangeReset) { + sp<TestStateListener> listener = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::BLE_SCAN_STATE_CHANGED, listener); + + std::vector<int> attributionUids1 = {1000}; + std::vector<string> attributionTags1 = {"tag1"}; + std::vector<int> attributionUids2 = {2000}; + + std::unique_ptr<LogEvent> event1 = + CreateBleScanStateChangedEvent(timestampNs, attributionUids1, attributionTags1, + BleScanStateChanged::ON, false, false, false); + mgr.onLogEvent(*event1); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(1000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); + listener->updates.clear(); + + std::unique_ptr<LogEvent> event2 = + CreateBleScanStateChangedEvent(timestampNs + 1000, attributionUids2, attributionTags1, + BleScanStateChanged::ON, false, false, false); + mgr.onLogEvent(*event2); + EXPECT_EQ(1, listener->updates.size()); + EXPECT_EQ(2000, listener->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(BleScanStateChanged::ON, listener->updates[0].mState); + listener->updates.clear(); + + std::unique_ptr<LogEvent> event3 = + CreateBleScanStateChangedEvent(timestampNs + 2000, attributionUids2, attributionTags1, + BleScanStateChanged::RESET, false, false, false); + mgr.onLogEvent(*event3); + EXPECT_EQ(2, listener->updates.size()); + EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[0].mState); + EXPECT_EQ(BleScanStateChanged::OFF, listener->updates[1].mState); +} + +/** + * Test StateManager's onLogEvent and StateListener's onStateChanged correctly + * updates listener for states without primary keys. + */ +TEST(StateTrackerTest, TestStateChangeNoPrimaryFields) { + sp<TestStateListener> listener1 = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1); + + // log event + std::unique_ptr<LogEvent> event = CreateScreenStateChangedEvent( + timestampNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON); + mgr.onLogEvent(*event); + + // check listener was updated + EXPECT_EQ(1, listener1->updates.size()); + EXPECT_EQ(DEFAULT_DIMENSION_KEY, listener1->updates[0].mKey); + EXPECT_EQ(2, listener1->updates[0].mState); + + // check StateTracker was updated by querying for state + HashableDimensionKey queryKey = DEFAULT_DIMENSION_KEY; + EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, + getStateInt(mgr, util::SCREEN_STATE_CHANGED, queryKey)); +} + +/** + * Test StateManager's onLogEvent and StateListener's onStateChanged correctly + * updates listener for states with one primary key. + */ +TEST(StateTrackerTest, TestStateChangeOnePrimaryField) { + sp<TestStateListener> listener1 = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener1); + + // log event + std::unique_ptr<LogEvent> event = CreateUidProcessStateChangedEvent( + timestampNs, 1000 /*uid*/, android::app::ProcessStateEnum::PROCESS_STATE_TOP); + mgr.onLogEvent(*event); + + // check listener was updated + EXPECT_EQ(1, listener1->updates.size()); + EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(1002, listener1->updates[0].mState); + + // check StateTracker was updated by querying for state + HashableDimensionKey queryKey; + getUidProcessKey(1000 /* uid */, &queryKey); + EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP, + getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey)); +} + +TEST(StateTrackerTest, TestStateChangePrimaryFieldAttrChain) { + sp<TestStateListener> listener1 = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener1); + + // Log event. + std::vector<int> attributionUids = {1001}; + std::vector<string> attributionTags = {"tag1"}; + + std::unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timestampNs, attributionUids, + attributionTags, "wakelockName"); + mgr.onLogEvent(*event); + EXPECT_EQ(1, mgr.getStateTrackersCount()); + EXPECT_EQ(1, mgr.getListenersCount(util::WAKELOCK_STATE_CHANGED)); + + // Check listener was updated. + EXPECT_EQ(1, listener1->updates.size()); + EXPECT_EQ(3, listener1->updates[0].mKey.getValues().size()); + EXPECT_EQ(1001, listener1->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(1, listener1->updates[0].mKey.getValues()[1].mValue.int_value); + EXPECT_EQ("wakelockName", listener1->updates[0].mKey.getValues()[2].mValue.str_value); + EXPECT_EQ(WakelockStateChanged::ACQUIRE, listener1->updates[0].mState); + + // Check StateTracker was updated by querying for state. + HashableDimensionKey queryKey; + getPartialWakelockKey(1001 /* uid */, "wakelockName", &queryKey); + EXPECT_EQ(WakelockStateChanged::ACQUIRE, + getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey)); + + // No state stored for this query key. + HashableDimensionKey queryKey2; + getPartialWakelockKey(1002 /* uid */, "tag1", &queryKey2); + EXPECT_EQ(WakelockStateChanged::RELEASE, + getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey2)); + + // Partial query fails. + HashableDimensionKey queryKey3; + getPartialWakelockKey(1001 /* uid */, &queryKey3); + EXPECT_EQ(WakelockStateChanged::RELEASE, + getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey3)); +} + +/** + * Test StateManager's onLogEvent and StateListener's onStateChanged correctly + * updates listener for states with multiple primary keys. + */ +TEST(StateTrackerTest, TestStateChangeMultiplePrimaryFields) { + sp<TestStateListener> listener1 = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1); + + // log event + std::unique_ptr<LogEvent> event = CreateOverlayStateChangedEvent( + timestampNs, 1000 /* uid */, "package1", true /*using_alert_window*/, + OverlayStateChanged::ENTERED); + mgr.onLogEvent(*event); + + // check listener was updated + EXPECT_EQ(1, listener1->updates.size()); + EXPECT_EQ(1000, listener1->updates[0].mKey.getValues()[0].mValue.int_value); + EXPECT_EQ(1, listener1->updates[0].mState); + + // check StateTracker was updated by querying for state + HashableDimensionKey queryKey; + getOverlayKey(1000 /* uid */, "package1", &queryKey); + EXPECT_EQ(OverlayStateChanged::ENTERED, + getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey)); +} + +/** + * Test StateManager's onLogEvent and StateListener's onStateChanged + * when there is an error extracting state from log event. Listener is not + * updated of state change. + */ +TEST(StateTrackerTest, TestStateChangeEventError) { + sp<TestStateListener> listener1 = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener1); + + // log event + std::shared_ptr<LogEvent> event1 = + buildIncorrectOverlayEvent(1000 /* uid */, "package1", 1 /* state */); + std::shared_ptr<LogEvent> event2 = buildOverlayEventBadStateType(1001 /* uid */, "package2"); + + // check listener was updated + mgr.onLogEvent(*event1); + EXPECT_EQ(0, listener1->updates.size()); + mgr.onLogEvent(*event2); + EXPECT_EQ(0, listener1->updates.size()); +} + +TEST(StateTrackerTest, TestStateQuery) { + sp<TestStateListener> listener1 = new TestStateListener(); + sp<TestStateListener> listener2 = new TestStateListener(); + sp<TestStateListener> listener3 = new TestStateListener(); + sp<TestStateListener> listener4 = new TestStateListener(); + StateManager mgr; + mgr.registerListener(util::SCREEN_STATE_CHANGED, listener1); + mgr.registerListener(util::UID_PROCESS_STATE_CHANGED, listener2); + mgr.registerListener(util::OVERLAY_STATE_CHANGED, listener3); + mgr.registerListener(util::WAKELOCK_STATE_CHANGED, listener4); + + std::unique_ptr<LogEvent> event1 = CreateUidProcessStateChangedEvent( + timestampNs, 1000 /*uid*/, + android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002 + std::unique_ptr<LogEvent> event2 = CreateUidProcessStateChangedEvent( + timestampNs + 1000, 1001 /*uid*/, + android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE); // state value: + // 1003 + std::unique_ptr<LogEvent> event3 = CreateUidProcessStateChangedEvent( + timestampNs + 2000, 1002 /*uid*/, + android::app::ProcessStateEnum::PROCESS_STATE_PERSISTENT); // state value: 1000 + std::unique_ptr<LogEvent> event4 = CreateUidProcessStateChangedEvent( + timestampNs + 3000, 1001 /*uid*/, + android::app::ProcessStateEnum::PROCESS_STATE_TOP); // state value: 1002 + std::unique_ptr<LogEvent> event5 = CreateScreenStateChangedEvent( + timestampNs + 4000, android::view::DisplayStateEnum::DISPLAY_STATE_ON); + std::unique_ptr<LogEvent> event6 = CreateOverlayStateChangedEvent( + timestampNs + 5000, 1000 /*uid*/, "package1", true /*using_alert_window*/, + OverlayStateChanged::ENTERED); + std::unique_ptr<LogEvent> event7 = CreateOverlayStateChangedEvent( + timestampNs + 6000, 1000 /*uid*/, "package2", true /*using_alert_window*/, + OverlayStateChanged::EXITED); + + std::vector<int> attributionUids = {1005}; + std::vector<string> attributionTags = {"tag"}; + + std::unique_ptr<LogEvent> event8 = CreateAcquireWakelockEvent( + timestampNs + 7000, attributionUids, attributionTags, "wakelock1"); + std::unique_ptr<LogEvent> event9 = CreateReleaseWakelockEvent( + timestampNs + 8000, attributionUids, attributionTags, "wakelock2"); + + mgr.onLogEvent(*event1); + mgr.onLogEvent(*event2); + mgr.onLogEvent(*event3); + mgr.onLogEvent(*event5); + mgr.onLogEvent(*event5); + mgr.onLogEvent(*event6); + mgr.onLogEvent(*event7); + mgr.onLogEvent(*event8); + mgr.onLogEvent(*event9); + + // Query for UidProcessState of uid 1001 + HashableDimensionKey queryKey1; + getUidProcessKey(1001, &queryKey1); + EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE, + getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1)); + + // Query for UidProcessState of uid 1004 - not in state map + HashableDimensionKey queryKey2; + getUidProcessKey(1004, &queryKey2); + EXPECT_EQ(-1, getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, + queryKey2)); // default state + + // Query for UidProcessState of uid 1001 - after change in state + mgr.onLogEvent(*event4); + EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_TOP, + getStateInt(mgr, util::UID_PROCESS_STATE_CHANGED, queryKey1)); + + // Query for ScreenState + EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, + getStateInt(mgr, util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY)); + + // Query for OverlayState of uid 1000, package name "package2" + HashableDimensionKey queryKey3; + getOverlayKey(1000, "package2", &queryKey3); + EXPECT_EQ(OverlayStateChanged::EXITED, + getStateInt(mgr, util::OVERLAY_STATE_CHANGED, queryKey3)); + + // Query for WakelockState of uid 1005, tag 2 + HashableDimensionKey queryKey4; + getPartialWakelockKey(1005, "wakelock2", &queryKey4); + EXPECT_EQ(WakelockStateChanged::RELEASE, + getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey4)); + + // Query for WakelockState of uid 1005, tag 1 + HashableDimensionKey queryKey5; + getPartialWakelockKey(1005, "wakelock1", &queryKey5); + EXPECT_EQ(WakelockStateChanged::ACQUIRE, + getStateInt(mgr, util::WAKELOCK_STATE_CHANGED, queryKey5)); +} } // namespace statsd } // namespace os diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp index 050dbf8db7ad..c7838fcddb53 100644 --- a/cmds/statsd/tests/statsd_test_util.cpp +++ b/cmds/statsd/tests/statsd_test_util.cpp @@ -600,32 +600,51 @@ std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampN return logEvent; } -//std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent( -// const std::vector<AttributionNodeInternal>& attributions, const string& jobName, -// const ScheduledJobStateChanged::State state, uint64_t timestampNs) { -// auto event = std::make_unique<LogEvent>(util::SCHEDULED_JOB_STATE_CHANGED, timestampNs); -// event->write(attributions); -// event->write(jobName); -// event->write(state); -// event->init(); -// return event; -//} -// -//std::unique_ptr<LogEvent> CreateStartScheduledJobEvent( -// const std::vector<AttributionNodeInternal>& attributions, -// const string& name, uint64_t timestampNs) { -// return CreateScheduledJobStateChangedEvent( -// attributions, name, ScheduledJobStateChanged::STARTED, timestampNs); -//} -// -//// Create log event when scheduled job finishes. -//std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent( -// const std::vector<AttributionNodeInternal>& attributions, -// const string& name, uint64_t timestampNs) { -// return CreateScheduledJobStateChangedEvent( -// attributions, name, ScheduledJobStateChanged::FINISHED, timestampNs); -//} -// +std::unique_ptr<LogEvent> CreateScheduledJobStateChangedEvent( + const vector<int>& attributionUids, const vector<string>& attributionTags, + const string& jobName, const ScheduledJobStateChanged::State state, uint64_t timestampNs) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, util::SCHEDULED_JOB_STATE_CHANGED); + AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); + + vector<const char*> cTags(attributionTags.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = attributionTags[i].c_str(); + } + + AStatsEvent_writeAttributionChain(statsEvent, + reinterpret_cast<const uint32_t*>(attributionUids.data()), + cTags.data(), attributionUids.size()); + AStatsEvent_writeString(statsEvent, jobName.c_str()); + AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + + std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); + logEvent->parseBuffer(buf, size); + AStatsEvent_release(statsEvent); + return logEvent; +} + +std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs, + const vector<int>& attributionUids, + const vector<string>& attributionTags, + const string& jobName) { + return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName, + ScheduledJobStateChanged::STARTED, timestampNs); +} + +// Create log event when scheduled job finishes. +std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs, + const vector<int>& attributionUids, + const vector<string>& attributionTags, + const string& jobName) { + return CreateScheduledJobStateChangedEvent(attributionUids, attributionTags, jobName, + ScheduledJobStateChanged::FINISHED, timestampNs); +} + std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs, const vector<int>& attributionUids, const vector<string>& attributionTags, @@ -833,6 +852,62 @@ std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent( return logEvent; } +std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs, + const vector<int>& attributionUids, + const vector<string>& attributionTags, + const BleScanStateChanged::State state, + const bool filtered, const bool firstMatch, + const bool opportunistic) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, util::BLE_SCAN_STATE_CHANGED); + AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); + + vector<const char*> cTags(attributionTags.size()); + for (int i = 0; i < cTags.size(); i++) { + cTags[i] = attributionTags[i].c_str(); + } + + AStatsEvent_writeAttributionChain(statsEvent, + reinterpret_cast<const uint32_t*>(attributionUids.data()), + cTags.data(), attributionUids.size()); + AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_writeInt32(statsEvent, filtered); // filtered + AStatsEvent_writeInt32(statsEvent, firstMatch); // first match + AStatsEvent_writeInt32(statsEvent, opportunistic); // opportunistic + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + + std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); + logEvent->parseBuffer(buf, size); + AStatsEvent_release(statsEvent); + return logEvent; +} + +std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid, + const string& packageName, + const bool usingAlertWindow, + const OverlayStateChanged::State state) { + AStatsEvent* statsEvent = AStatsEvent_obtain(); + AStatsEvent_setAtomId(statsEvent, util::OVERLAY_STATE_CHANGED); + AStatsEvent_overwriteTimestamp(statsEvent, timestampNs); + + AStatsEvent_writeInt32(statsEvent, uid); + AStatsEvent_writeString(statsEvent, packageName.c_str()); + AStatsEvent_writeInt32(statsEvent, usingAlertWindow); + AStatsEvent_writeInt32(statsEvent, state); + AStatsEvent_build(statsEvent); + + size_t size; + uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size); + + std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0); + logEvent->parseBuffer(buf, size); + AStatsEvent_release(statsEvent); + return logEvent; +} + sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs, const StatsdConfig& config, const ConfigKey& key, const shared_ptr<IPullAtomCallback>& puller, diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h index ead041c29f28..05e1572e3aa9 100644 --- a/cmds/statsd/tests/statsd_test_util.h +++ b/cmds/statsd/tests/statsd_test_util.h @@ -195,14 +195,16 @@ std::unique_ptr<LogEvent> CreateScreenStateChangedEvent( std::unique_ptr<LogEvent> CreateScreenBrightnessChangedEvent(uint64_t timestampNs, int level); // Create log event when scheduled job starts. -std::unique_ptr<LogEvent> CreateStartScheduledJobEvent( - const std::vector<AttributionNodeInternal>& attributions, - const string& name, uint64_t timestampNs); +std::unique_ptr<LogEvent> CreateStartScheduledJobEvent(uint64_t timestampNs, + const vector<int>& attributionUids, + const vector<string>& attributionTags, + const string& jobName); // Create log event when scheduled job finishes. -std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent( - const std::vector<AttributionNodeInternal>& attributions, - const string& name, uint64_t timestampNs); +std::unique_ptr<LogEvent> CreateFinishScheduledJobEvent(uint64_t timestampNs, + const vector<int>& attributionUids, + const vector<string>& attributionTags, + const string& jobName); // Create log event when battery saver starts. std::unique_ptr<LogEvent> CreateBatterySaverOnEvent(uint64_t timestampNs); @@ -247,6 +249,18 @@ std::unique_ptr<LogEvent> CreateIsolatedUidChangedEvent(uint64_t timestampNs, in std::unique_ptr<LogEvent> CreateUidProcessStateChangedEvent( uint64_t timestampNs, int uid, const android::app::ProcessStateEnum state); +std::unique_ptr<LogEvent> CreateBleScanStateChangedEvent(uint64_t timestampNs, + const vector<int>& attributionUids, + const vector<string>& attributionTags, + const BleScanStateChanged::State state, + const bool filtered, const bool firstMatch, + const bool opportunistic); + +std::unique_ptr<LogEvent> CreateOverlayStateChangedEvent(int64_t timestampNs, const int32_t uid, + const string& packageName, + const bool usingAlertWindow, + const OverlayStateChanged::State state); + // Helper function to create an AttributionNodeInternal proto. AttributionNodeInternal CreateAttribution(const int& uid, const string& tag); |