(Part 3) Use new socket schema with statsd tests
Update last set of statsd tests to use new socket schema
Test: bit statsd_test:*
Bug: 149590301
Change-Id: I0fe2c219ad75813db54ff0cfbad50f55e29cb626
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index f9711c3..57e5455 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -78,7 +78,8 @@
// 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 @@
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 a5ff067..0bf24f1 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 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 @@
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 @@
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 @@
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 2de6377..6f4c8e4 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 @@
#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 d6498f4..9e7b7c8 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -253,1416 +253,1420 @@
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 a49c18f..29005a2 100644
--- a/cmds/statsd/tests/UidMap_test.cpp
+++ b/cmds/statsd/tests/UidMap_test.cpp
@@ -39,35 +39,28 @@
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 4c55683..5eef92e 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 @@
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 b1633c6..a0e0095 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 os {
namespace statsd {
+const int32_t timestampNs = 1000;
+
/**
* Mock StateListener class for testing.
* Stores primary key and state pairs.
@@ -56,95 +60,49 @@
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 @@
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 050dbf8..c7838fc 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -600,32 +600,51 @@
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 @@
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 ead041c..05e1572 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> 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> 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);