(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);