Snap for 8730993 from dc0641836870140075628fd25a256eb789bdf8d9 to mainline-tzdata3-release

Change-Id: I1251c0fcd094b30704a427873990c7b7bb871815
diff --git a/apex/apex_manifest.json b/apex/apex_manifest.json
index 0fb3227..7eb4b43 100644
--- a/apex/apex_manifest.json
+++ b/apex/apex_manifest.json
@@ -1,5 +1,5 @@
 {
   "name": "com.android.os.statsd",
-  "version": 339990000
+  "version": 319999900
 }
 
diff --git a/framework/test/unittests/Android.bp b/framework/test/unittests/Android.bp
index 243328c..e3fdfb9 100644
--- a/framework/test/unittests/Android.bp
+++ b/framework/test/unittests/Android.bp
@@ -24,7 +24,6 @@
     static_libs: [
         "androidx.test.rules",
         "truth-prebuilt",
-        "modules-utils-build",
     ],
     libs: [
         "android.test.runner.stubs",
diff --git a/framework/test/unittests/src/android/util/StatsEventTest.java b/framework/test/unittests/src/android/util/StatsEventTest.java
index 6d7e92d..ded21c3 100644
--- a/framework/test/unittests/src/android/util/StatsEventTest.java
+++ b/framework/test/unittests/src/android/util/StatsEventTest.java
@@ -18,18 +18,22 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
+
 import static java.nio.charset.StandardCharsets.UTF_8;
 
 import android.os.SystemClock;
+
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
-import com.android.modules.utils.build.SdkLevel;
+
 import com.google.common.collect.Range;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Random;
-import org.junit.Test;
-import org.junit.runner.RunWith;
 
 /**
  * Internal tests for {@link StatsEvent}.
@@ -417,11 +421,6 @@
 
     @Test
     public void testBoolArrayIntArrayLongArray() {
-        // Skip test if build version isn't T or greater.
-        if (!SdkLevel.isAtLeastT()) {
-            return;
-        }
-
         final int expectedAtomId = 109;
         final boolean[] field1 = new boolean[] {true, false, false};
         final int[] field1Converted = new int[] {1, 0, 0};
@@ -526,11 +525,6 @@
 
     @Test
     public void testFloatArrayStringArray() {
-        // Skip test if build version isn't T or greater.
-        if (!SdkLevel.isAtLeastT()) {
-            return;
-        }
-
         final int expectedAtomId = 109;
         final float[] field1 = new float[] {0.21f, 0.13f};
         final String[] field2 = new String[] {"str1", "str2", "str3"};
@@ -696,11 +690,6 @@
 
     @Test
     public void testArrayFieldAnnotations() {
-        // Skip test if build version isn't T or greater.
-        if (!SdkLevel.isAtLeastT()) {
-            return;
-        }
-
         final int expectedAtomId = 109;
         final int[] field1 = new int[] {4, 11};
         final byte boolAnnotationId = 45;
diff --git a/lib/libstatssocket/include/stats_event.h b/lib/libstatssocket/include/stats_event.h
index 23e1419..3d3baf9 100644
--- a/lib/libstatssocket/include/stats_event.h
+++ b/lib/libstatssocket/include/stats_event.h
@@ -141,49 +141,6 @@
                                        const char* const* tags, uint8_t numNodes);
 
 /**
- * Write a int32 array field to this StatsEvent.
- *
- * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
- * to StatsEvent.
- **/
-void AStatsEvent_writeInt32Array(AStatsEvent* event, const int32_t* elements, size_t numElements);
-
-/**
- * Write a int64 array field to this StatsEvent.
- *
- * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
- * to StatsEvent.
- **/
-void AStatsEvent_writeInt64Array(AStatsEvent* event, const int64_t* elements, size_t numElements);
-
-/**
- * Write a float array field to this StatsEvent.
- *
- * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
- * to StatsEvent.
- **/
-void AStatsEvent_writeFloatArray(AStatsEvent* event, const float* elements, size_t numElements);
-
-/**
- * Write a bool array field to this StatsEvent.
- *
- * Max size of array is 127. If exceeded, array is not written and ERROR_LIST_TOO_LONG is appended
- * to StatsEvent.
- **/
-void AStatsEvent_writeBoolArray(AStatsEvent* event, const bool* elements, size_t numElements);
-
-/**
- * Write a string array field to this StatsEvent.
- *
- * String array encoding is UTF8.
- *
- * Strings must be null terminated. Max size of array is 127. If exceeded, array is not written and
- * ERROR_LIST_TOO_LONG is appended to StatsEvent.
- **/
-void AStatsEvent_writeStringArray(AStatsEvent* event, const char* const* elements,
-                                  size_t numElements);
-
-/**
  * Write a bool annotation for the previous field written.
  **/
 void AStatsEvent_addBoolAnnotation(AStatsEvent* event, uint8_t annotationId, bool value);
diff --git a/lib/libstatssocket/libstatssocket.map.txt b/lib/libstatssocket/libstatssocket.map.txt
index aa6eb30..5c13904 100644
--- a/lib/libstatssocket/libstatssocket.map.txt
+++ b/lib/libstatssocket/libstatssocket.map.txt
@@ -12,11 +12,6 @@
         AStatsEvent_writeByteArray; # apex # introduced=30
         AStatsEvent_writeString; # apex # introduced=30
         AStatsEvent_writeAttributionChain; # apex # introduced=30
-        AStatsEvent_writeInt32Array; # apex # introduced=Tiramisu
-        AStatsEvent_writeInt64Array; # apex # introduced=Tiramisu
-        AStatsEvent_writeFloatArray; # apex # introduced=Tiramisu
-        AStatsEvent_writeBoolArray; # apex # introduced=Tiramisu
-        AStatsEvent_writeStringArray; # apex # introduced=Tiramisu
         AStatsEvent_addBoolAnnotation; # apex # introduced=30
         AStatsEvent_addInt32Annotation; # apex # introduced=30
         AStatsSocket_close; # apex # introduced=30
diff --git a/lib/libstatssocket/stats_event.c b/lib/libstatssocket/stats_event.c
index 9bb4c52..dcd34aa 100644
--- a/lib/libstatssocket/stats_event.c
+++ b/lib/libstatssocket/stats_event.c
@@ -50,7 +50,6 @@
 #define ERROR_INVALID_VALUE_TYPE 0x400
 #define ERROR_STRING_NOT_NULL_TERMINATED 0x800
 #define ERROR_ATOM_ID_INVALID_POSITION 0x2000
-#define ERROR_LIST_TOO_LONG 0x4000
 
 /* TYPE IDS */
 #define INT32_TYPE 0x00
@@ -265,69 +264,6 @@
     }
 }
 
-static bool writeArrayMetadata(AStatsEvent* event, size_t numElements, uint8_t elementTypeId) {
-    if (numElements > MAX_BYTE_VALUE) {
-        event->errors |= ERROR_LIST_TOO_LONG;
-        return false;
-    }
-
-    start_field(event, LIST_TYPE);
-    append_byte(event, numElements);
-    append_byte(event, elementTypeId);
-    return true;
-}
-
-void AStatsEvent_writeInt32Array(AStatsEvent* event, const int32_t* elements, size_t numElements) {
-    if (!writeArrayMetadata(event, numElements, INT32_TYPE)) {
-        return;
-    }
-
-    for (size_t i = 0; i < numElements; i++) {
-        append_int32(event, elements[i]);
-    }
-}
-
-void AStatsEvent_writeInt64Array(AStatsEvent* event, const int64_t* elements, size_t numElements) {
-    if (!writeArrayMetadata(event, numElements, INT64_TYPE)) {
-        return;
-    }
-
-    for (size_t i = 0; i < numElements; i++) {
-        append_int64(event, elements[i]);
-    }
-}
-
-void AStatsEvent_writeFloatArray(AStatsEvent* event, const float* elements, size_t numElements) {
-    if (!writeArrayMetadata(event, numElements, FLOAT_TYPE)) {
-        return;
-    }
-
-    for (size_t i = 0; i < numElements; i++) {
-        append_float(event, elements[i]);
-    }
-}
-
-void AStatsEvent_writeBoolArray(AStatsEvent* event, const bool* elements, size_t numElements) {
-    if (!writeArrayMetadata(event, numElements, BOOL_TYPE)) {
-        return;
-    }
-
-    for (size_t i = 0; i < numElements; i++) {
-        append_bool(event, elements[i]);
-    }
-}
-
-void AStatsEvent_writeStringArray(AStatsEvent* event, const char* const* elements,
-                                  size_t numElements) {
-    if (!writeArrayMetadata(event, numElements, STRING_TYPE)) {
-        return;
-    }
-
-    for (size_t i = 0; i < numElements; i++) {
-        append_string(event, elements[i] == NULL ? "" : elements[i]);
-    }
-}
-
 // Side-effect: modifies event->errors if field has too many annotations
 static void increment_annotation_count(AStatsEvent* event) {
     uint8_t fieldType = event->buf[event->lastFieldPos] & 0x0F;
diff --git a/lib/libstatssocket/tests/stats_event_test.cpp b/lib/libstatssocket/tests/stats_event_test.cpp
index 93a99f1..2f9ccdc 100644
--- a/lib/libstatssocket/tests/stats_event_test.cpp
+++ b/lib/libstatssocket/tests/stats_event_test.cpp
@@ -33,7 +33,6 @@
 #define ERROR_INVALID_VALUE_TYPE 0x400
 #define ERROR_STRING_NOT_NULL_TERMINATED 0x800
 #define ERROR_ATOM_ID_INVALID_POSITION 0x2000
-#define ERROR_LIST_TOO_LONG 0x4000
 
 /* TYPE IDS */
 #define INT32_TYPE 0x00
@@ -88,23 +87,6 @@
     *buffer += size;  // move buffer past byte array we just read
 }
 
-void checkArrayMetadata(uint8_t** buffer, uint8_t numElements, uint8_t elementTypeId,
-                        uint8_t numAnnotations = 0) {
-    checkTypeHeader(buffer, LIST_TYPE, numAnnotations);
-    EXPECT_EQ(readNext<uint8_t>(buffer), numElements);
-    checkTypeHeader(buffer, elementTypeId);
-}
-
-template <class T>
-void checkScalarArray(uint8_t** buffer, uint8_t numElements, uint8_t elementTypeId,
-                      const T* expectedArrayValues, uint8_t numAnnotations = 0) {
-    checkArrayMetadata(buffer, numElements, elementTypeId, numAnnotations);
-
-    for (int i = 0; i < numElements; i++) {
-        checkScalar(buffer, expectedArrayValues[i]);
-    }
-}
-
 template <class T>
 void checkAnnotation(uint8_t** buffer, uint8_t annotationId, uint8_t typeId, T annotationValue) {
     EXPECT_EQ(readNext<uint8_t>(buffer), annotationId);
@@ -277,61 +259,6 @@
     AStatsEvent_release(event);
 }
 
-TEST(StatsEventTest, TestAllArrays) {
-    uint32_t atomId = 100;
-
-    uint8_t numElements = 3;
-    int32_t int32Array[3] = {3, 6, 9};
-    int64_t int64Array[3] = {1000L, 1001L, 1002L};
-    float floatArray[3] = {0.1f, 0.3f, 0.09f};
-    bool boolArray[3] = {0, 1, 1};
-
-    vector<string> stringArray = {"str1", "str2", "str3"};
-    const char* cStringArray[3];
-    for (int i = 0; i < numElements; i++) {
-        cStringArray[i] = stringArray[i].c_str();
-    }
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeInt32Array(event, int32Array, numElements);
-    AStatsEvent_writeInt64Array(event, int64Array, numElements);
-    AStatsEvent_writeFloatArray(event, floatArray, numElements);
-    AStatsEvent_writeBoolArray(event, boolArray, numElements);
-    AStatsEvent_writeStringArray(event, cStringArray, numElements);
-    AStatsEvent_build(event);
-    int64_t endTime = android::elapsedRealtimeNano();
-
-    size_t bufferSize;
-    uint8_t* buffer = AStatsEvent_getBuffer(event, &bufferSize);
-    uint8_t* bufferEnd = buffer + bufferSize;
-
-    checkMetadata(&buffer, /*numTopLevelElements=*/5, startTime, endTime, atomId);
-
-    // check int32Array element
-    checkScalarArray(&buffer, numElements, INT32_TYPE, int32Array);
-
-    // check int64Array element
-    checkScalarArray(&buffer, numElements, INT64_TYPE, int64Array);
-
-    // check floatArray element
-    checkScalarArray(&buffer, numElements, FLOAT_TYPE, floatArray);
-
-    // check boolArray element
-    checkScalarArray(&buffer, numElements, BOOL_TYPE, boolArray);
-
-    // check stringArray element
-    checkArrayMetadata(&buffer, numElements, STRING_TYPE);
-    for (int i = 0; i < numElements; i++) {
-        checkString(&buffer, stringArray[i]);
-    }
-
-    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
-
 TEST(StatsEventTest, TestAttributionChains) {
     uint32_t atomId = 100;
 
@@ -427,43 +354,6 @@
     AStatsEvent_release(event);
 }
 
-TEST(StatsEventTest, TestArrayFieldAnnotations) {
-    uint32_t atomId = 100;
-
-    // array annotation info
-    uint8_t boolAnnotationId = 1;
-    uint8_t int32AnnotationId = 2;
-    bool boolAnnotationValue = true;
-    int32_t int32AnnotationValue = 4;
-
-    uint8_t numElements = 3;
-    int32_t int32Array[3] = {3, 6, 9};
-
-    int64_t startTime = android::elapsedRealtimeNano();
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeInt32Array(event, int32Array, numElements);
-    AStatsEvent_addBoolAnnotation(event, boolAnnotationId, boolAnnotationValue);
-    AStatsEvent_addInt32Annotation(event, int32AnnotationId, int32AnnotationValue);
-    AStatsEvent_build(event);
-    int64_t endTime = android::elapsedRealtimeNano();
-
-    size_t bufferSize;
-    uint8_t* buffer = AStatsEvent_getBuffer(event, &bufferSize);
-    uint8_t* bufferEnd = buffer + bufferSize;
-
-    checkMetadata(&buffer, /*numElements=*/1, startTime, endTime, atomId);
-
-    // check first element
-    checkScalarArray(&buffer, numElements, INT32_TYPE, int32Array, /*numAnnotations=*/2);
-    checkAnnotation(&buffer, boolAnnotationId, BOOL_TYPE, boolAnnotationValue);
-    checkAnnotation(&buffer, int32AnnotationId, INT32_TYPE, int32AnnotationValue);
-
-    EXPECT_EQ(buffer, bufferEnd);  // ensure that we have read the entire buffer
-    EXPECT_EQ(AStatsEvent_getErrors(event), 0);
-    AStatsEvent_release(event);
-}
-
 TEST(StatsEventTest, TestAtomLevelAnnotations) {
     uint32_t atomId = 100;
     // atom-level annotation information
@@ -624,43 +514,3 @@
     EXPECT_EQ(AStatsEvent_getErrors(event), 0);
     AStatsEvent_release(event);
 }
-
-TEST(StatsEventTest, TestAttributionChainTooLongError) {
-    uint32_t atomId = 100;
-    uint8_t numNodes = 128;
-    uint32_t uids[numNodes];
-    vector<string> tags(numNodes);  // storage that cTag elements point to
-    const char* cTags[numNodes];
-    for (int i = 0; i < (int)numNodes; i++) {
-        uids[i] = i;
-        if (0 == i) {
-            tags.push_back("");
-            cTags[i] = nullptr;
-        } else {
-            tags.push_back("test" + std::to_string(i));
-            cTags[i] = tags[i].c_str();
-        }
-    }
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeAttributionChain(event, uids, cTags, numNodes);
-    AStatsEvent_build(event);
-
-    uint32_t errors = AStatsEvent_getErrors(event);
-    EXPECT_EQ(errors & ERROR_ATTRIBUTION_CHAIN_TOO_LONG, ERROR_ATTRIBUTION_CHAIN_TOO_LONG);
-}
-
-TEST(StatsEventTest, TestListTooLongError) {
-    uint32_t atomId = 100;
-    uint8_t numElements = 128;
-    int32_t int32Array[128] = {1};
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, atomId);
-    AStatsEvent_writeInt32Array(event, int32Array, numElements);
-    AStatsEvent_build(event);
-
-    uint32_t errors = AStatsEvent_getErrors(event);
-    EXPECT_EQ(errors & ERROR_LIST_TOO_LONG, ERROR_LIST_TOO_LONG);
-}
diff --git a/service/java/com/android/server/stats/StatsCompanionService.java b/service/java/com/android/server/stats/StatsCompanionService.java
index bc7e25e..a0460fa 100644
--- a/service/java/com/android/server/stats/StatsCompanionService.java
+++ b/service/java/com/android/server/stats/StatsCompanionService.java
@@ -774,12 +774,7 @@
                     mContext.getMainExecutor(), this::onPropertiesChanged);
 
             // Get current statsd_java properties.
-            final long token = Binder.clearCallingIdentity();
-            try {
-                updateProperties(DeviceConfig.getProperties(NAMESPACE_STATSD_JAVA));
-            } finally {
-                Binder.restoreCallingIdentity(token);
-            }
+            updateProperties(DeviceConfig.getProperties(NAMESPACE_STATSD_JAVA));
 
             // Register death recipient.
             List<BroadcastReceiver> broadcastReceivers =
diff --git a/statsd/Android.bp b/statsd/Android.bp
index cb81c34..f9463ba 100644
--- a/statsd/Android.bp
+++ b/statsd/Android.bp
@@ -265,6 +265,9 @@
     require_root: true,
 
     srcs: [
+        // atom_field_options.proto needs field_options.proto, but that is
+        // not included in libprotobuf-cpp-lite, so compile it here.
+        ":libprotobuf-internal-protos",
         ":libstats_internal_protos",
 
         "src/shell/shell_data.proto",
@@ -323,7 +326,6 @@
         "tests/shell/ShellSubscriber_test.cpp",
         "tests/state/StateTracker_test.cpp",
         "tests/statsd_test_util.cpp",
-        "tests/statsd_test_util_test.cpp",
         "tests/StatsLogProcessor_test.cpp",
         "tests/StatsService_test.cpp",
         "tests/storage/StorageManager_test.cpp",
@@ -333,15 +335,16 @@
 
     static_libs: [
         "libgmock",
-        "libplatformprotos-test",
+        "libplatformprotos",
         "libstatslog_statsdtest",
         "libstatssocket_private",
     ],
 
     proto: {
-        type: "full",
+        type: "lite",
         include_dirs: [
             "external/protobuf/src",
+            "frameworks/proto_logging/stats",
         ],
     },
 
diff --git a/statsd/src/FieldValue.cpp b/statsd/src/FieldValue.cpp
index 406c19f..9e4e450 100644
--- a/statsd/src/FieldValue.cpp
+++ b/statsd/src/FieldValue.cpp
@@ -137,10 +137,6 @@
     return fieldValue.mAnnotations.isUidField();
 }
 
-bool isPrimitiveRepeatedField(const Field& field) {
-    return field.getDepth() == 1;
-}
-
 Value::Value(const Value& from) {
     type = from.getType();
     switch (type) {
@@ -500,19 +496,6 @@
     return false;
 }
 
-bool HasPrimitiveRepeatedField(const FieldMatcher& matcher) {
-    for (const auto& child : matcher.child()) {
-        if (child.has_position() && child.child_size() == 0) {
-            return true;
-        }
-    }
-    return false;
-}
-
-bool ShouldUseNestedDimensions(const FieldMatcher& matcher) {
-    return HasPositionALL(matcher) || HasPrimitiveRepeatedField(matcher);
-}
-
 size_t getSize(const std::vector<FieldValue>& fieldValues) {
     size_t totalSize = 0;
     for (const FieldValue& fieldValue : fieldValues) {
diff --git a/statsd/src/FieldValue.h b/statsd/src/FieldValue.h
index 979264c..81fe28c 100644
--- a/statsd/src/FieldValue.h
+++ b/statsd/src/FieldValue.h
@@ -194,13 +194,13 @@
  * It contains all information needed to match one or more leaf node.
  * All information is encoded in a Field(2 ints) and a bit mask(1 int).
  *
- * For example, to match the first/all/last uid field in attribution chain in Atom 10,
+ * For example, to match the first/any/last uid field in attribution chain in Atom 10,
  * we have the following FieldMatcher in statsd_config
  *    FieldMatcher {
  *        field:10
  *         FieldMatcher {
  *              field:1
- *              position: all/last/first
+ *              position: any/last/first
  *              FieldMatcher {
  *                  field:1
  *              }
@@ -210,6 +210,7 @@
  * We translate the FieldMatcher into a Field, and mask
  * First: [Matcher Field] 0x02010101  [Mask]0xff7f7f7f
  * Last:  [Matcher Field] 0x02018001  [Mask]0xff7f807f
+ * Any:   [Matcher Field] 0x02010001  [Mask]0xff7f007f
  * All:   [Matcher Field] 0x02010001  [Mask]0xff7f7f7f
  *
  * [To match a log Field with a Matcher] we apply the bit mask to the log Field and check if
@@ -241,7 +242,15 @@
     }
 
     bool hasAllPositionMatcher() const {
-        return mMatcher.getDepth() >= 1 && getRawMaskAtDepth(1) == 0x7f;
+        return mMatcher.getDepth() == 2 && getRawMaskAtDepth(1) == 0x7f;
+    }
+
+    bool hasAnyPositionMatcher(int* prefix) const {
+        if (mMatcher.getDepth() == 2 && mMatcher.getRawPosAtDepth(1) == 0) {
+            (*prefix) = mMatcher.getPrefix(1);
+            return true;
+        }
+        return false;
     }
 
     inline bool operator!=(const Matcher& that) const {
@@ -441,8 +450,6 @@
 
 bool HasPositionANY(const FieldMatcher& matcher);
 bool HasPositionALL(const FieldMatcher& matcher);
-bool HasPrimitiveRepeatedField(const FieldMatcher& matcher);
-bool ShouldUseNestedDimensions(const FieldMatcher& matcher);
 
 bool isAttributionUidField(const FieldValue& value);
 
@@ -453,7 +460,6 @@
 
 bool isAttributionUidField(const Field& field, const Value& value);
 bool isUidField(const FieldValue& fieldValue);
-bool isPrimitiveRepeatedField(const Field& field);
 
 bool equalDimensions(const std::vector<Matcher>& dimension_a,
                      const std::vector<Matcher>& dimension_b);
diff --git a/statsd/src/StatsLogProcessor.cpp b/statsd/src/StatsLogProcessor.cpp
index b90a5b7..1f0f564 100644
--- a/statsd/src/StatsLogProcessor.cpp
+++ b/statsd/src/StatsLogProcessor.cpp
@@ -139,9 +139,9 @@
 }
 
 void StatsLogProcessor::mapIsolatedUidToHostUidIfNecessaryLocked(LogEvent* event) const {
-    if (std::pair<size_t, size_t> indexRange; event->hasAttributionChain(&indexRange)) {
+    if (std::pair<int, int> indexRange; event->hasAttributionChain(&indexRange)) {
         vector<FieldValue>* const fieldValues = event->getMutableValues();
-        for (size_t i = indexRange.first; i <= indexRange.second; i++) {
+        for (int i = indexRange.first; i <= indexRange.second; i++) {
             FieldValue& fieldValue = fieldValues->at(i);
             if (isAttributionUidField(fieldValue)) {
                 const int hostUid = mUidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
diff --git a/statsd/src/StatsLogProcessor.h b/statsd/src/StatsLogProcessor.h
index 231b411..761748c 100644
--- a/statsd/src/StatsLogProcessor.h
+++ b/statsd/src/StatsLogProcessor.h
@@ -322,7 +322,6 @@
     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid);
     FRIEND_TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain);
     FRIEND_TEST(GaugeMetricE2ePushedTest, TestMultipleFieldsForPushedEvent);
-    FRIEND_TEST(GaugeMetricE2ePushedTest, TestRepeatedFieldsForPushedEvent);
     FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvents);
     FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEvent_LateAlarm);
     FRIEND_TEST(GaugeMetricE2ePulledTest, TestRandomSamplePulledEventsWithActivation);
@@ -360,7 +359,6 @@
     FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithMap);
     FRIEND_TEST(CountMetricE2eTest, TestMultipleSlicedStates);
     FRIEND_TEST(CountMetricE2eTest, TestSlicedStateWithPrimaryFields);
-    FRIEND_TEST(CountMetricE2eTest, TestRepeatedFieldsAndEmptyArrays);
 
     FRIEND_TEST(DurationMetricE2eTest, TestOneBucket);
     FRIEND_TEST(DurationMetricE2eTest, TestTwoBuckets);
@@ -374,7 +372,6 @@
     FRIEND_TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat);
     FRIEND_TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset);
     FRIEND_TEST(DurationMetricE2eTest, TestUploadThreshold);
-    FRIEND_TEST(DurationMetricE2eTest, TestConditionOnRepeatedEnumField);
 
     FRIEND_TEST(ValueMetricE2eTest, TestInitialConditionChanges);
     FRIEND_TEST(ValueMetricE2eTest, TestPulledEvents);
@@ -383,9 +380,6 @@
     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState);
     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithDimensions);
     FRIEND_TEST(ValueMetricE2eTest, TestInitWithSlicedState_WithIncorrectDimensions);
-    FRIEND_TEST(ValueMetricE2eTest, TestInitWithValueFieldPositionALL);
-
-    FRIEND_TEST(KllMetricE2eTest, TestInitWithKllFieldPositionALL);
 };
 
 }  // namespace statsd
diff --git a/statsd/src/StatsService.cpp b/statsd/src/StatsService.cpp
index 1c647cb..ef21a04 100644
--- a/statsd/src/StatsService.cpp
+++ b/statsd/src/StatsService.cpp
@@ -55,6 +55,8 @@
 
 constexpr const char* kPermissionRegisterPullAtom = "android.permission.REGISTER_STATS_PULL_ATOM";
 
+constexpr const char* kIncludeCertificateHash = "include_certificate_hash";
+
 #define STATS_SERVICE_DIR "/data/misc/stats-service"
 
 // for StatsDataDumpProto
@@ -88,9 +90,8 @@
     }                                                             \
 }
 
-StatsService::StatsService(const sp<UidMap>& uidMap, shared_ptr<LogEventQueue> queue)
-    : mUidMap(uidMap),
-      mAnomalyAlarmMonitor(new AlarmMonitor(
+StatsService::StatsService(const sp<Looper>& handlerLooper, shared_ptr<LogEventQueue> queue)
+    : mAnomalyAlarmMonitor(new AlarmMonitor(
               MIN_DIFF_TO_UPDATE_REGISTERED_ALARM_SECS,
               [this](const shared_ptr<IStatsCompanionService>& /*sc*/, int64_t timeMillis) {
                   mProcessor->setAnomalyAlarm(timeMillis);
@@ -119,6 +120,7 @@
                            [this]() { mProcessor->onStatsdInitCompleted(getElapsedRealtimeNs()); }),
       mStatsCompanionServiceDeathRecipient(
               AIBinder_DeathRecipient_new(StatsService::statsCompanionServiceDied)) {
+    mUidMap = UidMap::getInstance();
     mPullerManager = new StatsPullerManager();
     StatsPuller::SetUidMap(mUidMap);
     mConfigManager = new ConfigManager();
diff --git a/statsd/src/StatsService.h b/statsd/src/StatsService.h
index d0f1325..790397f 100644
--- a/statsd/src/StatsService.h
+++ b/statsd/src/StatsService.h
@@ -53,11 +53,9 @@
 namespace os {
 namespace statsd {
 
-constexpr const char* kIncludeCertificateHash = "include_certificate_hash";
-
 class StatsService : public BnStatsd {
 public:
-    StatsService(const sp<UidMap>& uidMap, shared_ptr<LogEventQueue> queue);
+    StatsService(const sp<Looper>& handlerLooper, std::shared_ptr<LogEventQueue> queue);
     virtual ~StatsService();
 
     /** The anomaly alarm registered with AlarmManager won't be updated by less than this. */
@@ -351,7 +349,7 @@
     /**
      * Tracks the uid <--> package name mapping.
      */
-    const sp<UidMap> mUidMap;
+    sp<UidMap> mUidMap;
 
     /**
      * Fetches external metrics
diff --git a/statsd/src/external/puller_util.cpp b/statsd/src/external/puller_util.cpp
index b0c68f4..dc7cdce 100644
--- a/statsd/src/external/puller_util.cpp
+++ b/statsd/src/external/puller_util.cpp
@@ -51,7 +51,7 @@
                                       int tagId, const vector<int>& additiveFieldsVec) {
     // Check the first LogEvent for attribution chain or a uid field as either all atoms with this
     // tagId have them or none of them do.
-    std::pair<size_t, size_t> attrIndexRange;
+    std::pair<int, int> attrIndexRange;
     const bool hasAttributionChain = data[0]->hasAttributionChain(&attrIndexRange);
     const uint8_t numUidFields = data[0]->getNumUidFields();
 
@@ -68,7 +68,7 @@
         }
         if (hasAttributionChain) {
             vector<FieldValue>* const fieldValues = event->getMutableValues();
-            for (size_t i = attrIndexRange.first; i <= attrIndexRange.second; i++) {
+            for (int i = attrIndexRange.first; i <= attrIndexRange.second; i++) {
                 FieldValue& fieldValue = fieldValues->at(i);
                 if (isAttributionUidField(fieldValue)) {
                     const int hostUid = uidMap->getHostUidOrSelf(fieldValue.mValue.int_value);
@@ -101,15 +101,12 @@
     bool needMerge = true;
 
     // 3. do the merge.
-    // The loop invariant is this: for every event,
-    // - check if it has a different length (means different attribution chains or repeated fields)
-    // - check if fields are different
-    // - check if non-additive field values are different (non-additive is default for repeated
-    // fields)
-    // If any are true, no need to merge, add itself to the result. Otherwise, merge the
-    // value onto the one immediately next to it.
+    // The loop invariant is this: for every event, check if it differs on
+    // non-additive fields, or have different attribution chain length.
+    // If so, no need to merge, add itself to the result.
+    // Otherwise, merge the value onto the one immediately next to it.
     for (int i = 0; i < (int)data.size() - 1; i++) {
-        // Size different, must be different chains or repeated fields.
+        // Size different, must be different chains.
         if (data[i]->size() != data[i + 1]->size()) {
             mergedData.push_back(data[i]);
             continue;
@@ -118,16 +115,10 @@
         vector<FieldValue>* rhsValues = data[i + 1]->getMutableValues();
         needMerge = true;
         for (int p = 0; p < (int)lhsValues->size(); p++) {
-            if ((*lhsValues)[p].mField != (*rhsValues)[p].mField) {
-                needMerge = false;
-                break;
-            }
-            if ((*lhsValues)[p].mValue != (*rhsValues)[p].mValue) {
+            if ((*lhsValues)[p] != (*rhsValues)[p]) {
                 int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
                 // Differ on non-additive field, abort.
-                // Repeated additive fields are treated as non-additive fields.
-                if (isPrimitiveRepeatedField((*lhsValues)[p].mField) ||
-                    (additiveFields.find(pos) == additiveFields.end())) {
+                if (additiveFields.find(pos) == additiveFields.end()) {
                     needMerge = false;
                     break;
                 }
@@ -140,9 +131,7 @@
         // This should be infrequent operation.
         for (int p = 0; p < (int)lhsValues->size(); p++) {
             int pos = (*lhsValues)[p].mField.getPosAtDepth(0);
-            // Don't merge repeated fields.
-            if (!isPrimitiveRepeatedField((*lhsValues)[p].mField) &&
-                (additiveFields.find(pos) != additiveFields.end())) {
+            if (additiveFields.find(pos) != additiveFields.end()) {
                 (*rhsValues)[p].mValue += (*lhsValues)[p].mValue;
             }
         }
diff --git a/statsd/src/flags/FlagProvider.h b/statsd/src/flags/FlagProvider.h
index dcdf35f..61d1841 100644
--- a/statsd/src/flags/FlagProvider.h
+++ b/statsd/src/flags/FlagProvider.h
@@ -37,7 +37,8 @@
 const std::string STATSD_NATIVE_NAMESPACE = "statsd_native";
 const std::string STATSD_NATIVE_BOOT_NAMESPACE = "statsd_native_boot";
 
-const std::string OPTIMIZATION_ATOM_MATCHER_MAP_FLAG = "optimization_atom_matcher_map";
+const std::string VALUE_METRIC_SUBSET_DIMENSION_AGGREGATION_FLAG =
+        "value_metric_subset_dimension_aggregation";
 
 const std::string FLAG_TRUE = "true";
 const std::string FLAG_FALSE = "false";
@@ -111,8 +112,10 @@
     friend class FlagProviderTest_SPlus_RealValues;
     friend class KllMetricE2eAbTest;
     friend class MetricsManagerTest;
-    friend class StatsLogProcessorTest;
+    friend class NumericValueMetricProducerTest_SubsetDimensions;
+    friend class PartialBucketE2e_AppUpgradeDefaultTest;
 
+    FRIEND_TEST(ConfigUpdateE2eTest, TestKllMetric_KllDisabledBeforeConfigUpdate);
     FRIEND_TEST(ConfigUpdateE2eTest, TestEventMetric);
     FRIEND_TEST(ConfigUpdateE2eTest, TestGaugeMetric);
     FRIEND_TEST(EventMetricE2eTest, TestEventMetricDataAggregated);
@@ -126,8 +129,10 @@
     FRIEND_TEST(FlagProviderTest_SPlus, TestGetFlagBoolServerFlagEmptyDefaultTrue);
     FRIEND_TEST(FlagProviderTest_SPlus_RealValues, TestGetBootFlagBoolServerFlagTrue);
     FRIEND_TEST(FlagProviderTest_SPlus_RealValues, TestGetBootFlagBoolServerFlagFalse);
-    FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagFalse);
-    FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagTrue);
+    FRIEND_TEST(NumericValueMetricProducerTest_SubsetDimensions, TestSubsetDimensions_FlagTrue);
+    FRIEND_TEST(NumericValueMetricProducerTest_SubsetDimensions, TestSubsetDimensions_FlagFalse);
+    FRIEND_TEST(PartialBucketE2e_AppUpgradeDefaultTest, TestCountMetricDefaultFalse);
+    FRIEND_TEST(PartialBucketE2e_AppUpgradeDefaultTest, TestCountMetricDefaultTrue);
 };
 
 }  // namespace statsd
diff --git a/statsd/src/guardrail/StatsdStats.h b/statsd/src/guardrail/StatsdStats.h
index d812e55..bfcb0fd 100644
--- a/statsd/src/guardrail/StatsdStats.h
+++ b/statsd/src/guardrail/StatsdStats.h
@@ -102,10 +102,10 @@
     static const std::map<int, std::pair<size_t, size_t>> kAtomDimensionKeySizeLimitMap;
 
     const static int kMaxConfigCountPerUid = 20;
-    const static int kMaxAlertCountPerConfig = 200;
-    const static int kMaxConditionCountPerConfig = 500;
-    const static int kMaxMetricCountPerConfig = 2000;
-    const static int kMaxMatcherCountPerConfig = 2500;
+    const static int kMaxAlertCountPerConfig = 100;
+    const static int kMaxConditionCountPerConfig = 300;
+    const static int kMaxMetricCountPerConfig = 1000;
+    const static int kMaxMatcherCountPerConfig = 1200;
 
     // The max number of old config stats we keep.
     const static int kMaxIceBoxSize = 20;
@@ -163,11 +163,11 @@
     static const int64_t kPullMaxDelayNs = 30 * NS_PER_SEC;
 
     // Maximum number of pushed atoms statsd stats will track above kMaxPushedAtomId.
-    static const int kMaxNonPlatformPushedAtoms = 600;
+    static const int kMaxNonPlatformPushedAtoms = 400;
 
     // Maximum atom id value that we consider a platform pushed atom.
     // This should be updated once highest pushed atom id in atoms.proto approaches this value.
-    static const int kMaxPushedAtomId = 750;
+    static const int kMaxPushedAtomId = 500;
 
     // Atom id that is the start of the pulled atoms.
     static const int kPullAtomStartTag = 10000;
diff --git a/statsd/src/logd/LogEvent.cpp b/statsd/src/logd/LogEvent.cpp
index 398ce3e..e89d067 100644
--- a/statsd/src/logd/LogEvent.cpp
+++ b/statsd/src/logd/LogEvent.cpp
@@ -39,6 +39,34 @@
 using std::string;
 using std::vector;
 
+// stats_event.h socket types. Keep in sync.
+/* ERRORS */
+#define ERROR_NO_TIMESTAMP 0x1
+#define ERROR_NO_ATOM_ID 0x2
+#define ERROR_OVERFLOW 0x4
+#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
+#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
+#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
+#define ERROR_INVALID_ANNOTATION_ID 0x40
+#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
+#define ERROR_TOO_MANY_ANNOTATIONS 0x100
+#define ERROR_TOO_MANY_FIELDS 0x200
+#define ERROR_INVALID_VALUE_TYPE 0x400
+#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
+
+/* TYPE IDS */
+#define INT32_TYPE 0x00
+#define INT64_TYPE 0x01
+#define STRING_TYPE 0x02
+#define LIST_TYPE 0x03
+#define FLOAT_TYPE 0x04
+#define BOOL_TYPE 0x05
+#define BYTE_ARRAY_TYPE 0x06
+#define OBJECT_TYPE 0x07
+#define KEY_VALUE_PAIRS_TYPE 0x08
+#define ATTRIBUTION_CHAIN_TYPE 0x09
+#define ERROR_TYPE 0x0F
+
 LogEvent::LogEvent(int32_t uid, int32_t pid)
     : mLogdTimestampNs(time(nullptr)), mLogUid(uid), mLogPid(pid) {
 }
@@ -175,11 +203,8 @@
 
 void LogEvent::parseAttributionChain(int32_t* pos, int32_t depth, bool* last,
                                      uint8_t numAnnotations) {
-    std::optional<size_t> firstUidInChainIndex = mValues.size();
-    const uint8_t numNodes = readNextValue<uint8_t>();
-
-    if (numNodes > INT8_MAX) mValid = false;
-
+    const unsigned int firstUidInChainIndex = mValues.size();
+    const int32_t numNodes = readNextValue<uint8_t>();
     for (pos[1] = 1; pos[1] <= numNodes; pos[1]++) {
         last[1] = (pos[1] == numNodes);
 
@@ -193,96 +218,39 @@
         parseString(pos, /*depth=*/2, last, /*numAnnotations=*/0);
     }
 
-    if (mValues.size() > (firstUidInChainIndex.value() + 1)) {
-        // At least one node was successfully parsed.
-        mAttributionChainStartIndex = firstUidInChainIndex;
-        mAttributionChainEndIndex = mValues.size() - 1;
-    } else {
-        firstUidInChainIndex = std::nullopt;
+    if (mValues.size() - 1 > INT8_MAX) {
         mValid = false;
+    } else if (mValues.size() - 1 > firstUidInChainIndex) {
+        // At least one node was successfully parsed.
+        mAttributionChainStartIndex = static_cast<int8_t>(firstUidInChainIndex);
+        mAttributionChainEndIndex = static_cast<int8_t>(mValues.size() - 1);
     }
 
     if (mValid) {
-        parseAnnotations(numAnnotations, /*numElements*/ std::nullopt, firstUidInChainIndex);
+        parseAnnotations(numAnnotations, firstUidInChainIndex);
     }
 
     pos[1] = pos[2] = 1;
     last[1] = last[2] = false;
 }
 
-void LogEvent::parseArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations) {
-    const uint8_t numElements = readNextValue<uint8_t>();
-    const uint8_t typeInfo = readNextValue<uint8_t>();
-    const uint8_t typeId = getTypeId(typeInfo);
-
-    if (numElements > INT8_MAX) mValid = false;
-
-    for (pos[1] = 1; pos[1] <= numElements; pos[1]++) {
-        last[1] = (pos[1] == numElements);
-
-        // The top-level array is at depth 0, and all of its elements are at depth 1.
-        // Once nested fields are supported, array elements will be at top-level depth + 1.
-
-        switch (typeId) {
-            case INT32_TYPE:
-                parseInt32(pos, /*depth=*/1, last, /*numAnnotations=*/0);
-                break;
-            case INT64_TYPE:
-                parseInt64(pos, /*depth=*/1, last, /*numAnnotations=*/0);
-                break;
-            case FLOAT_TYPE:
-                parseFloat(pos, /*depth=*/1, last, /*numAnnotations=*/0);
-                break;
-            case BOOL_TYPE:
-                parseBool(pos, /*depth=*/1, last, /*numAnnotations=*/0);
-                break;
-            case STRING_TYPE:
-                parseString(pos, /*depth=*/1, last, /*numAnnotations=*/0);
-                break;
-            default:
-                mValid = false;
-                break;
-        }
-    }
-
-    parseAnnotations(numAnnotations, numElements);
-
-    pos[1] = 1;
-    last[1] = false;
-}
-
 // Assumes that mValues is not empty
 bool LogEvent::checkPreviousValueType(Type expected) {
     return mValues[mValues.size() - 1].mValue.getType() == expected;
 }
 
-void LogEvent::parseIsUidAnnotation(uint8_t annotationType, std::optional<uint8_t> numElements) {
-    // Need to set numElements if not an array.
-    if (!numElements) {
-        numElements = 1;
-    }
-
-    // If array is empty, skip uid parsing.
-    if (numElements == 0 && annotationType == BOOL_TYPE) {
-        readNextValue<uint8_t>();
-        return;
-    }
-
-    // Allowed types: INT, repeated INT
-    if (numElements > mValues.size() || !checkPreviousValueType(INT) ||
-        annotationType != BOOL_TYPE) {
+void LogEvent::parseIsUidAnnotation(uint8_t annotationType) {
+    if (mValues.empty() || mValues.size() - 1 > INT8_MAX || !checkPreviousValueType(INT)
+            || annotationType != BOOL_TYPE) {
         mValid = false;
         return;
     }
 
     bool isUid = readNextValue<uint8_t>();
     if (isUid) {
-        mNumUidFields += numElements.value();
+        mNumUidFields++;
     }
-
-    for (int i = 1; i <= numElements; i++) {
-        mValues[mValues.size() - i].mAnnotations.setUidField(isUid);
-    }
+    mValues[mValues.size() - 1].mAnnotations.setUidField(isUid);
 }
 
 void LogEvent::parseTruncateTimestampAnnotation(uint8_t annotationType) {
@@ -294,11 +262,8 @@
     mTruncateTimestamp = readNextValue<uint8_t>();
 }
 
-void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType,
-                                           std::optional<uint8_t> numElements,
-                                           std::optional<size_t> firstUidInChainIndex) {
-    // Allowed types: all types except for attribution chains and repeated fields.
-    if (mValues.empty() || annotationType != BOOL_TYPE || firstUidInChainIndex || numElements) {
+void LogEvent::parsePrimaryFieldAnnotation(uint8_t annotationType) {
+    if (mValues.empty() || annotationType != BOOL_TYPE) {
         mValid = false;
         return;
     }
@@ -308,42 +273,41 @@
 }
 
 void LogEvent::parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType,
-                                                   std::optional<size_t> firstUidInChainIndex) {
-    // Allowed types: attribution chains
-    if (mValues.empty() || annotationType != BOOL_TYPE || !firstUidInChainIndex) {
+                                                   int firstUidInChainIndex) {
+    if (mValues.empty() || annotationType != BOOL_TYPE || -1 == firstUidInChainIndex) {
         mValid = false;
         return;
     }
 
-    if (mValues.size() < firstUidInChainIndex.value() + 1) {  // AttributionChain is empty.
+    if (static_cast<int>(mValues.size() - 1) < firstUidInChainIndex) { // AttributionChain is empty.
         mValid = false;
         android_errorWriteLog(0x534e4554, "174485572");
         return;
     }
 
     const bool primaryField = readNextValue<uint8_t>();
-    mValues[firstUidInChainIndex.value()].mAnnotations.setPrimaryField(primaryField);
+    mValues[firstUidInChainIndex].mAnnotations.setPrimaryField(primaryField);
 }
 
-void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType,
-                                             std::optional<uint8_t> numElements) {
-    // Allowed types: INT
-    if (mValues.empty() || annotationType != BOOL_TYPE || !checkPreviousValueType(INT) ||
-        numElements) {
+void LogEvent::parseExclusiveStateAnnotation(uint8_t annotationType) {
+    if (mValues.empty() || annotationType != BOOL_TYPE) {
+        mValid = false;
+        return;
+    }
+
+    if (mValues.size() - 1 > INT8_MAX) {
+        android_errorWriteLog(0x534e4554, "174488848");
         mValid = false;
         return;
     }
 
     const bool exclusiveState = readNextValue<uint8_t>();
-    mExclusiveStateFieldIndex = mValues.size() - 1;
-    mValues[getExclusiveStateFieldIndex().value()].mAnnotations.setExclusiveState(exclusiveState);
+    mExclusiveStateFieldIndex = static_cast<int8_t>(mValues.size() - 1);
+    mValues[getExclusiveStateFieldIndex()].mAnnotations.setExclusiveState(exclusiveState);
 }
 
-void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType,
-                                                std::optional<uint8_t> numElements) {
-    // Allowed types: INT
-    if (mValues.empty() || annotationType != INT32_TYPE || !checkPreviousValueType(INT) ||
-        numElements) {
+void LogEvent::parseTriggerStateResetAnnotation(uint8_t annotationType) {
+    if (mValues.empty() || annotationType != INT32_TYPE) {
         mValid = false;
         return;
     }
@@ -351,11 +315,8 @@
     mResetState = readNextValue<int32_t>();
 }
 
-void LogEvent::parseStateNestedAnnotation(uint8_t annotationType,
-                                          std::optional<uint8_t> numElements) {
-    // Allowed types: INT
-    if (mValues.empty() || annotationType != BOOL_TYPE || !checkPreviousValueType(INT) ||
-        numElements) {
+void LogEvent::parseStateNestedAnnotation(uint8_t annotationType) {
+    if (mValues.empty() || annotationType != BOOL_TYPE) {
         mValid = false;
         return;
     }
@@ -366,34 +327,32 @@
 
 // firstUidInChainIndex is a default parameter that is only needed when parsing
 // annotations for attribution chains.
-// numElements is a default param that is only needed when parsing annotations for repeated fields
-void LogEvent::parseAnnotations(uint8_t numAnnotations, std::optional<uint8_t> numElements,
-                                std::optional<size_t> firstUidInChainIndex) {
+void LogEvent::parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex) {
     for (uint8_t i = 0; i < numAnnotations; i++) {
         uint8_t annotationId = readNextValue<uint8_t>();
         uint8_t annotationType = readNextValue<uint8_t>();
 
         switch (annotationId) {
             case ANNOTATION_ID_IS_UID:
-                parseIsUidAnnotation(annotationType, numElements);
+                parseIsUidAnnotation(annotationType);
                 break;
             case ANNOTATION_ID_TRUNCATE_TIMESTAMP:
                 parseTruncateTimestampAnnotation(annotationType);
                 break;
             case ANNOTATION_ID_PRIMARY_FIELD:
-                parsePrimaryFieldAnnotation(annotationType, numElements, firstUidInChainIndex);
+                parsePrimaryFieldAnnotation(annotationType);
                 break;
             case ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID:
                 parsePrimaryFieldFirstUidAnnotation(annotationType, firstUidInChainIndex);
                 break;
             case ANNOTATION_ID_EXCLUSIVE_STATE:
-                parseExclusiveStateAnnotation(annotationType, numElements);
+                parseExclusiveStateAnnotation(annotationType);
                 break;
             case ANNOTATION_ID_TRIGGER_STATE_RESET:
-                parseTriggerStateResetAnnotation(annotationType, numElements);
+                parseTriggerStateResetAnnotation(annotationType);
                 break;
             case ANNOTATION_ID_STATE_NESTED:
-                parseStateNestedAnnotation(annotationType, numElements);
+                parseStateNestedAnnotation(annotationType);
                 break;
             default:
                 mValid = false;
@@ -416,7 +375,7 @@
     if (getTypeId(typeInfo) != OBJECT_TYPE) mValid = false;
 
     uint8_t numElements = readNextValue<uint8_t>();
-    if (numElements < 2 || numElements > INT8_MAX) mValid = false;
+    if (numElements < 2 || numElements > 127) mValid = false;
 
     typeInfo = readNextValue<uint8_t>();
     if (getTypeId(typeInfo) != INT64_TYPE) mValid = false;
@@ -460,9 +419,6 @@
             case ATTRIBUTION_CHAIN_TYPE:
                 parseAttributionChain(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
                 break;
-            case LIST_TYPE:
-                parseArray(pos, /*depth=*/0, last, getNumAnnotations(typeInfo));
-                break;
             case ERROR_TYPE:
                 /* mErrorBitmask =*/ readNextValue<int32_t>();
                 mValid = false;
@@ -627,14 +583,14 @@
     writeFieldValueTreeToStream(mTagId, getValues(), &protoOutput);
 }
 
-bool LogEvent::hasAttributionChain(std::pair<size_t, size_t>* indexRange) const {
-    if (!mAttributionChainStartIndex || !mAttributionChainEndIndex) {
+bool LogEvent::hasAttributionChain(std::pair<int, int>* indexRange) const {
+    if (mAttributionChainStartIndex == -1 || mAttributionChainEndIndex == -1) {
         return false;
     }
 
     if (nullptr != indexRange) {
-        indexRange->first = mAttributionChainStartIndex.value();
-        indexRange->second = mAttributionChainEndIndex.value();
+        indexRange->first = static_cast<int>(mAttributionChainStartIndex);
+        indexRange->second = static_cast<int>(mAttributionChainEndIndex);
     }
 
     return true;
diff --git a/statsd/src/logd/LogEvent.h b/statsd/src/logd/LogEvent.h
index 88dd9b7..92541d7 100644
--- a/statsd/src/logd/LogEvent.h
+++ b/statsd/src/logd/LogEvent.h
@@ -16,49 +16,18 @@
 
 #pragma once
 
+#include "FieldValue.h"
+
 #include <android/util/ProtoOutputStream.h>
 #include <private/android_logger.h>
 
-#include <optional>
 #include <string>
 #include <vector>
 
-#include "FieldValue.h"
-
 namespace android {
 namespace os {
 namespace statsd {
 
-// stats_event.h socket types. Keep in sync.
-/* ERRORS */
-#define ERROR_NO_TIMESTAMP 0x1
-#define ERROR_NO_ATOM_ID 0x2
-#define ERROR_OVERFLOW 0x4
-#define ERROR_ATTRIBUTION_CHAIN_TOO_LONG 0x8
-#define ERROR_TOO_MANY_KEY_VALUE_PAIRS 0x10
-#define ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD 0x20
-#define ERROR_INVALID_ANNOTATION_ID 0x40
-#define ERROR_ANNOTATION_ID_TOO_LARGE 0x80
-#define ERROR_TOO_MANY_ANNOTATIONS 0x100
-#define ERROR_TOO_MANY_FIELDS 0x200
-#define ERROR_INVALID_VALUE_TYPE 0x400
-#define ERROR_STRING_NOT_NULL_TERMINATED 0x800
-#define ERROR_ATOM_ID_INVALID_POSITION 0x2000
-#define ERROR_LIST_TOO_LONG 0x4000
-
-/* TYPE IDS */
-#define INT32_TYPE 0x00
-#define INT64_TYPE 0x01
-#define STRING_TYPE 0x02
-#define LIST_TYPE 0x03
-#define FLOAT_TYPE 0x04
-#define BOOL_TYPE 0x05
-#define BYTE_ARRAY_TYPE 0x06
-#define OBJECT_TYPE 0x07
-#define KEY_VALUE_PAIRS_TYPE 0x08
-#define ATTRIBUTION_CHAIN_TYPE 0x09
-#define ERROR_TYPE 0x0F
-
 struct InstallTrainInfo {
     int64_t trainVersionCode;
     std::string trainName;
@@ -187,20 +156,20 @@
     // Returns whether this LogEvent has an AttributionChain.
     // If it does and indexRange is not a nullptr, populate indexRange with the start and end index
     // of the AttributionChain within mValues.
-    bool hasAttributionChain(std::pair<size_t, size_t>* indexRange = nullptr) const;
+    bool hasAttributionChain(std::pair<int, int>* indexRange = nullptr) const;
 
     // Returns the index of the exclusive state field within the FieldValues vector if
     // an exclusive state exists. If there is no exclusive state field, returns -1.
     //
     // If the index within the atom definition is desired, do the following:
-    //    const std::optional<size_t>& vectorIndex = LogEvent.getExclusiveStateFieldIndex();
-    //    if (!vectorIndex) {
-    //        FieldValue& v = LogEvent.getValues()[vectorIndex.value()];
+    //    int vectorIndex = LogEvent.getExclusiveStateFieldIndex();
+    //    if (vectorIndex != -1) {
+    //        FieldValue& v = LogEvent.getValues()[vectorIndex];
     //        int atomIndex = v.mField.getPosAtDepth(0);
     //    }
     // Note that atomIndex is 1-indexed.
-    inline std::optional<size_t> getExclusiveStateFieldIndex() const {
-        return mExclusiveStateFieldIndex;
+    inline int getExclusiveStateFieldIndex() const {
+        return static_cast<int>(mExclusiveStateFieldIndex);
     }
 
     // If a reset state is not sent in the StatsEvent, returns -1. Note that a
@@ -243,20 +212,15 @@
     void parseByteArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
     void parseKeyValuePairs(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
     void parseAttributionChain(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
-    void parseArray(int32_t* pos, int32_t depth, bool* last, uint8_t numAnnotations);
 
-    void parseAnnotations(uint8_t numAnnotations, std::optional<uint8_t> numElements = std::nullopt,
-                          std::optional<size_t> firstUidInChainIndex = std::nullopt);
-    void parseIsUidAnnotation(uint8_t annotationType, std::optional<uint8_t> numElements);
+    void parseAnnotations(uint8_t numAnnotations, int firstUidInChainIndex = -1);
+    void parseIsUidAnnotation(uint8_t annotationType);
     void parseTruncateTimestampAnnotation(uint8_t annotationType);
-    void parsePrimaryFieldAnnotation(uint8_t annotationType, std::optional<uint8_t> numElements,
-                                     std::optional<size_t> firstUidInChainIndex);
-    void parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType,
-                                             std::optional<size_t> firstUidInChainIndex);
-    void parseExclusiveStateAnnotation(uint8_t annotationType, std::optional<uint8_t> numElements);
-    void parseTriggerStateResetAnnotation(uint8_t annotationType,
-                                          std::optional<uint8_t> numElements);
-    void parseStateNestedAnnotation(uint8_t annotationType, std::optional<uint8_t> numElements);
+    void parsePrimaryFieldAnnotation(uint8_t annotationType);
+    void parsePrimaryFieldFirstUidAnnotation(uint8_t annotationType, int firstUidInChainIndex);
+    void parseExclusiveStateAnnotation(uint8_t annotationType);
+    void parseTriggerStateResetAnnotation(uint8_t annotationType);
+    void parseStateNestedAnnotation(uint8_t annotationType);
     bool checkPreviousValueType(Type expected);
 
     /**
@@ -302,8 +266,10 @@
     template <class T>
     void addToValues(int32_t* pos, int32_t depth, T& value, bool* last) {
         Field f = Field(mTagId, pos, depth);
-        // only decorate last position for depths with repeated fields (depth 1)
-        if (depth > 0 && last[1]) f.decorateLastPos(1);
+        // do not decorate last position at depth 0
+        for (int i = 1; i < depth; i++) {
+            if (last[i]) f.decorateLastPos(i);
+        }
 
         Value v = Value(value);
         mValues.push_back(FieldValue(f, v));
@@ -336,11 +302,13 @@
     bool mTruncateTimestamp = false;
     int mResetState = -1;
 
-    size_t mNumUidFields = 0;
+    uint8_t mNumUidFields = 0;
 
-    std::optional<size_t> mAttributionChainStartIndex;
-    std::optional<size_t> mAttributionChainEndIndex;
-    std::optional<size_t> mExclusiveStateFieldIndex;
+    // Indexes within the FieldValue vector can be stored in 7 bits because
+    // that's the assumption enforced by the encoding used in FieldValue.
+    int8_t mAttributionChainStartIndex = -1;
+    int8_t mAttributionChainEndIndex = -1;
+    int8_t mExclusiveStateFieldIndex = -1;
 };
 
 void writeExperimentIdsToProto(const std::vector<int64_t>& experimentIds, std::vector<uint8_t>* protoOut);
diff --git a/statsd/src/main.cpp b/statsd/src/main.cpp
index 66b4389..01e1e92 100644
--- a/statsd/src/main.cpp
+++ b/statsd/src/main.cpp
@@ -17,19 +17,19 @@
 #define STATSD_DEBUG false  // STOPSHIP if true
 #include "Log.h"
 
+#include "StatsService.h"
+#include "flags/FlagProvider.h"
+#include "socket/StatsSocketListener.h"
+
 #include <android/binder_interface_utils.h>
-#include <android/binder_manager.h>
 #include <android/binder_process.h>
+#include <android/binder_manager.h>
+#include <utils/Looper.h>
+
 #include <stdio.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <utils/Looper.h>
-
-#include "StatsService.h"
-#include "flags/FlagProvider.h"
-#include "packages/UidMap.h"
-#include "socket/StatsSocketListener.h"
 
 using namespace android;
 using namespace android::os::statsd;
@@ -80,12 +80,10 @@
             std::make_shared<LogEventQueue>(4000 /*buffer limit. Buffer is NOT pre-allocated*/);
 
     // Initialize boot flags
-    FlagProvider::getInstance().initBootFlags({OPTIMIZATION_ATOM_MATCHER_MAP_FLAG});
-
-    sp<UidMap> uidMap = UidMap::getInstance();
+    FlagProvider::getInstance().initBootFlags({VALUE_METRIC_SUBSET_DIMENSION_AGGREGATION_FLAG});
 
     // Create the service
-    gStatsService = SharedRefBase::make<StatsService>(uidMap, eventQueue);
+    gStatsService = SharedRefBase::make<StatsService>(looper, eventQueue);
     // TODO(b/149582373): Set DUMP_FLAG_PROTO once libbinder_ndk supports
     // setting dumpsys priorities.
     binder_status_t status = AServiceManager_addService(gStatsService->asBinder().get(), "stats");
diff --git a/statsd/src/matchers/matcher_util.cpp b/statsd/src/matchers/matcher_util.cpp
index 27b9fb2..68c1159 100644
--- a/statsd/src/matchers/matcher_util.cpp
+++ b/statsd/src/matchers/matcher_util.cpp
@@ -237,13 +237,18 @@
         case FieldValueMatcher::ValueMatcherCase::kNeqAnyString: {
             const auto& str_list = matcher.neq_any_string();
             for (int i = start; i < end; i++) {
+                bool notEqAll = true;
                 for (const auto& str : str_list.str_value()) {
                     if (tryMatchString(uidMap, values[i], str)) {
-                        return false;
+                        notEqAll = false;
+                        break;
                     }
                 }
+                if (notEqAll) {
+                    return true;
+                }
             }
-            return true;
+            return false;
         }
         case FieldValueMatcher::ValueMatcherCase::kEqAnyString: {
             const auto& str_list = matcher.eq_any_string();
diff --git a/statsd/src/metrics/CountMetricProducer.cpp b/statsd/src/metrics/CountMetricProducer.cpp
index 67a7250..9e003a2 100644
--- a/statsd/src/metrics/CountMetricProducer.cpp
+++ b/statsd/src/metrics/CountMetricProducer.cpp
@@ -90,7 +90,7 @@
         mContainANYPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
     }
 
-    mShouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
+    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
 
     if (metric.links().size() > 0) {
         for (const auto& link : metric.links()) {
@@ -224,8 +224,8 @@
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
 
-    // Fills the dimension path if not slicing by a primitive repeated field or position ALL.
-    if (!mShouldUseNestedDimensions) {
+    // Fills the dimension path if not slicing by ALL.
+    if (!mSliceByPositionALL) {
         if (!mDimensionsInWhat.empty()) {
             uint64_t dimenPathToken = protoOutput->start(
                     FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
@@ -244,7 +244,7 @@
                 protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
 
         // First fill dimension.
-        if (mShouldUseNestedDimensions) {
+        if (mSliceByPositionALL) {
             uint64_t dimensionToken = protoOutput->start(
                     FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
             writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
diff --git a/statsd/src/metrics/DurationMetricProducer.cpp b/statsd/src/metrics/DurationMetricProducer.cpp
index 5b7a1c1..add5fa4 100644
--- a/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/statsd/src/metrics/DurationMetricProducer.cpp
@@ -117,7 +117,7 @@
         mValid = false;
     }
 
-    mShouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
+    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
 
     if (metric.links().size() > 0) {
         for (const auto& link : metric.links()) {
@@ -507,7 +507,7 @@
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
 
-    if (!mShouldUseNestedDimensions) {
+    if (!mSliceByPositionALL) {
         if (!mDimensionsInWhat.empty()) {
             uint64_t dimenPathToken = protoOutput->start(
                     FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
@@ -528,7 +528,7 @@
                 protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
 
         // First fill dimension.
-        if (mShouldUseNestedDimensions) {
+        if (mSliceByPositionALL) {
             uint64_t dimensionToken = protoOutput->start(
                     FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
             writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
diff --git a/statsd/src/metrics/GaugeMetricProducer.cpp b/statsd/src/metrics/GaugeMetricProducer.cpp
index 4df3e24..b4fbe17 100644
--- a/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -128,7 +128,7 @@
         }
         mConditionSliced = true;
     }
-    mShouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
+    mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what());
 
     flushIfNeededLocked(startTimeNs);
     // Kicks off the puller immediately.
@@ -256,8 +256,8 @@
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
 
-    // Fills the dimension path if not slicing by a primitive repeated field or position ALL.
-    if (!mShouldUseNestedDimensions) {
+    // Fills the dimension path if not slicing by ALL.
+    if (!mSliceByPositionALL) {
         if (!mDimensionsInWhat.empty()) {
             uint64_t dimenPathToken = protoOutput->start(
                     FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
@@ -294,7 +294,7 @@
                 protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
 
         // First fill dimension.
-        if (mShouldUseNestedDimensions) {
+        if (mSliceByPositionALL) {
             uint64_t dimensionToken = protoOutput->start(
                     FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
             writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
diff --git a/statsd/src/metrics/MetricProducer.cpp b/statsd/src/metrics/MetricProducer.cpp
index 17aa312..9a00c87 100644
--- a/statsd/src/metrics/MetricProducer.cpp
+++ b/statsd/src/metrics/MetricProducer.cpp
@@ -66,7 +66,7 @@
       mConditionSliced(false),
       mWizard(wizard),
       mContainANYPositionInDimensionsInWhat(false),
-      mShouldUseNestedDimensions(false),
+      mSliceByPositionALL(false),
       mHasLinksToAllConditionDimensionsInTracker(false),
       mEventActivationMap(eventActivationMap),
       mEventDeactivationMap(eventDeactivationMap),
diff --git a/statsd/src/metrics/MetricProducer.h b/statsd/src/metrics/MetricProducer.h
index 95f8dd4..435287a 100644
--- a/statsd/src/metrics/MetricProducer.h
+++ b/statsd/src/metrics/MetricProducer.h
@@ -520,9 +520,7 @@
 
     bool mContainANYPositionInDimensionsInWhat;
 
-    // Metrics slicing by primitive repeated field and/or position ALL need to use nested
-    // dimensions.
-    bool mShouldUseNestedDimensions;
+    bool mSliceByPositionALL;
 
     vector<Matcher> mDimensionsInWhat;  // The dimensions_in_what defined in statsd_config
 
diff --git a/statsd/src/metrics/MetricsManager.cpp b/statsd/src/metrics/MetricsManager.cpp
index d192476..4e577e1 100644
--- a/statsd/src/metrics/MetricsManager.cpp
+++ b/statsd/src/metrics/MetricsManager.cpp
@@ -23,7 +23,6 @@
 #include "CountMetricProducer.h"
 #include "condition/CombinationConditionTracker.h"
 #include "condition/SimpleConditionTracker.h"
-#include "flags/FlagProvider.h"
 #include "guardrail/StatsdStats.h"
 #include "matchers/CombinationAtomMatchingTracker.h"
 #include "matchers/SimpleAtomMatchingTracker.h"
@@ -76,20 +75,18 @@
       mPullerManager(pullerManager),
       mWhitelistedAtomIds(config.whitelisted_atom_ids().begin(),
                           config.whitelisted_atom_ids().end()),
-      mShouldPersistHistory(config.persist_locally()),
-      mAtomMatcherOptimizationEnabled(FlagProvider::getInstance().getBootFlagBool(
-              OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, FLAG_FALSE)) {
+      mShouldPersistHistory(config.persist_locally()) {
     // Init the ttl end timestamp.
     refreshTtl(timeBaseNs);
 
     mConfigValid = initStatsdConfig(
             key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseNs, currentTimeNs, mTagIdsToMatchersMap, mAllAtomMatchingTrackers,
-            mAtomMatchingTrackerMap, mAllConditionTrackers, mConditionTrackerMap,
-            mAllMetricProducers, mMetricProducerMap, mAllAnomalyTrackers, mAllPeriodicAlarmTrackers,
-            mConditionToMetricMap, mTrackerToMetricMap, mTrackerToConditionMap,
-            mActivationAtomTrackerToMetricMap, mDeactivationAtomTrackerToMetricMap,
-            mAlertTrackerMap, mMetricIndexesWithActivation, mStateProtoHashes, mNoReportMetricIds);
+            timeBaseNs, currentTimeNs, mTagIds, mAllAtomMatchingTrackers, mAtomMatchingTrackerMap,
+            mAllConditionTrackers, mConditionTrackerMap, mAllMetricProducers, mMetricProducerMap,
+            mAllAnomalyTrackers, mAllPeriodicAlarmTrackers, mConditionToMetricMap,
+            mTrackerToMetricMap, mTrackerToConditionMap, mActivationAtomTrackerToMetricMap,
+            mDeactivationAtomTrackerToMetricMap, mAlertTrackerMap, mMetricIndexesWithActivation,
+            mStateProtoHashes, mNoReportMetricIds);
 
     mHashStringsInReport = config.hash_strings_in_metric_report();
     mVersionStringsInReport = config.version_strings_in_metric_report();
@@ -131,7 +128,7 @@
     vector<sp<AnomalyTracker>> newAnomalyTrackers;
     unordered_map<int64_t, int> newAlertTrackerMap;
     vector<sp<AlarmTracker>> newPeriodicAlarmTrackers;
-    mTagIdsToMatchersMap.clear();
+    mTagIds.clear();
     mConditionToMetricMap.clear();
     mTrackerToMetricMap.clear();
     mTrackerToConditionMap.clear();
@@ -143,7 +140,7 @@
             mConfigKey, config, mUidMap, mPullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
             timeBaseNs, currentTimeNs, mAllAtomMatchingTrackers, mAtomMatchingTrackerMap,
             mAllConditionTrackers, mConditionTrackerMap, mAllMetricProducers, mMetricProducerMap,
-            mAllAnomalyTrackers, mAlertTrackerMap, mStateProtoHashes, mTagIdsToMatchersMap,
+            mAllAnomalyTrackers, mAlertTrackerMap, mStateProtoHashes, mTagIds,
             newAtomMatchingTrackers, newAtomMatchingTrackerMap, newConditionTrackers,
             newConditionTrackerMap, newMetricProducers, newMetricProducerMap, newAnomalyTrackers,
             newAlertTrackerMap, newPeriodicAlarmTrackers, mConditionToMetricMap,
@@ -559,9 +556,7 @@
 
     mIsActive = isActive || !activeMetricsIndices.empty();
 
-    const auto matchersIt = mTagIdsToMatchersMap.find(tagId);
-
-    if (matchersIt == mTagIdsToMatchersMap.end()) {
+    if (mTagIds.find(tagId) == mTagIds.end()) {
         // Not interesting...
         return;
     }
@@ -569,16 +564,9 @@
     vector<MatchingState> matcherCache(mAllAtomMatchingTrackers.size(),
                                        MatchingState::kNotComputed);
 
-    if (mAtomMatcherOptimizationEnabled) {
-        for (const auto& matcherIndex : matchersIt->second) {
-            mAllAtomMatchingTrackers[matcherIndex]->onLogEvent(event, mAllAtomMatchingTrackers,
-                                                               matcherCache);
-        }
-    } else {
-        //  Evaluate all atom matchers.
-        for (auto& matcher : mAllAtomMatchingTrackers) {
-            matcher->onLogEvent(event, mAllAtomMatchingTrackers, matcherCache);
-        }
+    // Evaluate all atom matchers.
+    for (auto& matcher : mAllAtomMatchingTrackers) {
+        matcher->onLogEvent(event, mAllAtomMatchingTrackers, matcherCache);
     }
 
     // Set of metrics that received an activation cancellation.
diff --git a/statsd/src/metrics/MetricsManager.h b/statsd/src/metrics/MetricsManager.h
index 1eccf8d..4600ae1 100644
--- a/statsd/src/metrics/MetricsManager.h
+++ b/statsd/src/metrics/MetricsManager.h
@@ -216,10 +216,8 @@
 
     bool mShouldPersistHistory;
 
-    const bool mAtomMatcherOptimizationEnabled;
-
-    // All event tags that are interesting to config metrics matchers.
-    std::unordered_map<int, std::vector<int>> mTagIdsToMatchersMap;
+    // All event tags that are interesting to my metrics.
+    std::set<int> mTagIds;
 
     // We only store the sp of AtomMatchingTracker, MetricProducer, and ConditionTracker in
     // MetricsManager. There are relationships between them, and the relationships are denoted by
@@ -258,7 +256,7 @@
     // To make the log processing more efficient, we want to do as much filtering as possible
     // before we go into individual trackers and conditions to match.
 
-    // 1st filter: check if the event tag id is in mTagIdsToMatchersMap.
+    // 1st filter: check if the event tag id is in mTagIds.
     // 2nd filter: if it is, we parse the event because there is at least one member is interested.
     //             then pass to all AtomMatchingTrackers (itself also filter events by ids).
     // 3nd filter: for AtomMatchingTrackers that matched this event, we pass this event to the
@@ -347,8 +345,6 @@
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithSameDeactivation);
     FRIEND_TEST(MetricActivationE2eTest, TestCountMetricWithTwoMetricsTwoDeactivations);
 
-    FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagFalse);
-    FRIEND_TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagTrue);
     FRIEND_TEST(MetricsManagerTest, TestLogSources);
     FRIEND_TEST(MetricsManagerTest, TestLogSourcesOnConfigUpdate);
 
diff --git a/statsd/src/metrics/NumericValueMetricProducer.cpp b/statsd/src/metrics/NumericValueMetricProducer.cpp
index 703b07b..f2e93f1 100644
--- a/statsd/src/metrics/NumericValueMetricProducer.cpp
+++ b/statsd/src/metrics/NumericValueMetricProducer.cpp
@@ -22,6 +22,7 @@
 #include <limits.h>
 #include <stdlib.h>
 
+#include "flags/FlagProvider.h"
 #include "guardrail/StatsdStats.h"
 #include "metrics/parsing_utils/metrics_manager_util.h"
 #include "stats_log_util.h"
@@ -253,9 +254,9 @@
     }
 
     mMatchedMetricDimensionKeys.clear();
-    if (mUseDiff) {
-        // An extra aggregation step is needed to sum values with matching dimensions
-        // before calculating the diff between sums of consecutive pulls.
+    if (FlagProvider::getInstance().getBootFlagBool(VALUE_METRIC_SUBSET_DIMENSION_AGGREGATION_FLAG,
+                                                    FLAG_FALSE) &&
+        mUseDiff) {
         std::unordered_map<HashableDimensionKey, pair<LogEvent, vector<int>>> aggregateEvents;
         for (const auto& data : allData) {
             if (mEventMatcherWizard->matchLogEvent(*data, mWhatMatcherIndex) !=
diff --git a/statsd/src/metrics/NumericValueMetricProducer.h b/statsd/src/metrics/NumericValueMetricProducer.h
index 8eca3f8..542975d 100644
--- a/statsd/src/metrics/NumericValueMetricProducer.h
+++ b/statsd/src/metrics/NumericValueMetricProducer.h
@@ -264,7 +264,7 @@
     FRIEND_TEST(NumericValueMetricProducerTest_ConditionCorrection, TestThresholdUploadSkip);
     FRIEND_TEST(NumericValueMetricProducerTest_ConditionCorrection, TestLateStateChangeSlicedAtoms);
 
-    FRIEND_TEST(NumericValueMetricProducerTest, TestSubsetDimensions);
+    FRIEND_TEST(NumericValueMetricProducerTest_SubsetDimensions, TestSubsetDimensions_FlagTrue);
 
     FRIEND_TEST(ConfigUpdateTest, TestUpdateValueMetrics);
 
diff --git a/statsd/src/metrics/ValueMetricProducer.cpp b/statsd/src/metrics/ValueMetricProducer.cpp
index 50958ca..dccdbef 100644
--- a/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/statsd/src/metrics/ValueMetricProducer.cpp
@@ -101,7 +101,7 @@
         translateFieldMatcher(whatOptions.dimensionsInWhat, &mDimensionsInWhat);
     }
     mContainANYPositionInDimensionsInWhat = whatOptions.containsAnyPositionInDimensionsInWhat;
-    mShouldUseNestedDimensions = whatOptions.shouldUseNestedDimensions;
+    mSliceByPositionALL = whatOptions.sliceByPositionAll;
 
     if (conditionOptions.conditionLinks.size() > 0) {
         for (const auto& link : conditionOptions.conditionLinks) {
@@ -324,8 +324,8 @@
     }
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_TIME_BASE, (long long)mTimeBaseNs);
     protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_SIZE, (long long)mBucketSizeNs);
-    // Fills the dimension path if not slicing by a primitive repeated field or position ALL.
-    if (!mShouldUseNestedDimensions) {
+    // Fills the dimension path if not slicing by ALL.
+    if (!mSliceByPositionALL) {
         if (!mDimensionsInWhat.empty()) {
             uint64_t dimenPathToken =
                     protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
@@ -364,7 +364,7 @@
                 protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_DATA);
 
         // First fill dimension.
-        if (mShouldUseNestedDimensions) {
+        if (mSliceByPositionALL) {
             uint64_t dimensionToken =
                     protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
             writeDimensionToProto(metricDimensionKey.getDimensionKeyInWhat(), strSet, protoOutput);
diff --git a/statsd/src/metrics/ValueMetricProducer.h b/statsd/src/metrics/ValueMetricProducer.h
index 956580a..6a9b931 100644
--- a/statsd/src/metrics/ValueMetricProducer.h
+++ b/statsd/src/metrics/ValueMetricProducer.h
@@ -83,7 +83,7 @@
 
     struct WhatOptions {
         const bool containsAnyPositionInDimensionsInWhat;
-        const bool shouldUseNestedDimensions;
+        const bool sliceByPositionAll;
         const int whatMatcherIndex;
         const sp<EventMatcherWizard>& matcherWizard;
         const FieldMatcher& dimensionsInWhat;
diff --git a/statsd/src/metrics/parsing_utils/config_update_utils.cpp b/statsd/src/metrics/parsing_utils/config_update_utils.cpp
index e65e4bc..c0a1efa 100644
--- a/statsd/src/metrics/parsing_utils/config_update_utils.cpp
+++ b/statsd/src/metrics/parsing_utils/config_update_utils.cpp
@@ -110,7 +110,7 @@
 bool updateAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
                                 const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
                                 const vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-                                std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
+                                set<int>& allTagIds,
                                 unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
                                 vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
                                 set<int64_t>& replacedMatchers) {
@@ -182,29 +182,14 @@
     }
 
     std::fill(cycleTracker.begin(), cycleTracker.end(), false);
-    for (size_t matcherIndex = 0; matcherIndex < newAtomMatchingTrackers.size(); matcherIndex++) {
-        auto& matcher = newAtomMatchingTrackers[matcherIndex];
+    for (auto& matcher : newAtomMatchingTrackers) {
         if (!matcher->init(matcherProtos, newAtomMatchingTrackers, newAtomMatchingTrackerMap,
                            cycleTracker)) {
             return false;
         }
-
         // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
         const set<int>& tagIds = matcher->getAtomIds();
-        for (int atomId : tagIds) {
-            auto& matchers = allTagIdsToMatchersMap[atomId];
-            // Performance note:
-            // For small amount of elements linear search in vector will be
-            // faster then look up in a set:
-            // - we do not expect matchers vector per atom id will have significant size (< 10)
-            // - iteration via vector is the fastest way compared to other containers (set, etc.)
-            //   in the hot path MetricsManager::onLogEvent()
-            // - vector<T> will have the smallest memory footprint compared to any other
-            //   std containers implementation
-            if (find(matchers.begin(), matchers.end(), matcherIndex) == matchers.end()) {
-                matchers.push_back(matcherIndex);
-            }
-        }
+        allTagIds.insert(tagIds.begin(), tagIds.end());
     }
 
     return true;
@@ -1115,8 +1100,7 @@
                         const unordered_map<int64_t, int>& oldMetricProducerMap,
                         const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
                         const unordered_map<int64_t, int>& oldAlertTrackerMap,
-                        const map<int64_t, uint64_t>& oldStateProtoHashes,
-                        std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
+                        const map<int64_t, uint64_t>& oldStateProtoHashes, set<int>& allTagIds,
                         vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
                         unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
                         vector<sp<ConditionTracker>>& newConditionTrackers,
@@ -1149,9 +1133,8 @@
     }
 
     if (!updateAtomMatchingTrackers(config, uidMap, oldAtomMatchingTrackerMap,
-                                    oldAtomMatchingTrackers, allTagIdsToMatchersMap,
-                                    newAtomMatchingTrackerMap, newAtomMatchingTrackers,
-                                    replacedMatchers)) {
+                                    oldAtomMatchingTrackers, allTagIds, newAtomMatchingTrackerMap,
+                                    newAtomMatchingTrackers, replacedMatchers)) {
         ALOGE("updateAtomMatchingTrackers failed");
         return false;
     }
diff --git a/statsd/src/metrics/parsing_utils/config_update_utils.h b/statsd/src/metrics/parsing_utils/config_update_utils.h
index f311661..24f8c85 100644
--- a/statsd/src/metrics/parsing_utils/config_update_utils.h
+++ b/statsd/src/metrics/parsing_utils/config_update_utils.h
@@ -58,14 +58,14 @@
 // [oldAtomMatchingTrackerMap]: existing matcher id to index mapping
 // [oldAtomMatchingTrackers]: stores the existing AtomMatchingTrackers
 // output:
-// [allTagIdsToMatchersMap]: maps of tag ids to atom matchers
+// [allTagIds]: contains the set of all interesting tag ids to this config.
 // [newAtomMatchingTrackerMap]: new matcher id to index mapping
 // [newAtomMatchingTrackers]: stores the new AtomMatchingTrackers
 // [replacedMatchers]: set of matcher ids that changed and have been replaced
 bool updateAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
                                 const std::unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
                                 const std::vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
-                                std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
+                                std::set<int>& allTagIds,
                                 std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
                                 std::vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
                                 std::set<int64_t>& replacedMatchers);
@@ -243,7 +243,7 @@
                         const std::vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
                         const std::unordered_map<int64_t, int>& oldAlertTrackerMap,
                         const std::map<int64_t, uint64_t>& oldStateProtoHashes,
-                        std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
+                        std::set<int>& allTagIds,
                         std::vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
                         std::unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
                         std::vector<sp<ConditionTracker>>& newConditionTrackers,
diff --git a/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp b/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
index 915c4ae..0073c92 100644
--- a/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
+++ b/statsd/src/metrics/parsing_utils/metrics_manager_util.cpp
@@ -655,11 +655,6 @@
         ALOGE("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
         return nullopt;
     }
-    if (HasPositionALL(metric.value_field())) {
-        ALOGE("value field with position ALL is not supported. ValueMetric \"%lld\"",
-              (long long)metric.id());
-        return nullopt;
-    }
     std::vector<Matcher> fieldMatchers;
     translateFieldMatcher(metric.value_field(), &fieldMatchers);
     if (fieldMatchers.size() < 1) {
@@ -733,7 +728,7 @@
             MillisToNano(TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), bucketSizeTimeUnit));
 
     const bool containsAnyPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
-    const bool shouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
+    const bool sliceByPositionAll = HasPositionALL(metric.dimensions_in_what());
 
     const auto [dimensionSoftLimit, dimensionHardLimit] =
             StatsdStats::getAtomDimensionKeySizeLimits(pullTagId);
@@ -748,8 +743,8 @@
             key, metric, metricHash, {pullTagId, pullerManager},
             {timeBaseNs, currentTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
              conditionCorrectionThresholdNs, getAppUpgradeBucketSplit(metric)},
-            {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions, trackerIndex,
-             matcherWizard, metric.dimensions_in_what(), fieldMatchers},
+            {containsAnyPositionInDimensionsInWhat, sliceByPositionAll, trackerIndex, matcherWizard,
+             metric.dimensions_in_what(), fieldMatchers},
             {conditionIndex, metric.links(), initialConditionCache, wizard},
             {metric.state_link(), slicedStateAtoms, stateGroupMap},
             {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit});
@@ -781,11 +776,6 @@
         ALOGE("cannot find \"kll_field\" in KllMetric \"%lld\"", (long long)metric.id());
         return nullopt;
     }
-    if (HasPositionALL(metric.kll_field())) {
-        ALOGE("kll field with position ALL is not supported. KllMetric \"%lld\"",
-              (long long)metric.id());
-        return nullopt;
-    }
     std::vector<Matcher> fieldMatchers;
     translateFieldMatcher(metric.kll_field(), &fieldMatchers);
     if (fieldMatchers.empty()) {
@@ -855,7 +845,7 @@
             MillisToNano(TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), bucketSizeTimeUnit));
 
     const bool containsAnyPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
-    const bool shouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
+    const bool sliceByPositionAll = HasPositionALL(metric.dimensions_in_what());
 
     sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
     const int atomTagId = *(atomMatcher->getAtomIds().begin());
@@ -866,8 +856,8 @@
             key, metric, metricHash, {/*pullTagId=*/-1, pullerManager},
             {timeBaseNs, currentTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
              /*conditionCorrectionThresholdNs=*/nullopt, getAppUpgradeBucketSplit(metric)},
-            {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions, trackerIndex,
-             matcherWizard, metric.dimensions_in_what(), fieldMatchers},
+            {containsAnyPositionInDimensionsInWhat, sliceByPositionAll, trackerIndex, matcherWizard,
+             metric.dimensions_in_what(), fieldMatchers},
             {conditionIndex, metric.links(), initialConditionCache, wizard},
             {metric.state_link(), slicedStateAtoms, stateGroupMap},
             {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit});
@@ -1024,7 +1014,7 @@
 bool initAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
                               unordered_map<int64_t, int>& atomMatchingTrackerMap,
                               vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                              unordered_map<int, vector<int>>& allTagIdsToMatchersMap) {
+                              set<int>& allTagIds) {
     vector<AtomMatcher> matcherConfigs;
     const int atomMatcherCount = config.atom_matcher_size();
     matcherConfigs.reserve(atomMatcherCount);
@@ -1046,31 +1036,15 @@
     }
 
     vector<bool> stackTracker2(allAtomMatchingTrackers.size(), false);
-    for (size_t matcherIndex = 0; matcherIndex < allAtomMatchingTrackers.size(); matcherIndex++) {
-        auto& matcher = allAtomMatchingTrackers[matcherIndex];
+    for (auto& matcher : allAtomMatchingTrackers) {
         if (!matcher->init(matcherConfigs, allAtomMatchingTrackers, atomMatchingTrackerMap,
                            stackTracker2)) {
             return false;
         }
-
         // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
         const set<int>& tagIds = matcher->getAtomIds();
-        for (int atomId : tagIds) {
-            auto& matchers = allTagIdsToMatchersMap[atomId];
-            // Performance note:
-            // For small amount of elements linear search in vector will be
-            // faster then look up in a set:
-            // - we do not expect matchers vector per atom id will have significant size (< 10)
-            // - iteration via vector is the fastest way compared to other containers (set, etc.)
-            //   in the hot path MetricsManager::onLogEvent()
-            // - vector<T> will have the smallest memory footprint compared to any other
-            //   std containers implementation
-            if (find(matchers.begin(), matchers.end(), matcherIndex) == matchers.end()) {
-                matchers.push_back(matcherIndex);
-            }
-        }
+        allTagIds.insert(tagIds.begin(), tagIds.end());
     }
-
     return true;
 }
 
@@ -1368,8 +1342,7 @@
                       const sp<StatsPullerManager>& pullerManager,
                       const sp<AlarmMonitor>& anomalyAlarmMonitor,
                       const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                      const int64_t currentTimeNs,
-                      std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
+                      const int64_t currentTimeNs, set<int>& allTagIds,
                       vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
                       unordered_map<int64_t, int>& atomMatchingTrackerMap,
                       vector<sp<ConditionTracker>>& allConditionTrackers,
@@ -1397,7 +1370,7 @@
     }
 
     if (!initAtomMatchingTrackers(config, uidMap, atomMatchingTrackerMap, allAtomMatchingTrackers,
-                                  allTagIdsToMatchersMap)) {
+                                  allTagIds)) {
         ALOGE("initAtomMatchingTrackers failed");
         return false;
     }
diff --git a/statsd/src/metrics/parsing_utils/metrics_manager_util.h b/statsd/src/metrics/parsing_utils/metrics_manager_util.h
index 17e4b66..47306d4 100644
--- a/statsd/src/metrics/parsing_utils/metrics_manager_util.h
+++ b/statsd/src/metrics/parsing_utils/metrics_manager_util.h
@@ -258,11 +258,11 @@
 // output:
 // [atomMatchingTrackerMap]: this map should contain matcher name to index mapping
 // [allAtomMatchingTrackers]: should store the sp to all the AtomMatchingTracker
-// [allTagIdsToMatchersMap]: maps of tag ids to atom matchers
+// [allTagIds]: contains the set of all interesting tag ids to this config.
 bool initAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
                               std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
                               std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
-                              std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap);
+                              std::set<int>& allTagIds);
 
 // Initialize ConditionTrackers
 // input:
@@ -340,8 +340,7 @@
                       const sp<StatsPullerManager>& pullerManager,
                       const sp<AlarmMonitor>& anomalyAlarmMonitor,
                       const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
-                      const int64_t currentTimeNs,
-                      std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
+                      const int64_t currentTimeNs, std::set<int>& allTagIds,
                       std::vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
                       std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
                       std::vector<sp<ConditionTracker>>& allConditionTrackers,
diff --git a/statsd/src/state/StateManager.h b/statsd/src/state/StateManager.h
index 8437279..18c404c 100644
--- a/statsd/src/state/StateManager.h
+++ b/statsd/src/state/StateManager.h
@@ -35,7 +35,7 @@
  * This class is NOT thread safe.
  * It should only be used while StatsLogProcessor's lock is held.
  */
-class StateManager {
+class StateManager : public virtual RefBase {
 public:
     StateManager();
 
diff --git a/statsd/src/state/StateTracker.cpp b/statsd/src/state/StateTracker.cpp
index ebba22a..719ff3f 100644
--- a/statsd/src/state/StateTracker.cpp
+++ b/statsd/src/state/StateTracker.cpp
@@ -176,13 +176,13 @@
 }
 
 bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output) {
-    const std::optional<size_t>& exclusiveStateFieldIndex = event.getExclusiveStateFieldIndex();
-    if (!exclusiveStateFieldIndex) {
+    const int exclusiveStateFieldIndex = event.getExclusiveStateFieldIndex();
+    if (-1 == exclusiveStateFieldIndex) {
         ALOGE("error extracting state from log event. Missing exclusive state field.");
         return false;
     }
 
-    *output = event.getValues()[exclusiveStateFieldIndex.value()];
+    *output = event.getValues()[exclusiveStateFieldIndex];
     return true;
 }
 
diff --git a/statsd/src/stats_log_util.cpp b/statsd/src/stats_log_util.cpp
index 65eecaa..801c081 100644
--- a/statsd/src/stats_log_util.cpp
+++ b/statsd/src/stats_log_util.cpp
@@ -103,7 +103,7 @@
 namespace {
 
 void writeDimensionToProtoHelper(const std::vector<FieldValue>& dims, size_t* index, int depth,
-                                 int prefix, std::set<string>* str_set,
+                                 int prefix, std::set<string> *str_set,
                                  ProtoOutputStream* protoOutput) {
     size_t count = dims.size();
     while (*index < count) {
@@ -116,9 +116,7 @@
             return;
         }
 
-        // If valueDepth == 1, we're writing a repeated field. Use fieldNum at depth 0 instead
-        // of valueDepth.
-        if ((depth == valueDepth || valueDepth == 1) && valuePrefix == prefix) {
+        if (depth == valueDepth && valuePrefix == prefix) {
             uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                                                  DIMENSIONS_VALUE_TUPLE_VALUE);
             protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
@@ -141,8 +139,9 @@
                                            dim.mValue.str_value);
                     } else {
                         str_set->insert(dim.mValue.str_value);
-                        protoOutput->write(FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
-                                           (long long)Hash64(dim.mValue.str_value));
+                        protoOutput->write(
+                                FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
+                                (long long)Hash64(dim.mValue.str_value));
                     }
                     break;
                 default:
@@ -152,10 +151,10 @@
                 protoOutput->end(token);
             }
             (*index)++;
-        } else if (valueDepth == depth + 2 && valuePrefix == prefix) {
+        } else if (valueDepth > depth && valuePrefix == prefix) {
             // Writing the sub tree
-            uint64_t dimensionToken = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
-                                                         DIMENSIONS_VALUE_TUPLE_VALUE);
+            uint64_t dimensionToken = protoOutput->start(
+                    FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
             protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
             uint64_t tupleToken =
                     protoOutput->start(FIELD_TYPE_MESSAGE | DIMENSIONS_VALUE_VALUE_TUPLE);
@@ -171,8 +170,9 @@
 }
 
 void writeDimensionLeafToProtoHelper(const std::vector<FieldValue>& dims,
-                                     const int dimensionLeafField, size_t* index, int depth,
-                                     int prefix, std::set<string>* str_set,
+                                     const int dimensionLeafField,
+                                     size_t* index, int depth,
+                                     int prefix, std::set<string> *str_set,
                                      ProtoOutputStream* protoOutput) {
     size_t count = dims.size();
     while (*index < count) {
@@ -184,8 +184,7 @@
             return;
         }
 
-        // If valueDepth == 1, we're writing a repeated field.
-        if ((depth == valueDepth || valueDepth == 1) && valuePrefix == prefix) {
+        if (depth == valueDepth && valuePrefix == prefix) {
             uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                                                 dimensionLeafField);
             switch (dim.mValue.getType()) {
@@ -207,8 +206,9 @@
                                            dim.mValue.str_value);
                     } else {
                         str_set->insert(dim.mValue.str_value);
-                        protoOutput->write(FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
-                                           (long long)Hash64(dim.mValue.str_value));
+                        protoOutput->write(
+                                FIELD_TYPE_UINT64 | DIMENSIONS_VALUE_VALUE_STR_HASH,
+                                (long long)Hash64(dim.mValue.str_value));
                     }
                     break;
                 default:
@@ -218,7 +218,7 @@
                 protoOutput->end(token);
             }
             (*index)++;
-        } else if (valueDepth == depth + 2 && valuePrefix == prefix) {
+        } else if (valueDepth > depth && valuePrefix == prefix) {
             writeDimensionLeafToProtoHelper(dims, dimensionLeafField,
                                             index, valueDepth, dim.mField.getPrefix(valueDepth),
                                             str_set, protoOutput);
@@ -243,7 +243,7 @@
             return;
         }
 
-        if ((depth == valueDepth || valueDepth == 1) && valuePrefix == prefix) {
+        if (depth == valueDepth && valuePrefix == prefix) {
             uint64_t token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED |
                                                  DIMENSIONS_VALUE_TUPLE_VALUE);
             protoOutput->write(FIELD_TYPE_INT32 | DIMENSIONS_VALUE_FIELD, fieldNum);
@@ -251,7 +251,7 @@
                 protoOutput->end(token);
             }
             (*index)++;
-        } else if (valueDepth == depth + 2 && valuePrefix == prefix) {
+        } else if (valueDepth > depth && valuePrefix == prefix) {
             // Writing the sub tree
             uint64_t dimensionToken = protoOutput->start(
                     FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | DIMENSIONS_VALUE_TUPLE_VALUE);
@@ -312,8 +312,8 @@
 // Supported Atoms format
 // XYZ_Atom {
 //     repeated SubMsg field_1 = 1;
-//     repeated int32/float/string/int64 field_2 = 2;
-//     optional int32/float/string/int64 field_3 = 3;
+//     SubMsg2 field_2 = 2;
+//     int32/float/string/int63 field_3 = 3;
 // }
 // logd's msg format, doesn't allow us to distinguish between the 2 cases below
 // Case (1):
@@ -344,31 +344,25 @@
         const int valueDepth = dim.mField.getDepth();
         const int valuePrefix = dim.mField.getPrefix(depth);
         const int fieldNum = dim.mField.getPosAtDepth(depth);
-        const uint64_t repeatedFieldMask = (valueDepth == 1) ? FIELD_COUNT_REPEATED : 0;
         if (valueDepth > 2) {
             ALOGE("Depth > 2 not supported");
             return;
         }
 
-        // If valueDepth == 1, we're writing a repeated field. Use fieldNum at depth 0 instead
-        // of valueDepth.
-        if ((depth == valueDepth || valueDepth == 1) && valuePrefix == prefix) {
+        if (depth == valueDepth && valuePrefix == prefix) {
             switch (dim.mValue.getType()) {
                 case INT:
-                    protoOutput->write(FIELD_TYPE_INT32 | repeatedFieldMask | fieldNum,
-                                       dim.mValue.int_value);
+                    protoOutput->write(FIELD_TYPE_INT32 | fieldNum, dim.mValue.int_value);
                     break;
                 case LONG:
-                    protoOutput->write(FIELD_TYPE_INT64 | repeatedFieldMask | fieldNum,
+                    protoOutput->write(FIELD_TYPE_INT64 | fieldNum,
                                        (long long)dim.mValue.long_value);
                     break;
                 case FLOAT:
-                    protoOutput->write(FIELD_TYPE_FLOAT | repeatedFieldMask | fieldNum,
-                                       dim.mValue.float_value);
+                    protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
                     break;
                 case STRING: {
-                    protoOutput->write(FIELD_TYPE_STRING | repeatedFieldMask | fieldNum,
-                                       dim.mValue.str_value);
+                    protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
                     break;
                 }
                 case STORAGE:
@@ -380,10 +374,15 @@
                     break;
             }
             (*index)++;
-        } else if (valueDepth == depth + 2 && valuePrefix == prefix) {
+        } else if (valueDepth > depth && valuePrefix == prefix) {
             // Writing the sub tree
             uint64_t msg_token = 0ULL;
-            msg_token = protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | fieldNum);
+            if (valueDepth == depth + 2) {
+                msg_token =
+                        protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | fieldNum);
+            } else if (valueDepth == depth + 1) {
+                msg_token = protoOutput->start(FIELD_TYPE_MESSAGE | fieldNum);
+            }
             // Directly jump to the leaf value because the repeated position field is implied
             // by the position of the sub msg in the parent field.
             writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth,
diff --git a/statsd/tests/FieldValue_test.cpp b/statsd/tests/FieldValue_test.cpp
index ff3e54a..f4ac8e5 100644
--- a/statsd/tests/FieldValue_test.cpp
+++ b/statsd/tests/FieldValue_test.cpp
@@ -34,7 +34,6 @@
 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) {
@@ -60,14 +59,6 @@
 
     parseStatsEventToLogEvent(statsEvent, logEvent);
 }
-
-void makeRepeatedIntLogEvent(LogEvent* logEvent, const int32_t atomId,
-                             const vector<int>& intArray) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_writeInt32Array(statsEvent, intArray.data(), intArray.size());
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
 }  // anonymous namespace
 
 TEST(AtomMatcherTest, TestFieldTranslation) {
@@ -157,76 +148,6 @@
     EXPECT_EQ("some value", output.getValues()[6].mValue.str_value);
 }
 
-TEST(AtomMatcherTest, TestFilterRepeated_FIRST) {
-    FieldMatcher matcher;
-    matcher.set_field(123);
-    FieldMatcher* child = matcher.add_child();
-    child->set_field(1);
-    child->set_position(Position::FIRST);
-
-    vector<Matcher> matchers;
-    translateFieldMatcher(matcher, &matchers);
-
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<int> intArray = {21, 9, 13};
-    makeRepeatedIntLogEvent(&event, 123, intArray);
-
-    HashableDimensionKey output;
-    EXPECT_TRUE(filterValues(matchers, event.getValues(), &output));
-
-    ASSERT_EQ((size_t)1, output.getValues().size());
-    EXPECT_EQ((int32_t)0x01010100, output.getValues()[0].mField.getField());
-    EXPECT_EQ((int32_t)21, output.getValues()[0].mValue.int_value);
-}
-
-TEST(AtomMatcherTest, TestFilterRepeated_LAST) {
-    FieldMatcher matcher;
-    matcher.set_field(123);
-    FieldMatcher* child = matcher.add_child();
-    child->set_field(1);
-    child->set_position(Position::LAST);
-
-    vector<Matcher> matchers;
-    translateFieldMatcher(matcher, &matchers);
-
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<int> intArray = {21, 9, 13};
-    makeRepeatedIntLogEvent(&event, 123, intArray);
-
-    HashableDimensionKey output;
-    EXPECT_TRUE(filterValues(matchers, event.getValues(), &output));
-
-    ASSERT_EQ((size_t)1, output.getValues().size());
-    EXPECT_EQ((int32_t)0x01018000, output.getValues()[0].mField.getField());
-    EXPECT_EQ((int32_t)13, output.getValues()[0].mValue.int_value);
-}
-
-TEST(AtomMatcherTest, TestFilterRepeated_ALL) {
-    FieldMatcher matcher;
-    matcher.set_field(123);
-    FieldMatcher* child = matcher.add_child();
-    child->set_field(1);
-    child->set_position(Position::ALL);
-
-    vector<Matcher> matchers;
-    translateFieldMatcher(matcher, &matchers);
-
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<int> intArray = {21, 9, 13};
-    makeRepeatedIntLogEvent(&event, 123, intArray);
-
-    HashableDimensionKey output;
-    EXPECT_TRUE(filterValues(matchers, event.getValues(), &output));
-
-    ASSERT_EQ((size_t)3, output.getValues().size());
-    EXPECT_EQ((int32_t)0x01010100, output.getValues()[0].mField.getField());
-    EXPECT_EQ((int32_t)21, output.getValues()[0].mValue.int_value);
-    EXPECT_EQ((int32_t)0x01010200, output.getValues()[1].mField.getField());
-    EXPECT_EQ((int32_t)9, output.getValues()[1].mValue.int_value);
-    EXPECT_EQ((int32_t)0x01010300, output.getValues()[2].mField.getField());
-    EXPECT_EQ((int32_t)13, output.getValues()[2].mValue.int_value);
-}
-
 TEST(AtomMatcherTest, TestSubDimension) {
     HashableDimensionKey dim;
 
@@ -309,25 +230,21 @@
 }
 
 TEST(AtomMatcherTest, TestWriteDimensionPath) {
-    for (auto position : {Position::ALL, Position::FIRST, Position::LAST}) {
+    for (auto position : {Position::ANY, Position::ALL, Position::FIRST, Position::LAST}) {
         FieldMatcher matcher1;
         matcher1.set_field(10);
-
-        // Repeated nested fields (attribution chain).
         FieldMatcher* child = matcher1.add_child();
         child->set_field(2);
         child->set_position(position);
         child->add_child()->set_field(1);
         child->add_child()->set_field(3);
 
-        // Primitive field.
         child = matcher1.add_child();
         child->set_field(4);
 
-        // Repeated primitive field.
         child = matcher1.add_child();
         child->set_field(6);
-        child->set_position(position);
+        child->add_child()->set_field(2);
 
         vector<Matcher> matchers;
         translateFieldMatcher(matcher1, &matchers);
@@ -368,6 +285,9 @@
 
         const auto& dim3 = result.value_tuple().dimensions_value(2);
         EXPECT_EQ(6, dim3.field());
+        ASSERT_EQ(1, dim3.value_tuple().dimensions_value_size());
+        const auto& dim31 = dim3.value_tuple().dimensions_value(0);
+        EXPECT_EQ(2, dim31.field());
     }
 }
 
@@ -593,48 +513,6 @@
     EXPECT_EQ(999, atom.num_results());
 }
 
-TEST(AtomMatcherTest, TestWriteAtomWithRepeatedFieldsToProto) {
-    vector<int> intArray = {3, 6};
-    vector<int64_t> longArray = {1000L, 10002L};
-    vector<float> floatArray = {0.3f, 0.09f};
-    vector<string> stringArray = {"str1", "str2"};
-    int boolArrayLength = 2;
-    bool boolArray[boolArrayLength];
-    boolArray[0] = 1;
-    boolArray[1] = 0;
-    vector<bool> boolArrayVector = {1, 0};
-    vector<int> enumArray = {TestAtomReported::ON, TestAtomReported::OFF};
-
-    unique_ptr<LogEvent> event = CreateTestAtomReportedEventVariableRepeatedFields(
-            12345, intArray, longArray, floatArray, stringArray, boolArray, boolArrayLength,
-            enumArray);
-
-    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;
-    ASSERT_EQ(true, result.ParseFromArray(&outData[0], outData.size()));
-    EXPECT_EQ(Atom::PushedCase::kTestAtomReported, result.pushed_case());
-    TestAtomReported atom = result.test_atom_reported();
-    EXPECT_THAT(atom.repeated_int_field(), ElementsAreArray(intArray));
-    EXPECT_THAT(atom.repeated_long_field(), ElementsAreArray(longArray));
-    EXPECT_THAT(atom.repeated_float_field(), ElementsAreArray(floatArray));
-    EXPECT_THAT(atom.repeated_string_field(), ElementsAreArray(stringArray));
-    EXPECT_THAT(atom.repeated_boolean_field(), ElementsAreArray(boolArrayVector));
-    EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
-}
-
 /*
  * Test two Matchers is not a subset of one Matcher.
  * Test one Matcher is subset of two Matchers.
@@ -767,31 +645,6 @@
     EXPECT_FALSE(subsetDimensions(matchers2, matchers1));
 }
 
-TEST(AtomMatcherTest, TestIsPrimitiveRepeatedField) {
-    int pos1[] = {1, 1, 1};  // attribution uid
-    int pos2[] = {1, 1, 2};  // attribution tag
-    int pos3[] = {1, 2, 1};  // attribution uid - second node
-    int pos4[] = {1, 2, 2};  // attribution tag - second node
-    int pos5[] = {2, 1, 1};  // repeated field first element
-    int pos6[] = {2, 2, 1};  // repeated field second element
-    int pos7[] = {3, 1, 1};  // top-level field
-    Field field1(10, pos1, 2);
-    Field field2(10, pos2, 2);
-    Field field3(10, pos3, 2);
-    Field field4(10, pos4, 2);
-    Field field5(10, pos5, 1);
-    Field field6(10, pos6, 1);
-    Field field7(10, pos7, 0);
-
-    EXPECT_FALSE(isPrimitiveRepeatedField(field1));
-    EXPECT_FALSE(isPrimitiveRepeatedField(field2));
-    EXPECT_FALSE(isPrimitiveRepeatedField(field3));
-    EXPECT_FALSE(isPrimitiveRepeatedField(field4));
-    EXPECT_TRUE(isPrimitiveRepeatedField(field5));
-    EXPECT_TRUE(isPrimitiveRepeatedField(field6));
-    EXPECT_FALSE(isPrimitiveRepeatedField(field7));
-}
-
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/LogEntryMatcher_test.cpp b/statsd/tests/LogEntryMatcher_test.cpp
index 8a4fb19..0dc1888 100644
--- a/statsd/tests/LogEntryMatcher_test.cpp
+++ b/statsd/tests/LogEntryMatcher_test.cpp
@@ -107,36 +107,6 @@
     parseStatsEventToLogEvent(statsEvent, logEvent);
 }
 
-void makeRepeatedIntLogEvent(LogEvent* logEvent, const int32_t atomId,
-                             const vector<int>& intArray) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_writeInt32Array(statsEvent, intArray.data(), intArray.size());
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeRepeatedUidLogEvent(LogEvent* logEvent, const int32_t atomId,
-                             const vector<int>& intArray) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_writeInt32Array(statsEvent, intArray.data(), intArray.size());
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
-void makeRepeatedStringLogEvent(LogEvent* logEvent, const int32_t atomId,
-                                const vector<string>& stringArray) {
-    vector<const char*> cStringArray(stringArray.size());
-    for (int i = 0; i < cStringArray.size(); i++) {
-        cStringArray[i] = stringArray[i].c_str();
-    }
-
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_writeStringArray(statsEvent, cStringArray.data(), stringArray.size());
-    parseStatsEventToLogEvent(statsEvent, logEvent);
-}
-
 }  // anonymous namespace
 
 TEST(AtomMatcherTest, TestSimpleMatcher) {
@@ -419,99 +389,11 @@
     EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
 
     // Event has is_uid annotation, but uid maps to different package name.
-    simpleMatcher->mutable_field_value_matcher(0)->set_eq_string(
-            "pkg2");  // package names are normalized
+    simpleMatcher->mutable_field_value_matcher(0)->set_eq_string("Pkg2");
     EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
 }
 
-TEST(AtomMatcherTest, TestRepeatedUidFieldMatcher) {
-    sp<UidMap> uidMap = new 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("")},
-            /* certificateHash */ {{}, {}, {}, {}, {}});
-
-    // Set up matcher.
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-
-    // No is_uid annotation, no mapping from uid to package name.
-    vector<int> intArray = {1111, 3333, 2222};
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeRepeatedIntLogEvent(&event1, TAG_ID, intArray);
-
-    fieldValueMatcher->set_position(Position::FIRST);
-    fieldValueMatcher->set_eq_string("pkg0");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
-    fieldValueMatcher->set_position(Position::LAST);
-    fieldValueMatcher->set_eq_string("pkg1");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
-    fieldValueMatcher->set_position(Position::ANY);
-    fieldValueMatcher->set_eq_string("pkg2");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
-    // is_uid annotation, mapping from uid to package name.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeRepeatedUidLogEvent(&event2, TAG_ID, intArray);
-
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
-    fieldValueMatcher->set_eq_string("pkg0");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
-    fieldValueMatcher->set_eq_string("pkg1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-
-    fieldValueMatcher->set_position(Position::ANY);
-    fieldValueMatcher->set_eq_string("pkg");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
-    fieldValueMatcher->set_eq_string("pkg2");  // package names are normalized
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event2));
-}
-
-TEST(AtomMatcherTest, TestNeqAnyStringMatcher_SingleString) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the matcher
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-    StringListMatcher* neqStringList = fieldValueMatcher->mutable_neq_any_string();
-    neqStringList->add_str_value("some value");
-    neqStringList->add_str_value("another value");
-
-    // First string matched.
-    LogEvent event1(/*uid=*/0, /*pid=*/0);
-    makeStringLogEvent(&event1, TAG_ID, 0, "some value");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event1));
-
-    // Second string matched.
-    LogEvent event2(/*uid=*/0, /*pid=*/0);
-    makeStringLogEvent(&event2, TAG_ID, 0, "another value");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event2));
-
-    // No strings matched.
-    LogEvent event3(/*uid=*/0, /*pid=*/0);
-    makeStringLogEvent(&event3, TAG_ID, 0, "foo");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event3));
-}
-
-TEST(AtomMatcherTest, TestNeqAnyStringMatcher_AttributionUids) {
+TEST(AtomMatcherTest, TestNeqAnyStringMatcher) {
     sp<UidMap> uidMap = new UidMap();
     uidMap->updateMap(
             1, {1111, 1111, 2222, 3333, 3333} /* uid list */, {1, 1, 2, 1, 2} /* version list */,
@@ -689,284 +571,6 @@
     EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
 }
 
-TEST(AtomMatcherTest, TestIntMatcher_EmptyRepeatedField) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the log event.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    makeRepeatedIntLogEvent(&event, TAG_ID, {});
-
-    // Set up the matcher.
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-
-    // Match first int.
-    fieldValueMatcher->set_position(Position::FIRST);
-    fieldValueMatcher->set_eq_int(9);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match last int.
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match any int.
-    fieldValueMatcher->set_position(Position::ANY);
-    fieldValueMatcher->set_eq_int(13);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestIntMatcher_RepeatedIntField) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the log event.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<int> intArray = {21, 9};
-    makeRepeatedIntLogEvent(&event, TAG_ID, intArray);
-
-    // Set up the matcher.
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    // Match first int.
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-    fieldValueMatcher->set_position(Position::FIRST);
-    fieldValueMatcher->set_eq_int(9);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_int(21);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match last int.
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_int(9);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match any int.
-    fieldValueMatcher->set_position(Position::ANY);
-    fieldValueMatcher->set_eq_int(13);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_int(21);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_int(9);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestLtIntMatcher_RepeatedIntField) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the log event.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<int> intArray = {21, 9};
-    makeRepeatedIntLogEvent(&event, TAG_ID, intArray);
-
-    // Set up the matcher.
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    // Match first int.
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-    fieldValueMatcher->set_position(Position::FIRST);
-    fieldValueMatcher->set_lt_int(9);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_lt_int(21);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_lt_int(23);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match last int.
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_lt_int(9);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_lt_int(8);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match any int.
-    fieldValueMatcher->set_position(Position::ANY);
-    fieldValueMatcher->set_lt_int(21);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_lt_int(8);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_lt_int(23);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestStringMatcher_RepeatedStringField) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the log event.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<string> strArray = {"str1", "str2", "str3"};
-    makeRepeatedStringLogEvent(&event, TAG_ID, strArray);
-
-    // Set up the matcher.
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    // Match first int.
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-    fieldValueMatcher->set_position(Position::FIRST);
-    fieldValueMatcher->set_eq_string("str2");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_string("str1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match last int.
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_string("str3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    // Match any int.
-    fieldValueMatcher->set_position(Position::ANY);
-    fieldValueMatcher->set_eq_string("str4");
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_string("str1");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_string("str2");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    fieldValueMatcher->set_eq_string("str3");
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestEqAnyStringMatcher_RepeatedStringField) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the log event.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<string> strArray = {"str1", "str2", "str3"};
-    makeRepeatedStringLogEvent(&event, TAG_ID, strArray);
-
-    // Set up the matcher.
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-    StringListMatcher* eqStringList = fieldValueMatcher->mutable_eq_any_string();
-
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    eqStringList->add_str_value("str4");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    eqStringList->add_str_value("str2");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    eqStringList->add_str_value("str3");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    eqStringList->add_str_value("str1");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
-TEST(AtomMatcherTest, TestNeqAnyStringMatcher_RepeatedStringField) {
-    sp<UidMap> uidMap = new UidMap();
-
-    // Set up the log event.
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    vector<string> strArray = {"str1", "str2", "str3"};
-    makeRepeatedStringLogEvent(&event, TAG_ID, strArray);
-
-    // Set up the matcher.
-    AtomMatcher matcher;
-    SimpleAtomMatcher* simpleMatcher = matcher.mutable_simple_atom_matcher();
-    simpleMatcher->set_atom_id(TAG_ID);
-
-    FieldValueMatcher* fieldValueMatcher = simpleMatcher->add_field_value_matcher();
-    fieldValueMatcher->set_field(FIELD_ID_1);
-    StringListMatcher* neqStringList = fieldValueMatcher->mutable_neq_any_string();
-
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    neqStringList->add_str_value("str4");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    neqStringList->add_str_value("str2");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    neqStringList->add_str_value("str3");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_TRUE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-
-    neqStringList->add_str_value("str1");
-    fieldValueMatcher->set_position(Position::FIRST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::LAST);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-    fieldValueMatcher->set_position(Position::ANY);
-    EXPECT_FALSE(matchesSimple(uidMap, *simpleMatcher, event));
-}
-
 TEST(AtomMatcherTest, TestMultiFieldsMatcher) {
     sp<UidMap> uidMap = new UidMap();
     // Set up the matcher
diff --git a/statsd/tests/LogEvent_test.cpp b/statsd/tests/LogEvent_test.cpp
index d87b20b..4b4c6bc 100644
--- a/statsd/tests/LogEvent_test.cpp
+++ b/statsd/tests/LogEvent_test.cpp
@@ -37,111 +37,46 @@
 Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vector<bool>& last) {
     Field f(tag, (int32_t*)pos.data(), depth);
 
-    // only decorate last position for depths with repeated fields (depth 1)
-    if (depth > 0 && last[1]) f.decorateLastPos(1);
+    // For loop starts at 1 because the last field at depth 0 is not decorated.
+    for (int i = 1; i < depth; i++) {
+        if (last[i]) f.decorateLastPos(i);
+    }
 
     return f;
 }
 
-void createStatsEvent(AStatsEvent* statsEvent, uint8_t typeId) {
-    AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
-
-    int int32Array[2] = {3, 6};
-    uint32_t uids[] = {1001, 1002};
-    const char* tags[] = {"tag1", "tag2"};
-
-    switch (typeId) {
-        case INT32_TYPE:
-            AStatsEvent_writeInt32(statsEvent, 10);
-            break;
-        case INT64_TYPE:
-            AStatsEvent_writeInt64(statsEvent, 1000L);
-            break;
-        case STRING_TYPE:
-            AStatsEvent_writeString(statsEvent, "test");
-            break;
-        case LIST_TYPE:
-            AStatsEvent_writeInt32Array(statsEvent, int32Array, 2);
-            break;
-        case FLOAT_TYPE:
-            AStatsEvent_writeFloat(statsEvent, 1.3f);
-            break;
-        case BOOL_TYPE:
-            AStatsEvent_writeBool(statsEvent, 1);
-            break;
-        case BYTE_ARRAY_TYPE:
-            AStatsEvent_writeByteArray(statsEvent, (uint8_t*)"test", strlen("test"));
-            break;
-        case ATTRIBUTION_CHAIN_TYPE:
-            AStatsEvent_writeAttributionChain(statsEvent, uids, tags, 2);
-            break;
-        default:
-            break;
-    }
-}
-
-void createFieldWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t typeId, uint8_t annotationId,
-                                           bool annotationValue, bool parseBufferResult) {
+void createIntWithBoolAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
+                                         bool annotationValue) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    createStatsEvent(statsEvent, typeId);
+    AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
+    AStatsEvent_writeInt32(statsEvent, 10);
     AStatsEvent_addBoolAnnotation(statsEvent, annotationId, annotationValue);
     AStatsEvent_build(statsEvent);
 
     size_t size;
     uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    EXPECT_EQ(parseBufferResult, logEvent->parseBuffer(buf, size));
+    EXPECT_TRUE(logEvent->parseBuffer(buf, size));
 
     AStatsEvent_release(statsEvent);
 }
 
-void createFieldWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t typeId, uint8_t annotationId,
-                                          int annotationValue, bool parseBufferResult) {
+void createIntWithIntAnnotationLogEvent(LogEvent* logEvent, uint8_t annotationId,
+                                        int annotationValue) {
     AStatsEvent* statsEvent = AStatsEvent_obtain();
-    createStatsEvent(statsEvent, typeId);
+    AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
+    AStatsEvent_writeInt32(statsEvent, 10);
     AStatsEvent_addInt32Annotation(statsEvent, annotationId, annotationValue);
     AStatsEvent_build(statsEvent);
 
     size_t size;
     uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    EXPECT_EQ(parseBufferResult, logEvent->parseBuffer(buf, size));
+    EXPECT_TRUE(logEvent->parseBuffer(buf, size));
 
     AStatsEvent_release(statsEvent);
 }
 
 }  // anonymous namespace
 
-// Setup for parameterized tests.
-class LogEventTestBadAnnotationFieldTypes : public testing::TestWithParam<int> {
-public:
-    static std::string ToString(testing::TestParamInfo<int> info) {
-        switch (info.param) {
-            case INT32_TYPE:
-                return "Int32";
-            case INT64_TYPE:
-                return "Int64";
-            case STRING_TYPE:
-                return "String";
-            case LIST_TYPE:
-                return "List";
-            case FLOAT_TYPE:
-                return "Float";
-            case BYTE_ARRAY_TYPE:
-                return "ByteArray";
-            case ATTRIBUTION_CHAIN_TYPE:
-                return "AttributionChain";
-            default:
-                return "Unknown";
-        }
-    }
-};
-
-// TODO(b/222539899): Add BOOL_TYPE value once parseAnnotations is updated to check specific
-// typeIds. BOOL_TYPE should be a bad field type for is_uid, nested, and reset state annotations.
-INSTANTIATE_TEST_SUITE_P(BadAnnotationFieldTypes, LogEventTestBadAnnotationFieldTypes,
-                         testing::Values(INT32_TYPE, INT64_TYPE, STRING_TYPE, LIST_TYPE, FLOAT_TYPE,
-                                         BYTE_ARRAY_TYPE, ATTRIBUTION_CHAIN_TYPE),
-                         LogEventTestBadAnnotationFieldTypes::ToString);
-
 TEST(LogEventTest, TestPrimitiveParsing) {
     AStatsEvent* event = AStatsEvent_obtain();
     AStatsEvent_setAtomId(event, 100);
@@ -290,25 +225,6 @@
     AStatsEvent_release(event);
 }
 
-TEST(LogEventTest, TestTooManyTopLevelElements) {
-    int32_t numElements = 128;
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-
-    for (int i = 0; i < numElements; i++) {
-        AStatsEvent_writeInt32(event, i);
-    }
-
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
-
-    AStatsEvent_release(event);
-}
-
 TEST(LogEventTest, TestAttributionChain) {
     AStatsEvent* event = AStatsEvent_obtain();
     AStatsEvent_setAtomId(event, 100);
@@ -335,7 +251,7 @@
     const vector<FieldValue>& values = logEvent.getValues();
     ASSERT_EQ(4, values.size());  // 2 per attribution node
 
-    std::pair<size_t, size_t> attrIndexRange;
+    std::pair<int, int> attrIndexRange;
     EXPECT_TRUE(logEvent.hasAttributionChain(&attrIndexRange));
     EXPECT_EQ(0, attrIndexRange.first);
     EXPECT_EQ(3, attrIndexRange.second);
@@ -369,236 +285,9 @@
     AStatsEvent_release(event);
 }
 
-TEST(LogEventTest, TestEmptyAttributionChain) {
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-
-    AStatsEvent_writeAttributionChain(event, {}, {}, 0);
-    AStatsEvent_writeInt32(event, 10);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestAttributionChainTooManyElements) {
-    int32_t numNodes = 128;
-    uint32_t uids[numNodes];
-    vector<string> tags(numNodes);  // storage that cTag elements point to
-    const char* cTags[numNodes];
-
-    for (int i = 0; i < numNodes; i++) {
-        uids[i] = i;
-        tags.push_back("test");
-        cTags[i] = tags[i].c_str();
-    }
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeAttributionChain(event, uids, cTags, numNodes);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestArrayParsing) {
-    size_t numElements = 2;
-    int32_t int32Array[2] = {3, 6};
-    int64_t int64Array[2] = {1000L, 1002L};
-    float floatArray[2] = {0.3f, 0.09f};
-    bool boolArray[2] = {0, 1};
-
-    vector<string> stringArray = {"str1", "str2"};
-    const char* cStringArray[2];
-    for (int i = 0; i < numElements; i++) {
-        cStringArray[i] = stringArray[i].c_str();
-    }
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeInt32Array(event, int32Array, numElements);
-    AStatsEvent_writeInt64Array(event, int64Array, numElements);
-    AStatsEvent_writeFloatArray(event, floatArray, numElements);
-    AStatsEvent_writeBoolArray(event, boolArray, numElements);
-    AStatsEvent_writeStringArray(event, cStringArray, numElements);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-    EXPECT_FALSE(logEvent.hasAttributionChain());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(10, values.size());  // 2 for each array type
-
-    const FieldValue& int32ArrayItem1 = values[0];
-    Field expectedField = getField(100, {1, 1, 1}, 1, {false, false, false});
-    EXPECT_EQ(expectedField, int32ArrayItem1.mField);
-    EXPECT_EQ(Type::INT, int32ArrayItem1.mValue.getType());
-    EXPECT_EQ(3, int32ArrayItem1.mValue.int_value);
-
-    const FieldValue& int32ArrayItem2 = values[1];
-    expectedField = getField(100, {1, 2, 1}, 1, {false, true, false});
-    EXPECT_EQ(expectedField, int32ArrayItem2.mField);
-    EXPECT_EQ(Type::INT, int32ArrayItem2.mValue.getType());
-    EXPECT_EQ(6, int32ArrayItem2.mValue.int_value);
-
-    const FieldValue& int64ArrayItem1 = values[2];
-    expectedField = getField(100, {2, 1, 1}, 1, {false, false, false});
-    EXPECT_EQ(expectedField, int64ArrayItem1.mField);
-    EXPECT_EQ(Type::LONG, int64ArrayItem1.mValue.getType());
-    EXPECT_EQ(1000L, int64ArrayItem1.mValue.long_value);
-
-    const FieldValue& int64ArrayItem2 = values[3];
-    expectedField = getField(100, {2, 2, 1}, 1, {false, true, false});
-    EXPECT_EQ(expectedField, int64ArrayItem2.mField);
-    EXPECT_EQ(Type::LONG, int64ArrayItem2.mValue.getType());
-    EXPECT_EQ(1002L, int64ArrayItem2.mValue.long_value);
-
-    const FieldValue& floatArrayItem1 = values[4];
-    expectedField = getField(100, {3, 1, 1}, 1, {false, false, false});
-    EXPECT_EQ(expectedField, floatArrayItem1.mField);
-    EXPECT_EQ(Type::FLOAT, floatArrayItem1.mValue.getType());
-    EXPECT_EQ(0.3f, floatArrayItem1.mValue.float_value);
-
-    const FieldValue& floatArrayItem2 = values[5];
-    expectedField = getField(100, {3, 2, 1}, 1, {false, true, false});
-    EXPECT_EQ(expectedField, floatArrayItem2.mField);
-    EXPECT_EQ(Type::FLOAT, floatArrayItem2.mValue.getType());
-    EXPECT_EQ(0.09f, floatArrayItem2.mValue.float_value);
-
-    const FieldValue& boolArrayItem1 = values[6];
-    expectedField = getField(100, {4, 1, 1}, 1, {false, false, false});
-    EXPECT_EQ(expectedField, boolArrayItem1.mField);
-    EXPECT_EQ(Type::INT,
-              boolArrayItem1.mValue.getType());  // FieldValue does not support boolean type
-    EXPECT_EQ(false, boolArrayItem1.mValue.int_value);
-
-    const FieldValue& boolArrayItem2 = values[7];
-    expectedField = getField(100, {4, 2, 1}, 1, {false, true, false});
-    EXPECT_EQ(expectedField, boolArrayItem2.mField);
-    EXPECT_EQ(Type::INT,
-              boolArrayItem2.mValue.getType());  // FieldValue does not support boolean type
-    EXPECT_EQ(true, boolArrayItem2.mValue.int_value);
-
-    const FieldValue& stringArrayItem1 = values[8];
-    expectedField = getField(100, {5, 1, 1}, 1, {true, false, false});
-    EXPECT_EQ(expectedField, stringArrayItem1.mField);
-    EXPECT_EQ(Type::STRING, stringArrayItem1.mValue.getType());
-    EXPECT_EQ("str1", stringArrayItem1.mValue.str_value);
-
-    const FieldValue& stringArrayItem2 = values[9];
-    expectedField = getField(100, {5, 2, 1}, 1, {true, true, false});
-    EXPECT_EQ(expectedField, stringArrayItem2.mField);
-    EXPECT_EQ(Type::STRING, stringArrayItem2.mValue.getType());
-    EXPECT_EQ("str2", stringArrayItem2.mValue.str_value);
-}
-
-TEST(LogEventTest, TestEmptyStringArray) {
-    const char* cStringArray[2];
-    string empty = "";
-    cStringArray[0] = empty.c_str();
-    cStringArray[1] = empty.c_str();
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeStringArray(event, cStringArray, 2);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(2, values.size());
-
-    const FieldValue& stringArrayItem1 = values[0];
-    Field expectedField = getField(100, {1, 1, 1}, 1, {true, false, false});
-    EXPECT_EQ(expectedField, stringArrayItem1.mField);
-    EXPECT_EQ(Type::STRING, stringArrayItem1.mValue.getType());
-    EXPECT_EQ(empty, stringArrayItem1.mValue.str_value);
-
-    const FieldValue& stringArrayItem2 = values[1];
-    expectedField = getField(100, {1, 2, 1}, 1, {true, true, false});
-    EXPECT_EQ(expectedField, stringArrayItem2.mField);
-    EXPECT_EQ(Type::STRING, stringArrayItem2.mValue.getType());
-    EXPECT_EQ(empty, stringArrayItem2.mValue.str_value);
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestArrayTooManyElements) {
-    int32_t numElements = 128;
-    int32_t int32Array[numElements];
-
-    for (int i = 0; i < numElements; i++) {
-        int32Array[i] = 1;
-    }
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeInt32Array(event, int32Array, numElements);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
-
-    AStatsEvent_release(event);
-}
-
-TEST(LogEventTest, TestEmptyArray) {
-    int32_t int32Array[0] = {};
-
-    AStatsEvent* event = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeInt32Array(event, int32Array, 0);
-    AStatsEvent_build(event);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
-
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-
-    EXPECT_EQ(100, logEvent.GetTagId());
-    EXPECT_EQ(1000, logEvent.GetUid());
-    EXPECT_EQ(1001, logEvent.GetPid());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(0, values.size());
-
-    AStatsEvent_release(event);
-}
-
 TEST(LogEventTest, TestAnnotationIdIsUid) {
     LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_IS_UID, true,
-                                          /*parseBufferResult*/ true);
+    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_IS_UID, true);
 
     ASSERT_EQ(event.getNumUidFields(), 1);
 
@@ -607,214 +296,33 @@
     EXPECT_TRUE(isUidField(values.at(0)));
 }
 
-TEST(LogEventTest, TestAnnotationIdIsUid_RepeatedIntAndOtherFields) {
-    size_t numElements = 2;
-    int32_t int32Array[2] = {3, 6};
-
-    vector<string> stringArray = {"str1", "str2"};
-    const char* cStringArray[2];
-    for (int i = 0; i < numElements; i++) {
-        cStringArray[i] = stringArray[i].c_str();
-    }
-
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 100);
-    AStatsEvent_writeInt32(statsEvent, 5);
-    AStatsEvent_writeInt32Array(statsEvent, int32Array, numElements);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_writeStringArray(statsEvent, cStringArray, numElements);
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-    EXPECT_EQ(2, logEvent.getNumUidFields());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(values.size(), 5);
-    EXPECT_FALSE(isUidField(values.at(0)));
-    EXPECT_TRUE(isUidField(values.at(1)));
-    EXPECT_TRUE(isUidField(values.at(2)));
-    EXPECT_FALSE(isUidField(values.at(3)));
-    EXPECT_FALSE(isUidField(values.at(4)));
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid_RepeatedIntOneEntry) {
-    size_t numElements = 1;
-    int32_t int32Array[1] = {3};
-
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 100);
-    AStatsEvent_writeInt32Array(statsEvent, int32Array, numElements);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-    EXPECT_EQ(1, logEvent.getNumUidFields());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    ASSERT_EQ(values.size(), 1);
-    EXPECT_TRUE(isUidField(values.at(0)));
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid_EmptyIntArray) {
-    int32_t int32Array[0] = {};
-
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, 100);
-    AStatsEvent_writeInt32Array(statsEvent, int32Array, /*numElements*/ 0);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_writeInt32(statsEvent, 5);
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
-    EXPECT_EQ(0, logEvent.getNumUidFields());
-
-    const vector<FieldValue>& values = logEvent.getValues();
-    EXPECT_EQ(values.size(), 1);
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid_BadRepeatedInt64) {
-    int64_t int64Array[2] = {1000L, 1002L};
-
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
-    AStatsEvent_writeInt64Array(statsEvent, int64Array, /*numElements*/ 2);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-
-    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
-    EXPECT_EQ(0, logEvent.getNumUidFields());
-
-    AStatsEvent_release(statsEvent);
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid_BadRepeatedString) {
-    size_t numElements = 2;
-    vector<string> stringArray = {"str1", "str2"};
-    const char* cStringArray[2];
-    for (int i = 0; i < numElements; i++) {
-        cStringArray[i] = stringArray[i].c_str();
-    }
-
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, /*atomId=*/100);
-    AStatsEvent_writeStringArray(statsEvent, cStringArray, /*numElements*/ 2);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_build(statsEvent);
-
-    size_t size;
-    uint8_t* buf = AStatsEvent_getBuffer(statsEvent, &size);
-    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-
-    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
-    EXPECT_EQ(0, logEvent.getNumUidFields());
-
-    AStatsEvent_release(statsEvent);
-}
-
-TEST_P(LogEventTestBadAnnotationFieldTypes, TestAnnotationIdIsUid) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-
-    if (GetParam() != INT32_TYPE && GetParam() != LIST_TYPE) {
-        createFieldWithBoolAnnotationLogEvent(&event, GetParam(), ANNOTATION_ID_IS_UID, true,
-                                              /*parseBufferResult*/ false);
-    }
-}
-
-TEST(LogEventTest, TestAnnotationIdIsUid_NotIntAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_IS_UID, 10,
-                                         /*parseBufferResult*/ false);
-}
-
 TEST(LogEventTest, TestAnnotationIdStateNested) {
     LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_STATE_NESTED, true,
-                                          /*parseBufferResult*/ true);
+    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_STATE_NESTED, true);
 
     const vector<FieldValue>& values = event.getValues();
     ASSERT_EQ(values.size(), 1);
     EXPECT_TRUE(values[0].mAnnotations.isNested());
 }
 
-TEST_P(LogEventTestBadAnnotationFieldTypes, TestAnnotationIdStateNested) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-
-    if (GetParam() != INT32_TYPE) {
-        createFieldWithBoolAnnotationLogEvent(&event, GetParam(), ANNOTATION_ID_STATE_NESTED, true,
-                                              /*parseBufferResult*/ false);
-    }
-}
-
-TEST(LogEventTest, TestAnnotationIdStateNested_NotIntAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_STATE_NESTED, 10,
-                                         /*parseBufferResult*/ false);
-}
-
 TEST(LogEventTest, TestPrimaryFieldAnnotation) {
     LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_PRIMARY_FIELD, true,
-                                          /*parseBufferResult*/ true);
+    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_PRIMARY_FIELD, true);
 
     const vector<FieldValue>& values = event.getValues();
     ASSERT_EQ(values.size(), 1);
     EXPECT_TRUE(values[0].mAnnotations.isPrimaryField());
 }
 
-TEST_P(LogEventTestBadAnnotationFieldTypes, TestPrimaryFieldAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-
-    if (GetParam() == LIST_TYPE || GetParam() == ATTRIBUTION_CHAIN_TYPE) {
-        createFieldWithBoolAnnotationLogEvent(&event, GetParam(), ANNOTATION_ID_PRIMARY_FIELD, true,
-                                              /*parseBufferResult*/ false);
-    }
-}
-
-TEST(LogEventTest, TestPrimaryFieldAnnotation_NotIntAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_PRIMARY_FIELD, 10,
-                                         /*parseBufferResult*/ false);
-}
-
 TEST(LogEventTest, TestExclusiveStateAnnotation) {
     LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_EXCLUSIVE_STATE, true,
-                                          /*parseBufferResult*/ true);
+    createIntWithBoolAnnotationLogEvent(&event, ANNOTATION_ID_EXCLUSIVE_STATE, true);
 
     const vector<FieldValue>& values = event.getValues();
     ASSERT_EQ(values.size(), 1);
     EXPECT_TRUE(values[0].mAnnotations.isExclusiveState());
 }
 
-TEST_P(LogEventTestBadAnnotationFieldTypes, TestExclusiveStateAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-
-    if (GetParam() != INT32_TYPE) {
-        createFieldWithBoolAnnotationLogEvent(&event, GetParam(), ANNOTATION_ID_EXCLUSIVE_STATE,
-                                              true,
-                                              /*parseBufferResult*/ false);
-    }
-}
-
-TEST(LogEventTest, TestExclusiveStateAnnotation_NotIntAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_EXCLUSIVE_STATE, 10,
-                                         /*parseBufferResult*/ false);
-}
-
 TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation) {
     // Event has 10 ints and then an attribution chain
     int numInts = 10;
@@ -847,72 +355,100 @@
     EXPECT_TRUE(values[firstUidInChainIndex].mAnnotations.isPrimaryField());
 }
 
-TEST_P(LogEventTestBadAnnotationFieldTypes, TestPrimaryFieldFirstUidAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-
-    if (GetParam() != ATTRIBUTION_CHAIN_TYPE) {
-        createFieldWithBoolAnnotationLogEvent(&event, GetParam(),
-                                              ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, true,
-                                              /*parseBufferResult*/ false);
-    }
-}
-
-TEST(LogEventTest, TestPrimaryFieldFirstUidAnnotation_NotIntAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithIntAnnotationLogEvent(&event, ATTRIBUTION_CHAIN_TYPE,
-                                         ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID, 10,
-                                         /*parseBufferResult*/ false);
-}
-
 TEST(LogEventTest, TestResetStateAnnotation) {
     int32_t resetState = 10;
     LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithIntAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_TRIGGER_STATE_RESET,
-                                         resetState, /*parseBufferResult*/ true);
+    createIntWithIntAnnotationLogEvent(&event, ANNOTATION_ID_TRIGGER_STATE_RESET, resetState);
 
     const vector<FieldValue>& values = event.getValues();
     ASSERT_EQ(values.size(), 1);
     EXPECT_EQ(event.getResetState(), resetState);
 }
 
-TEST_P(LogEventTestBadAnnotationFieldTypes, TestResetStateAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    int32_t resetState = 10;
-
-    if (GetParam() != INT32_TYPE) {
-        createFieldWithIntAnnotationLogEvent(&event, GetParam(), ANNOTATION_ID_TRIGGER_STATE_RESET,
-                                             resetState,
-                                             /*parseBufferResult*/ false);
-    }
-}
-
-TEST(LogEventTest, TestResetStateAnnotation_NotBoolAnnotation) {
-    LogEvent event(/*uid=*/0, /*pid=*/0);
-    createFieldWithBoolAnnotationLogEvent(&event, INT32_TYPE, ANNOTATION_ID_TRIGGER_STATE_RESET,
-                                          true,
-                                          /*parseBufferResult*/ false);
-}
-
-TEST(LogEventTest, TestUidAnnotationWithInt8MaxValues) {
-    int32_t numElements = INT8_MAX;
-    int32_t int32Array[numElements];
-
-    for (int i = 0; i < numElements; i++) {
-        int32Array[i] = i;
-    }
-
+TEST(LogEventTest, TestExclusiveStateAnnotationAfterTooManyFields) {
     AStatsEvent* event = AStatsEvent_obtain();
     AStatsEvent_setAtomId(event, 100);
-    AStatsEvent_writeInt32Array(event, int32Array, numElements);
-    AStatsEvent_writeInt32(event, 10);
-    AStatsEvent_writeInt32(event, 11);
-    AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_IS_UID, true);
+
+    const unsigned int numAttributionNodes = 64;
+
+    uint32_t uids[numAttributionNodes];
+    const char* tags[numAttributionNodes];
+
+    for (unsigned int i = 1; i <= numAttributionNodes; i++) {
+        uids[i-1] = i;
+        tags[i-1] = std::to_string(i).c_str();
+    }
+
+    AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes);
+    AStatsEvent_writeInt32(event, 1);
+    AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_EXCLUSIVE_STATE, true);
+
     AStatsEvent_build(event);
 
     size_t size;
     uint8_t* buf = AStatsEvent_getBuffer(event, &size);
+
     LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
-    EXPECT_TRUE(logEvent.parseBuffer(buf, size));
+    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
+    EXPECT_EQ(-1, logEvent.getExclusiveStateFieldIndex());
+
+    AStatsEvent_release(event);
+}
+
+TEST(LogEventTest, TestUidAnnotationAfterTooManyFields) {
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, 100);
+
+    const unsigned int numAttributionNodes = 64;
+
+    uint32_t uids[numAttributionNodes];
+    const char* tags[numAttributionNodes];
+
+    for (unsigned int i = 1; i <= numAttributionNodes; i++) {
+        uids[i-1] = i;
+        tags[i-1] = std::to_string(i).c_str();
+    }
+
+    AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes);
+    AStatsEvent_writeInt32(event, 1);
+    AStatsEvent_addBoolAnnotation(event, ANNOTATION_ID_IS_UID, true);
+
+    AStatsEvent_build(event);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
+
+    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
+    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
+    EXPECT_EQ(0, logEvent.getNumUidFields());
+
+    AStatsEvent_release(event);
+}
+
+TEST(LogEventTest, TestAttributionChainEndIndexAfterTooManyFields) {
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, 100);
+
+    const unsigned int numAttributionNodes = 65;
+
+    uint32_t uids[numAttributionNodes];
+    const char* tags[numAttributionNodes];
+
+    for (unsigned int i = 1; i <= numAttributionNodes; i++) {
+        uids[i-1] = i;
+        tags[i-1] = std::to_string(i).c_str();
+    }
+
+    AStatsEvent_writeAttributionChain(event, uids, tags, numAttributionNodes);
+
+    AStatsEvent_build(event);
+
+    size_t size;
+    uint8_t* buf = AStatsEvent_getBuffer(event, &size);
+
+    LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
+    EXPECT_FALSE(logEvent.parseBuffer(buf, size));
+    EXPECT_FALSE(logEvent.hasAttributionChain());
 
     AStatsEvent_release(event);
 }
diff --git a/statsd/tests/MetricsManager_test.cpp b/statsd/tests/MetricsManager_test.cpp
index 5cab800..b5e8d8f 100644
--- a/statsd/tests/MetricsManager_test.cpp
+++ b/statsd/tests/MetricsManager_test.cpp
@@ -264,38 +264,6 @@
                 UnorderedElementsAreArray(unionSet({defaultPullUids, app2Uids, {AID_ADB}})));
 }
 
-TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagFalse) {
-    FlagProvider::getInstance().overrideFlag(OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, FLAG_FALSE,
-                                             /*isBootFlag=*/true);
-
-    sp<UidMap> uidMap;
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-
-    StatsdConfig config = buildGoodConfig();
-    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
-                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
-    EXPECT_FALSE(metricsManager.mAtomMatcherOptimizationEnabled);
-}
-
-TEST(MetricsManagerTest, TestAtomMatcherOptimizationEnabledFlagTrue) {
-    FlagProvider::getInstance().overrideFlag(OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, FLAG_TRUE,
-                                             /*isBootFlag=*/true);
-
-    sp<UidMap> uidMap;
-    sp<StatsPullerManager> pullerManager = new StatsPullerManager();
-    sp<AlarmMonitor> anomalyAlarmMonitor;
-    sp<AlarmMonitor> periodicAlarmMonitor;
-
-    StatsdConfig config = buildGoodConfig();
-    MetricsManager metricsManager(kConfigKey, config, timeBaseSec, timeBaseSec, uidMap,
-                                  pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor);
-
-    EXPECT_TRUE(metricsManager.mAtomMatcherOptimizationEnabled);
-}
-
 TEST(MetricsManagerTest, TestCheckLogCredentialsWhitelistedAtom) {
     sp<UidMap> uidMap;
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
diff --git a/statsd/tests/StatsLogProcessor_test.cpp b/statsd/tests/StatsLogProcessor_test.cpp
index 4bca452..b3d518d 100644
--- a/statsd/tests/StatsLogProcessor_test.cpp
+++ b/statsd/tests/StatsLogProcessor_test.cpp
@@ -14,18 +14,17 @@
 
 #include "StatsLogProcessor.h"
 
-#include <android-base/stringprintf.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <stdio.h>
 
 #include "StatsService.h"
 #include "config/ConfigKey.h"
+#include "src/stats_log.pb.h"
+#include "src/statsd_config.pb.h"
 #include "guardrail/StatsdStats.h"
 #include "logd/LogEvent.h"
 #include "packages/UidMap.h"
-#include "src/stats_log.pb.h"
-#include "src/statsd_config.pb.h"
 #include "statslog_statsdtest.h"
 #include "storage/StorageManager.h"
 #include "tests/statsd_test_util.h"
@@ -39,11 +38,9 @@
 namespace os {
 namespace statsd {
 
-using android::base::StringPrintf;
 using android::util::ProtoOutputStream;
 
 #ifdef __ANDROID__
-#define STATS_DATA_DIR "/data/misc/stats-data"
 
 /**
  * Mock MetricsManager (ByteSize() is called).
@@ -66,22 +63,7 @@
     MOCK_METHOD1(dropData, void(const int64_t dropTimeNs));
 };
 
-// Setup for test fixture.
-class StatsLogProcessorTest : public testing::TestWithParam<string> {
-    void SetUp() override {
-        FlagProvider::getInstance().overrideFlag(OPTIMIZATION_ATOM_MATCHER_MAP_FLAG, GetParam(),
-                                                 /*isBootFlag=*/true);
-    }
-
-    void TearDown() override {
-        FlagProvider::getInstance().resetOverrides();
-    }
-};
-
-INSTANTIATE_TEST_SUITE_P(OptimizationAtomMatcher, StatsLogProcessorTest,
-                         testing::Values(FLAG_FALSE, FLAG_TRUE));
-
-TEST_P(StatsLogProcessorTest, TestRateLimitByteSize) {
+TEST(StatsLogProcessorTest, TestRateLimitByteSize) {
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
     sp<AlarmMonitor> anomalyAlarmMonitor;
@@ -102,7 +84,7 @@
     p.flushIfNecessaryLocked(key, mockMetricsManager);
 }
 
-TEST_P(StatsLogProcessorTest, TestRateLimitBroadcast) {
+TEST(StatsLogProcessorTest, TestRateLimitBroadcast) {
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
     sp<AlarmMonitor> anomalyAlarmMonitor;
@@ -134,7 +116,7 @@
     // EXPECT_EQ(1, broadcastCount);
 }
 
-TEST_P(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
+TEST(StatsLogProcessorTest, TestDropWhenByteSizeTooLarge) {
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
     sp<AlarmMonitor> anomalyAlarmMonitor;
@@ -176,7 +158,7 @@
     return config;
 }
 
-TEST_P(StatsLogProcessorTest, TestUidMapHasSnapshot) {
+TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) {
     // Setup simple config key corresponding to empty config.
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
@@ -208,7 +190,7 @@
     ASSERT_EQ(2, uidmap.snapshots(0).package_info_size());
 }
 
-TEST_P(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) {
+TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) {
     // Setup simple config key corresponding to empty config.
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
@@ -238,7 +220,7 @@
     EXPECT_FALSE(output.reports(0).has_uid_map());
 }
 
-TEST_P(StatsLogProcessorTest, TestReportIncludesSubConfig) {
+TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) {
     // Setup simple config key corresponding to empty config.
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
@@ -272,7 +254,7 @@
     EXPECT_EQ(2, report.annotation(0).field_int32());
 }
 
-TEST_P(StatsLogProcessorTest, TestOnDumpReportEraseData) {
+TEST(StatsLogProcessorTest, TestOnDumpReportEraseData) {
     // Setup a simple config.
     StatsdConfig config;
     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
@@ -320,7 +302,7 @@
     EXPECT_TRUE(noData);
 }
 
-TEST_P(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate) {
+TEST(StatsLogProcessorTest, TestPullUidProviderSetOnConfigUpdate) {
     // Setup simple config key corresponding to empty config.
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
@@ -343,7 +325,7 @@
     EXPECT_EQ(pullerManager->mPullUidProviders.find(key), pullerManager->mPullUidProviders.end());
 }
 
-TEST_P(StatsLogProcessorTest, InvalidConfigRemoved) {
+TEST(StatsLogProcessorTest, InvalidConfigRemoved) {
     // Setup simple config key corresponding to empty config.
     sp<UidMap> m = new UidMap();
     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
@@ -377,11 +359,10 @@
               StatsdStats::getInstance().mConfigStats.find(key));
     // Both "config" and "invalidConfig" should be in the icebox.
     EXPECT_EQ(2, StatsdStats::getInstance().mIceBox.size());
-    string suffix = StringPrintf("%d_%lld", key.GetUid(), (long long)key.GetId());
-    StorageManager::deleteSuffixedFiles(STATS_DATA_DIR, suffix.c_str());
 }
 
-TEST_P(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
+
+TEST(StatsLogProcessorTest, TestActiveConfigMetricDiskWriteRead) {
     int uid = 1111;
 
     // Setup a simple config, no activation
@@ -726,7 +707,7 @@
     EXPECT_EQ(broadcastCount, 1);
 }
 
-TEST_P(StatsLogProcessorTest, TestActivationOnBoot) {
+TEST(StatsLogProcessorTest, TestActivationOnBoot) {
     int uid = 1111;
 
     StatsdConfig config1;
@@ -847,7 +828,7 @@
     EXPECT_EQ(kActive, activation1001->state);
 }
 
-TEST_P(StatsLogProcessorTest, TestActivationOnBootMultipleActivations) {
+TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivations) {
     int uid = 1111;
 
     // Create config with 2 metrics:
@@ -1248,7 +1229,7 @@
     // }}}-------------------------------------------------------------------------------
 }
 
-TEST_P(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActivationTypes) {
+TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActivationTypes) {
     int uid = 1111;
 
     // Create config with 2 metrics:
@@ -1510,7 +1491,7 @@
     // }}}---------------------------------------------------------------------------
 }
 
-TEST_P(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) {
+TEST(StatsLogProcessorTest, TestActivationsPersistAcrossSystemServerRestart) {
     int uid = 9876;
     long configId = 12341;
 
@@ -1574,9 +1555,7 @@
     metric2ActivationTrigger2->set_activation_type(ACTIVATE_IMMEDIATELY);
 
     // Send the config.
-    const sp<UidMap> uidMap = new UidMap();
-    const shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     string serialized = config1.SerializeAsString();
     service->addConfigurationChecked(uid, configId, {serialized.begin(), serialized.end()});
 
@@ -1890,87 +1869,7 @@
     EXPECT_EQ(field2, actualFieldValues->at(5).mValue.int_value);
 }
 
-/* *
- * Test cases for repeated uid fields:
- * - empty field
- * - single host uid
- * - single isolated uid
- * - multiple host uids
- * - multiple isolated uids
- * - multiple host and isolated uids
- */
-TEST(StatsLogProcessorTest_mapIsolatedUidToHostUid, LogRepeatedUidField) {
-    int hostUid1 = 21;
-    int hostUid2 = 22;
-    int isolatedUid1 = 31;
-    int isolatedUid2 = 32;
-    uint64_t eventTimeNs = 12355;
-    int atomId = 89;
-    int field1 = 90;
-    int field2 = 28;
-    sp<MockUidMap> mockUidMap =
-            makeMockUidMapForHosts({{hostUid1, {isolatedUid1}}, {hostUid2, {isolatedUid2}}});
-
-    ConfigKey cfgKey;
-    StatsdConfig config = MakeConfig(false);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(1, 1, config, cfgKey, nullptr, 0, mockUidMap);
-
-    // Empty repeated uid field.
-    shared_ptr<LogEvent> logEvent = makeRepeatedUidLogEvent(atomId, eventTimeNs, {});
-    processor->OnLogEvent(logEvent.get());
-
-    const vector<FieldValue>* actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(0, actualFieldValues->size());
-
-    // Single host uid.
-    logEvent = makeRepeatedUidLogEvent(atomId, eventTimeNs, {hostUid1});
-    processor->OnLogEvent(logEvent.get());
-
-    actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(1, actualFieldValues->size());
-    EXPECT_EQ(hostUid1, actualFieldValues->at(0).mValue.int_value);
-
-    // Single isolated uid.
-    logEvent = makeRepeatedUidLogEvent(atomId, eventTimeNs, {isolatedUid1});
-    processor->OnLogEvent(logEvent.get());
-
-    actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(1, actualFieldValues->size());
-    EXPECT_EQ(hostUid1, actualFieldValues->at(0).mValue.int_value);
-
-    // Multiple host uids.
-    logEvent = makeRepeatedUidLogEvent(atomId, eventTimeNs, {hostUid1, hostUid2});
-    processor->OnLogEvent(logEvent.get());
-
-    actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(2, actualFieldValues->size());
-    EXPECT_EQ(hostUid1, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid2, actualFieldValues->at(1).mValue.int_value);
-
-    // Multiple isolated uids.
-    logEvent = makeRepeatedUidLogEvent(atomId, eventTimeNs, {isolatedUid1, isolatedUid2});
-    processor->OnLogEvent(logEvent.get());
-
-    actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(2, actualFieldValues->size());
-    EXPECT_EQ(hostUid1, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid2, actualFieldValues->at(1).mValue.int_value);
-
-    // Multiple host and isolated uids.
-    logEvent = makeRepeatedUidLogEvent(atomId, eventTimeNs,
-                                       {isolatedUid1, hostUid2, isolatedUid2, hostUid1});
-    processor->OnLogEvent(logEvent.get());
-
-    actualFieldValues = &logEvent->getValues();
-    ASSERT_EQ(4, actualFieldValues->size());
-    EXPECT_EQ(hostUid1, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid2, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostUid2, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(hostUid1, actualFieldValues->at(3).mValue.int_value);
-}
-
-TEST_P(StatsLogProcessorTest, TestDumpReportWithoutErasingDataDoesNotUpdateTimestamp) {
+TEST(StatsLogProcessorTest, TestDumpReportWithoutErasingDataDoesNotUpdateTimestamp) {
     int hostUid = 20;
     int isolatedUid = 30;
     sp<MockUidMap> mockUidMap = makeMockUidMapForHosts({{hostUid, {isolatedUid}}});
@@ -2014,6 +1913,7 @@
     EXPECT_EQ(output.reports_size(), 1);
     EXPECT_EQ(output.reports(0).current_report_elapsed_nanos(), dumpTime3Ns);
     EXPECT_EQ(output.reports(0).last_report_elapsed_nanos(), dumpTime1Ns);
+
 }
 
 #else
diff --git a/statsd/tests/StatsService_test.cpp b/statsd/tests/StatsService_test.cpp
index 24cc2f2..9d01b0c 100644
--- a/statsd/tests/StatsService_test.cpp
+++ b/statsd/tests/StatsService_test.cpp
@@ -13,15 +13,14 @@
 // limitations under the License.
 
 #include "StatsService.h"
+#include "config/ConfigKey.h"
+#include "src/statsd_config.pb.h"
 
 #include <android/binder_interface_utils.h>
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
-#include <stdio.h>
 
-#include "config/ConfigKey.h"
-#include "packages/UidMap.h"
-#include "src/statsd_config.pb.h"
+#include <stdio.h>
 
 using namespace android;
 using namespace testing;
@@ -36,9 +35,7 @@
 #ifdef __ANDROID__
 
 TEST(StatsServiceTest, TestAddConfig_simple) {
-    const sp<UidMap> uidMap = new UidMap();
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     StatsdConfig config;
     config.set_id(12345);
     string serialized = config.SerializeAsString();
@@ -48,9 +45,7 @@
 }
 
 TEST(StatsServiceTest, TestAddConfig_empty) {
-    const sp<UidMap> uidMap = new UidMap();
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     string serialized = "";
 
     EXPECT_TRUE(
@@ -58,9 +53,7 @@
 }
 
 TEST(StatsServiceTest, TestAddConfig_invalid) {
-    const sp<UidMap> uidMap = new UidMap();
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     string serialized = "Invalid config!";
 
     EXPECT_FALSE(
@@ -77,9 +70,7 @@
 
     int32_t uid;
 
-    const sp<UidMap> uidMap = new UidMap();
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     service->mEngBuild = true;
 
     // "-1"
diff --git a/statsd/tests/UidMap_test.cpp b/statsd/tests/UidMap_test.cpp
index a303ac6..25305f7 100644
--- a/statsd/tests/UidMap_test.cpp
+++ b/statsd/tests/UidMap_test.cpp
@@ -13,20 +13,18 @@
 // limitations under the License.
 
 #include "packages/UidMap.h"
+#include "StatsLogProcessor.h"
+#include "config/ConfigKey.h"
+#include "guardrail/StatsdStats.h"
+#include "logd/LogEvent.h"
+#include "hash.h"
+#include "statslog_statsdtest.h"
+#include "statsd_test_util.h"
 
 #include <android/util/ProtoOutputStream.h>
 #include <gtest/gtest.h>
-#include <src/uid_data.pb.h>
-#include <stdio.h>
 
-#include "StatsLogProcessor.h"
-#include "StatsService.h"
-#include "config/ConfigKey.h"
-#include "guardrail/StatsdStats.h"
-#include "hash.h"
-#include "logd/LogEvent.h"
-#include "statsd_test_util.h"
-#include "statslog_statsdtest.h"
+#include <stdio.h>
 
 using namespace android;
 
@@ -36,74 +34,10 @@
 
 using android::util::ProtoOutputStream;
 using android::util::ProtoReader;
-using ::ndk::SharedRefBase;
 
 #ifdef __ANDROID__
-
-namespace {
 const string kApp1 = "app1.sharing.1";
 const string kApp2 = "app2.sharing.1";
-const string kApp3 = "app3";
-
-const vector<int32_t> kUids{1000, 1000, 1500};
-const vector<int64_t> kVersions{4, 5, 6};
-const vector<string> kVersionStrings{"v1", "v1", "v2"};
-const vector<string> kApps{kApp1, kApp2, kApp3};
-const vector<string> kInstallers{"", "", "com.android.vending"};
-const vector<vector<uint8_t>> kCertificateHashes{{'a', 'z'}, {'b', 'c'}, {'d', 'e'}};
-const vector<bool> kDeleted(3, false);
-
-void sendIncludeCertificateHashFlagToStatsd(shared_ptr<StatsService> service, bool flag) {
-    PropertyParcel certHashParcel;
-    certHashParcel.property = kIncludeCertificateHash;
-    certHashParcel.value = flag ? "true" : "false";
-    service->updateProperties({certHashParcel});
-}
-
-void sendPackagesToStatsd(shared_ptr<StatsService> service, const vector<int32_t>& uids,
-                          const vector<int64_t>& versions, const vector<string>& versionStrings,
-                          const vector<string>& apps, const vector<string>& installers,
-                          const vector<vector<uint8_t>>& certificateHashes) {
-    // Populate UidData from app data.
-    UidData uidData;
-    for (size_t i = 0; i < uids.size(); i++) {
-        ApplicationInfo* appInfo = uidData.add_app_info();
-        appInfo->set_uid(uids[i]);
-        appInfo->set_version(versions[i]);
-        appInfo->set_version_string(versionStrings[i]);
-        appInfo->set_package_name(apps[i]);
-        appInfo->set_installer(installers[i]);
-        appInfo->set_certificate_hash(certificateHashes[i].data(), certificateHashes[i].size());
-    }
-
-    // Create file descriptor from serialized UidData.
-    // Create a file that lives in memory.
-    ScopedFileDescriptor scopedFd(memfd_create("doesn't matter", MFD_CLOEXEC));
-    const int fd = scopedFd.get();
-    int f = fcntl(fd, F_GETFD);  // Read the file descriptor flags.
-    ASSERT_NE(-1, f);            // Ensure there was no error while reading file descriptor flags.
-    ASSERT_TRUE(f & FD_CLOEXEC);
-    ASSERT_TRUE(uidData.SerializeToFileDescriptor(fd));
-    ASSERT_EQ(0, lseek(fd, 0, SEEK_SET));
-
-    // Send file descriptor containing app data to statsd.
-    service->informAllUidData(scopedFd);
-}
-
-// Returns a vector of the same length as values param. Each i-th element in the returned vector is
-// the index at which values[i] appears in the list denoted by the begin and end iterators.
-template <typename Iterator, typename ValueType>
-vector<uint32_t> computeIndices(const Iterator begin, const Iterator end,
-                                const vector<ValueType>& values) {
-    vector<uint32_t> indices;
-    for (const ValueType& value : values) {
-        Iterator it = find(begin, end, value);
-        indices.emplace_back(distance(begin, it));
-    }
-    return indices;
-}
-
-}  // anonymous namespace
 
 TEST(UidMapTest, TestIsolatedUID) {
     sp<UidMap> m = new UidMap();
@@ -128,195 +62,114 @@
     EXPECT_EQ(101, m->getHostUidOrSelf(101));
 }
 
-TEST(UidMapTest, TestUpdateMap) {
-    const sp<UidMap> uidMap = new UidMap();
-    const shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
-    sendPackagesToStatsd(service, kUids, kVersions, kVersionStrings, kApps, kInstallers,
-                         kCertificateHashes);
+TEST(UidMapTest, TestMatching) {
+    UidMap m;
+    const vector<int32_t> uids{1000, 1000};
+    const vector<int64_t> versions{4, 5};
+    const vector<String16> versionStrings{String16("v1"), String16("v1")};
+    const vector<String16> apps{String16(kApp1.c_str()), String16(kApp2.c_str())};
+    const vector<String16> installers{String16(""), String16("")};
+    const vector<vector<uint8_t>> certificateHashes{{}, {}};
 
-    EXPECT_TRUE(uidMap->hasApp(1000, kApp1));
-    EXPECT_TRUE(uidMap->hasApp(1000, kApp2));
-    EXPECT_TRUE(uidMap->hasApp(1500, kApp3));
-    EXPECT_FALSE(uidMap->hasApp(1000, "not.app"));
+    m.updateMap(1 /* timestamp */, uids, versions, versionStrings, apps, installers,
+                certificateHashes);
+    EXPECT_TRUE(m.hasApp(1000, kApp1));
+    EXPECT_TRUE(m.hasApp(1000, kApp2));
+    EXPECT_FALSE(m.hasApp(1000, "not.app"));
 
-    std::set<string> name_set = uidMap->getAppNamesFromUid(1000u, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre(kApp1, kApp2));
+    std::set<string> name_set = m.getAppNamesFromUid(1000u, true /* returnNormalized */);
+    ASSERT_EQ(name_set.size(), 2u);
+    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
+    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
-    name_set = uidMap->getAppNamesFromUid(1500u, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre(kApp3));
-
-    name_set = uidMap->getAppNamesFromUid(12345, true /* returnNormalized */);
-    EXPECT_THAT(name_set, IsEmpty());
-
-    // Certificate hashes are not sent to statsd by default (when flag is not present).
-    vector<PackageInfo> expectedPackageInfos =
-            buildPackageInfos(kApps, kUids, kVersions, kVersionStrings, kInstallers,
-                              /* certHashes */ {}, kDeleted, /* installerIndices */ {},
-                              /* hashStrings */ false);
-
-    PackageInfoSnapshot packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
+    name_set = m.getAppNamesFromUid(12345, true /* returnNormalized */);
+    EXPECT_TRUE(name_set.empty());
 }
 
-TEST(UidMapTest, TestUpdateMapMultiple) {
-    const sp<UidMap> uidMap = new UidMap();
-    const shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
-    sendPackagesToStatsd(service, kUids, kVersions, kVersionStrings, kApps, kInstallers,
-                         kCertificateHashes);
+TEST(UidMapTest, TestAddAndRemove) {
+    UidMap m;
+    const vector<int32_t> uids{1000, 1000};
+    const vector<int64_t> versions{4, 5};
+    const vector<String16> versionStrings{String16("v1"), String16("v1")};
+    const vector<String16> apps{String16(kApp1.c_str()), String16(kApp2.c_str())};
+    const vector<String16> installers{String16(""), String16("")};
+    const vector<vector<uint8_t>> certificateHashes{{}, {}};
 
-    // Remove kApp3, and add NewApp
-    vector<int32_t> uids(kUids);
-    uids.back() = 2000;
-    vector<string> apps(kApps);
-    apps.back() = "NewApp";
-    vector<string> installers(kInstallers);
-    installers.back() = "NewInstaller";
+    m.updateMap(1 /* timestamp */, uids, versions, versionStrings, apps, installers,
+                certificateHashes);
 
-    sendPackagesToStatsd(service, uids, kVersions, kVersionStrings, apps, installers,
-                         kCertificateHashes);
+    std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
+    ASSERT_EQ(name_set.size(), 2u);
+    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
+    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
-    EXPECT_TRUE(uidMap->hasApp(1000, kApp1));
-    EXPECT_TRUE(uidMap->hasApp(1000, kApp2));
-    EXPECT_TRUE(uidMap->hasApp(2000, "NewApp"));
-    EXPECT_FALSE(uidMap->hasApp(1500, kApp3));
-    EXPECT_FALSE(uidMap->hasApp(1000, "not.app"));
+    // Update the app1 version.
+    m.updateApp(2, String16(kApp1.c_str()), 1000, 40, String16("v40"), String16(""),
+                /* certificateHash */ {});
+    EXPECT_EQ(40, m.getAppVersion(1000, kApp1));
 
-    std::set<string> name_set = uidMap->getAppNamesFromUid(1000u, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre(kApp1, kApp2));
+    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
+    ASSERT_EQ(name_set.size(), 2u);
+    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
+    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
-    name_set = uidMap->getAppNamesFromUid(2000, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre("newapp"));
+    m.removeApp(3, String16(kApp1.c_str()), 1000);
+    EXPECT_FALSE(m.hasApp(1000, kApp1));
+    EXPECT_TRUE(m.hasApp(1000, kApp2));
+    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
+    ASSERT_EQ(name_set.size(), 1u);
+    EXPECT_TRUE(name_set.find(kApp1) == name_set.end());
+    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
-    name_set = uidMap->getAppNamesFromUid(1500, true /* returnNormalized */);
-    EXPECT_THAT(name_set, IsEmpty());
-
-    // Certificate hashes are not sent to statsd by default (when flag is not present).
-    vector<PackageInfo> expectedPackageInfos =
-            buildPackageInfos(apps, uids, kVersions, kVersionStrings, installers,
-                              /* certHashes */ {}, kDeleted, /* installerIndices */ {},
-                              /* hashStrings */ false);
-
-    PackageInfoSnapshot packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-}
-
-TEST(UidMapTest, TestRemoveApp) {
-    const sp<UidMap> uidMap = new UidMap();
-    const shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
-    sendPackagesToStatsd(service, kUids, kVersions, kVersionStrings, kApps, kInstallers,
-                         kCertificateHashes);
-
-    service->informOnePackageRemoved(kApp1, 1000);
-    EXPECT_FALSE(uidMap->hasApp(1000, kApp1));
-    EXPECT_TRUE(uidMap->hasApp(1000, kApp2));
-    EXPECT_TRUE(uidMap->hasApp(1500, kApp3));
-    std::set<string> name_set = uidMap->getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre(kApp2));
-
-    vector<bool> deleted(kDeleted);
-    deleted[0] = true;
-    vector<PackageInfo> expectedPackageInfos =
-            buildPackageInfos(kApps, kUids, kVersions, kVersionStrings, kInstallers,
-                              /* certHashes */ {}, deleted, /* installerIndices */ {},
-                              /* hashStrings */ false);
-    PackageInfoSnapshot packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-
-    service->informOnePackageRemoved(kApp2, 1000);
-    EXPECT_FALSE(uidMap->hasApp(1000, kApp1));
-    EXPECT_FALSE(uidMap->hasApp(1000, kApp2));
-    EXPECT_TRUE(uidMap->hasApp(1500, kApp3));
-    EXPECT_FALSE(uidMap->hasApp(1000, "not.app"));
-    name_set = uidMap->getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_THAT(name_set, IsEmpty());
-
-    deleted[1] = true;
-    expectedPackageInfos =
-            buildPackageInfos(kApps, kUids, kVersions, kVersionStrings, kInstallers,
-                              /* certHashes */ {}, deleted, /* installerIndices */ {},
-                              /* hashStrings */ false);
-    packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-
-    service->informOnePackageRemoved(kApp3, 1500);
-    EXPECT_FALSE(uidMap->hasApp(1000, kApp1));
-    EXPECT_FALSE(uidMap->hasApp(1000, kApp2));
-    EXPECT_FALSE(uidMap->hasApp(1500, kApp3));
-    EXPECT_FALSE(uidMap->hasApp(1000, "not.app"));
-    name_set = uidMap->getAppNamesFromUid(1500, true /* returnNormalized */);
-    EXPECT_THAT(name_set, IsEmpty());
-
-    deleted[2] = true;
-    expectedPackageInfos =
-            buildPackageInfos(kApps, kUids, kVersions, kVersionStrings, kInstallers,
-                              /* certHashes */ {}, deleted, /* installerIndices */ {},
-                              /* hashStrings */ false);
-    packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
+    // Remove app2.
+    m.removeApp(4, String16(kApp2.c_str()), 1000);
+    EXPECT_FALSE(m.hasApp(1000, kApp1));
+    EXPECT_FALSE(m.hasApp(1000, kApp2));
+    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
+    EXPECT_TRUE(name_set.empty());
 }
 
 TEST(UidMapTest, TestUpdateApp) {
-    const sp<UidMap> uidMap = new UidMap();
-    const shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
-    sendPackagesToStatsd(service, kUids, kVersions, kVersionStrings, kApps, kInstallers,
-                         kCertificateHashes);
+    UidMap m;
+    m.updateMap(1, {1000, 1000}, {4, 5}, {String16("v4"), String16("v5")},
+                {String16(kApp1.c_str()), String16(kApp2.c_str())}, {String16(""), String16("")},
+                /* certificateHash */ {{}, {}});
+    std::set<string> name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
+    ASSERT_EQ(name_set.size(), 2u);
+    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
+    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
 
-    // Update app1 version.
-    service->informOnePackage(kApps[0].c_str(), kUids[0], /* version */ 40,
-                              /* versionString */ "v40", kInstallers[0], kCertificateHashes[0]);
-    EXPECT_THAT(uidMap->getAppVersion(kUids[0], kApps[0]), Eq(40));
-    std::set<string> name_set = uidMap->getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre(kApp1, kApp2));
+    // Adds a new name for uid 1000.
+    m.updateApp(2, String16("NeW_aPP1_NAmE"), 1000, 40, String16("v40"), String16(""),
+                /* certificateHash */ {});
+    name_set = m.getAppNamesFromUid(1000, true /* returnNormalized */);
+    ASSERT_EQ(name_set.size(), 3u);
+    EXPECT_TRUE(name_set.find(kApp1) != name_set.end());
+    EXPECT_TRUE(name_set.find(kApp2) != name_set.end());
+    EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
+    EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
 
-    // Add a new name for uid 1000.
-    service->informOnePackage("NeW_aPP1_NAmE", 1000, /* version */ 40,
-                              /* versionString */ "v40", /* installer */ "com.android.vending",
-                              /* certificateHash */ {'a'});
-    name_set = uidMap->getAppNamesFromUid(1000, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre(kApp1, kApp2, "new_app1_name"));
+    // This name is also reused by another uid 2000.
+    m.updateApp(3, String16("NeW_aPP1_NAmE"), 2000, 1, String16("v1"), String16(""),
+                /* certificateHash */ {});
+    name_set = m.getAppNamesFromUid(2000, true /* returnNormalized */);
+    ASSERT_EQ(name_set.size(), 1u);
+    EXPECT_TRUE(name_set.find("NeW_aPP1_NAmE") == name_set.end());
+    EXPECT_TRUE(name_set.find("new_app1_name") != name_set.end());
+}
 
-    // Re-add the same name for another uid 2000
-    service->informOnePackage("NeW_aPP1_NAmE", 2000, /* version */ 1,
-                              /* versionString */ "v1", /* installer */ "",
-                              /* certificateHash */ {'b'});
-    name_set = uidMap->getAppNamesFromUid(2000, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre("new_app1_name"));
-
-    // Re-add existing package with different installer
-    service->informOnePackage("NeW_aPP1_NAmE", 2000, /* version */ 1,
-                              /* versionString */ "v1", /* installer */ "new_installer",
-                              /* certificateHash */ {'b'});
-    name_set = uidMap->getAppNamesFromUid(2000, true /* returnNormalized */);
-    EXPECT_THAT(name_set, UnorderedElementsAre("new_app1_name"));
-
-    vector<int32_t> uids = concatenate(kUids, {1000, 2000});
-    vector<int64_t> versions = concatenate(kVersions, {40, 1});
-    versions[0] = 40;
-    vector<string> versionStrings = concatenate(kVersionStrings, {"v40", "v1"});
-    versionStrings[0] = "v40";
-    vector<string> apps = concatenate(kApps, {"NeW_aPP1_NAmE", "NeW_aPP1_NAmE"});
-    vector<string> installers = concatenate(kInstallers, {"com.android.vending", "new_installer"});
-    vector<bool> deleted = concatenate(kDeleted, {false, false});
-    // Certificate hashes are not sent to statsd by default (when flag is not present).
-    vector<PackageInfo> expectedPackageInfos =
-            buildPackageInfos(apps, uids, versions, versionStrings, installers, /* certHashes */ {},
-                              deleted, /* installerIndices */ {},
-                              /* hashStrings */ false);
-
-    PackageInfoSnapshot packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
+static void protoOutputStreamToUidMapping(ProtoOutputStream* proto, UidMapping* results) {
+    vector<uint8_t> bytes;
+    bytes.resize(proto->size());
+    size_t pos = 0;
+    sp<ProtoReader> reader = proto->data();
+    while (reader->readBuffer() != NULL) {
+        size_t toRead = reader->currentToRead();
+        std::memcpy(&((bytes)[pos]), reader->readBuffer(), toRead);
+        pos += toRead;
+        reader->move(toRead);
+    }
+    results->ParseFromArray(bytes.data(), bytes.size());
 }
 
 // Test that uid map returns at least one snapshot even if we already obtained
@@ -346,7 +199,7 @@
 
     // Check there's still a uidmap attached this one.
     UidMapping results;
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(1, results.snapshots_size());
     EXPECT_EQ("v1", results.snapshots(0).package_info(0).version_string());
 }
@@ -374,7 +227,7 @@
 
     // Snapshot should still contain this item as deleted.
     UidMapping results;
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(1, results.snapshots(0).package_info_size());
     EXPECT_EQ(true, results.snapshots(0).package_info(0).deleted());
 }
@@ -408,7 +261,7 @@
     m.appendUidMap(/* timestamp */ 3, config1, /* includeVersionStrings */ true,
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(maxDeletedApps + 10, results.snapshots(0).package_info_size());
 
     // Now remove all the apps.
@@ -423,7 +276,7 @@
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
     // Snapshot drops the first nine items.
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(maxDeletedApps, results.snapshots(0).package_info_size());
 }
 
@@ -449,7 +302,7 @@
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
     UidMapping results;
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(1, results.snapshots_size());
 
     // We have to keep at least one snapshot in memory at all times.
@@ -457,7 +310,7 @@
     m.appendUidMap(/* timestamp */ 2, config1, /* includeVersionStrings */ true,
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(1, results.snapshots_size());
 
     // Now add another configuration.
@@ -469,7 +322,7 @@
     m.appendUidMap(/* timestamp */ 6, config1, /* includeVersionStrings */ true,
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(1, results.snapshots_size());
     ASSERT_EQ(1, results.changes_size());
     ASSERT_EQ(1U, m.mChanges.size());
@@ -484,7 +337,7 @@
     m.appendUidMap(/* timestamp */ 8, config1, /* includeVersionStrings */ true,
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(1, results.snapshots_size());
     ASSERT_EQ(1, results.changes_size());
     ASSERT_EQ(2U, m.mChanges.size());
@@ -493,7 +346,7 @@
     m.appendUidMap(/* timestamp */ 9, config2, /* includeVersionStrings */ true,
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
-    outputStreamToProto(&proto, &results);
+    protoOutputStreamToUidMapping(&proto, &results);
     ASSERT_EQ(1, results.snapshots_size());
     ASSERT_EQ(2, results.changes_size());
     // At this point both should be cleared.
@@ -520,6 +373,7 @@
                 /* certificateHash */ {});
 
     ProtoOutputStream proto;
+    vector<uint8_t> bytes;
     m.appendUidMap(/* timestamp */ 2, config1, /* includeVersionStrings */ true,
                    /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
                    /* str_set */ nullptr, &proto);
@@ -568,254 +422,6 @@
     ASSERT_EQ(1U, m.mChanges.size());
 }
 
-// Set up parameterized test for testing with different boolean flag values that gate the inclusion
-// of package certificate hashes in UidMap.
-class UidMapTestWithAppCertificateFlag : public TestWithParam<bool> {
-protected:
-    const sp<UidMap> uidMap;
-    const shared_ptr<StatsService> service;
-    vector<PackageInfo> expectedPackageInfos;
-
-    UidMapTestWithAppCertificateFlag()
-        : uidMap(new UidMap()),
-          service(SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr)) {
-    }
-
-    void SetUp() override {
-        sendIncludeCertificateHashFlagToStatsd(service, GetParam());
-        sendPackagesToStatsd(service, kUids, kVersions, kVersionStrings, kApps, kInstallers,
-                             kCertificateHashes);
-
-        vector<vector<uint8_t>> emptyCertHashes;
-        vector<vector<uint8_t>> certHashes = GetParam() ? kCertificateHashes : emptyCertHashes;
-        expectedPackageInfos = buildPackageInfos(
-                kApps, kUids, kVersions, kVersionStrings, kInstallers, certHashes, kDeleted,
-                /* installerIndices */ {}, /* hashStrings */ false);
-    }
-};
-
-INSTANTIATE_TEST_SUITE_P(Boolean, UidMapTestWithAppCertificateFlag, Bool(),
-                         PrintToStringParamName());
-
-TEST_P(UidMapTestWithAppCertificateFlag, TestUpdateMap) {
-    PackageInfoSnapshot packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-}
-
-TEST_P(UidMapTestWithAppCertificateFlag, TestUpdateApp) {
-    // Add a new name for uid 1000.
-    service->informOnePackage("NeW_aPP1_NAmE", 1000, /* version */ 40,
-                              /* versionString */ "v40", /* installer */ "com.android.vending",
-                              /* certificateHash */ {'a'});
-
-    vector<uint8_t> certHash;
-    if (GetParam()) {
-        certHash = {'a'};
-    }
-    PackageInfo expectedPackageInfo =
-            buildPackageInfo("NeW_aPP1_NAmE", 1000, /* version */ 40, /* versionString */ "v40",
-                             /* installer */ "com.android.vending", certHash, /* deleted */ false,
-                             /* hashStrings */ false, /* installerIndex */ nullopt);
-    expectedPackageInfos.push_back(expectedPackageInfo);
-
-    PackageInfoSnapshot packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-
-    // Update installer and certificate for the same package.
-    service->informOnePackage("NeW_aPP1_NAmE", 1000, /* version */ 40,
-                              /* versionString */ "v40", /* installer */ "new_installer",
-                              /* certificateHash */ {'n', 'e', 'w'});
-
-    if (GetParam()) {
-        certHash = {'n', 'e', 'w'};
-    }
-    expectedPackageInfo =
-            buildPackageInfo("NeW_aPP1_NAmE", 1000, /* version */ 40, /* versionString */ "v40",
-                             /* installer */ "new_installer", certHash, /* deleted */ false,
-                             /* hashStrings */ false, /* installerIndex */ nullopt);
-    expectedPackageInfos.back() = expectedPackageInfo;
-
-    packageInfoSnapshot = getPackageInfoSnapshot(uidMap);
-    EXPECT_THAT(packageInfoSnapshot.package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-}
-
-class UidMapTestAppendUidMap : public Test {
-protected:
-    const ConfigKey config1;
-    const sp<UidMap> uidMap;
-    const shared_ptr<StatsService> service;
-
-    set<string> installersSet;
-    set<uint64_t> installerHashSet;
-    vector<uint64_t> installerHashes;
-
-    UidMapTestAppendUidMap()
-        : config1(1, StringToId("config1")),
-          uidMap(new UidMap()),
-          service(SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr)) {
-    }
-
-    void SetUp() override {
-        sendIncludeCertificateHashFlagToStatsd(service, true);
-        sendPackagesToStatsd(service, kUids, kVersions, kVersionStrings, kApps, kInstallers,
-                             kCertificateHashes);
-
-        for (const string& installer : kInstallers) {
-            installersSet.insert(installer);
-            uint64_t installerHash = Hash64(installer);
-            installerHashes.emplace_back(installerHash);
-            installerHashSet.insert(installerHash);
-        }
-    }
-};
-
-TEST_F(UidMapTestAppendUidMap, TestInstallersInReportIncludeInstallerAndHashStrings) {
-    ProtoOutputStream proto;
-    set<string> strSet;
-    uidMap->appendUidMap(/* timestamp */ 3, config1, /* includeVersionStrings */ true,
-                         /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0, &strSet,
-                         &proto);
-
-    UidMapping results;
-    outputStreamToProto(&proto, &results);
-
-    // Verify hashes for all installers are in the installer_hash list.
-    EXPECT_THAT(results.installer_hash(), UnorderedElementsAreArray(installerHashSet));
-
-    EXPECT_THAT(results.installer_name(), IsEmpty());
-
-    // Verify all installer names are added to the strSet argument.
-    EXPECT_THAT(strSet, IsSupersetOf(installersSet));
-
-    ASSERT_THAT(results.snapshots_size(), Eq(1));
-
-    // Compute installer indices for each package.
-    // Find the location of each installerHash from the input in the results.
-    // installerIndices[i] is the index in results.installer_hash() that matches installerHashes[i].
-    vector<uint32_t> installerIndices = computeIndices(
-            results.installer_hash().begin(), results.installer_hash().end(), installerHashes);
-
-    vector<PackageInfo> expectedPackageInfos =
-            buildPackageInfos(kApps, kUids, kVersions, kVersionStrings, kInstallers,
-                              /* certHashes */ {}, kDeleted, installerIndices,
-                              /* hashStrings */ true);
-
-    EXPECT_THAT(strSet, IsSupersetOf(kApps));
-
-    EXPECT_THAT(results.snapshots(0).package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-}
-
-TEST_F(UidMapTestAppendUidMap, TestInstallersInReportIncludeInstallerAndDontHashStrings) {
-    ProtoOutputStream proto;
-    uidMap->appendUidMap(/* timestamp */ 3, config1, /* includeVersionStrings */ true,
-                         /* includeInstaller */ true, /* truncatedCertificateHashSize */ 0,
-                         /* str_set */ nullptr, &proto);
-
-    UidMapping results;
-    outputStreamToProto(&proto, &results);
-
-    // Verify all installers are in the installer_name list.
-    EXPECT_THAT(results.installer_name(), UnorderedElementsAreArray(installersSet));
-
-    EXPECT_THAT(results.installer_hash(), IsEmpty());
-
-    ASSERT_THAT(results.snapshots_size(), Eq(1));
-
-    vector<uint32_t> installerIndices = computeIndices(results.installer_name().begin(),
-                                                       results.installer_name().end(), kInstallers);
-
-    vector<PackageInfo> expectedPackageInfos =
-            buildPackageInfos(kApps, kUids, kVersions, kVersionStrings, kInstallers,
-                              /* certHashes */ {}, kDeleted, installerIndices,
-                              /* hashStrings */ false);
-
-    EXPECT_THAT(results.snapshots(0).package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-}
-
-// Set up parameterized test with set<string>* parameter to control whether strings are hashed
-// or not in the report. A value of nullptr indicates strings should not be hashed and non-null
-// values indicates strings are hashed in the report and the original strings are added to this set.
-class UidMapTestAppendUidMapHashStrings : public UidMapTestAppendUidMap,
-                                          public WithParamInterface<set<string>*> {
-public:
-    inline static set<string> strSet;
-
-protected:
-    void SetUp() override {
-        strSet.clear();
-    }
-};
-
-INSTANTIATE_TEST_SUITE_P(
-        HashStrings, UidMapTestAppendUidMapHashStrings,
-        Values(nullptr, &(UidMapTestAppendUidMapHashStrings::strSet)),
-        [](const TestParamInfo<UidMapTestAppendUidMapHashStrings::ParamType>& info) {
-            return info.param == nullptr ? "NoHashStrings" : "HashStrings";
-        });
-
-TEST_P(UidMapTestAppendUidMapHashStrings, TestNoIncludeInstallersInReport) {
-    ProtoOutputStream proto;
-    uidMap->appendUidMap(/* timestamp */ 3, config1, /* includeVersionStrings */ true,
-                         /* includeInstaller */ false, /* truncatedCertificateHashSize */ 0,
-                         /* str_set */ GetParam(), &proto);
-
-    UidMapping results;
-    outputStreamToProto(&proto, &results);
-
-    // Verify installer lists are empty.
-    EXPECT_THAT(results.installer_name(), IsEmpty());
-    EXPECT_THAT(results.installer_hash(), IsEmpty());
-
-    ASSERT_THAT(results.snapshots_size(), Eq(1));
-
-    // Verify that none of installer, installer_hash, installer_index fields in PackageInfo are
-    // populated.
-    EXPECT_THAT(results.snapshots(0).package_info(),
-                Each(Property(&PackageInfo::has_installer, IsFalse())));
-    EXPECT_THAT(results.snapshots(0).package_info(),
-                Each(Property(&PackageInfo::has_installer_hash, IsFalse())));
-    EXPECT_THAT(results.snapshots(0).package_info(),
-                Each(Property(&PackageInfo::has_installer_index, IsFalse())));
-}
-
-// Set up parameterized test for testing with different truncation hash sizes for the certificates.
-class UidMapTestTruncateCertificateHash : public UidMapTestAppendUidMap,
-                                          public WithParamInterface<uint8_t> {};
-
-INSTANTIATE_TEST_SUITE_P(ZeroOneTwoThree, UidMapTestTruncateCertificateHash,
-                         Range(uint8_t{0}, uint8_t{4}));
-
-TEST_P(UidMapTestTruncateCertificateHash, TestCertificateHashesTruncated) {
-    const uint8_t hashSize = GetParam();
-    ProtoOutputStream proto;
-    uidMap->appendUidMap(/* timestamp */ 3, config1, /* includeVersionStrings */ true,
-                         /* includeInstaller */ false, hashSize, /* str_set */ nullptr, &proto);
-
-    UidMapping results;
-    outputStreamToProto(&proto, &results);
-
-    ASSERT_THAT(results.snapshots_size(), Eq(1));
-
-    vector<vector<uint8_t>> certHashes = kCertificateHashes;
-    for (vector<uint8_t>& certHash : certHashes) {
-        certHash.resize(certHash.size() < hashSize ? certHash.size() : hashSize);
-    }
-    vector<PackageInfo> expectedPackageInfos =
-            buildPackageInfos(kApps, kUids, kVersions, kVersionStrings,
-                              /* installers */ {}, certHashes, kDeleted,
-                              /* installerIndices*/ {},
-                              /* hashStrings */ false);
-
-    EXPECT_THAT(results.snapshots(0).package_info(),
-                UnorderedPointwise(ProtoEq(), expectedPackageInfos));
-}
-
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp b/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
index 30e8fd7..fd6ebde 100644
--- a/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
+++ b/statsd/tests/e2e/Anomaly_duration_sum_e2e_test.cpp
@@ -21,7 +21,6 @@
 #include "src/StatsLogProcessor.h"
 #include "src/StatsService.h"
 #include "src/anomaly/DurationAnomalyTracker.h"
-#include "src/packages/UidMap.h"
 #include "src/stats_log_util.h"
 #include "tests/statsd_test_util.h"
 
@@ -114,8 +113,7 @@
     const uint64_t alert_id = config.alert(0).id();
     const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
 
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     sendConfig(service, config);
 
     auto processor = service->mProcessor;
@@ -298,8 +296,7 @@
     const uint64_t alert_id = config.alert(0).id();
     const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
 
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     sendConfig(service, config);
 
     auto processor = service->mProcessor;
@@ -422,8 +419,7 @@
     const uint64_t alert_id = config.alert(0).id();
     const uint32_t refractory_period_sec = config.alert(0).refractory_period_secs();
 
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     sendConfig(service, config);
 
     auto processor = service->mProcessor;
@@ -514,8 +510,7 @@
     const uint32_t refractory_period_sec = 3 * bucketSizeNs / NS_PER_SEC;
     config.mutable_alert(0)->set_refractory_period_secs(refractory_period_sec);
 
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     sendConfig(service, config);
 
     auto processor = service->mProcessor;
diff --git a/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp b/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp
index 004ddee..d83a39d 100644
--- a/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp
+++ b/statsd/tests/e2e/ConfigUpdate_e2e_test.cpp
@@ -2374,9 +2374,7 @@
     SubscriberReporter::getInstance().setBroadcastSubscriber(key, replaceSubId, replaceBroadcast);
     SubscriberReporter::getInstance().setBroadcastSubscriber(key, removeSubId, removeBroadcast);
 
-    const sp<UidMap> uidMap = new UidMap();
-    const shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(uidMap, /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     sp<StatsLogProcessor> processor = service->mProcessor;
     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
     int64_t bucketStartTimeNs = processor->mTimeBaseNs;
diff --git a/statsd/tests/e2e/CountMetric_e2e_test.cpp b/statsd/tests/e2e/CountMetric_e2e_test.cpp
index ef183b7..8ea8861 100644
--- a/statsd/tests/e2e/CountMetric_e2e_test.cpp
+++ b/statsd/tests/e2e/CountMetric_e2e_test.cpp
@@ -965,788 +965,6 @@
                         3);
 }
 
-TEST(CountMetricE2eTest, TestRepeatedFieldsAndEmptyArrays) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(testAtomReportedAtomMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(123, 987);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> intArray = {3, 6};
-    vector<int64_t> longArray = {1000L, 10002L};
-    vector<float> floatArray = {0.3f, 0.09f};
-    vector<string> stringArray = {"str1", "str2"};
-    int boolArrayLength = 2;
-    bool boolArray[boolArrayLength];
-    boolArray[0] = 1;
-    boolArray[1] = 0;
-    vector<int> enumArray = {TestAtomReported::ON, TestAtomReported::OFF};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 10 * NS_PER_SEC, intArray, longArray, floatArray, stringArray,
-            boolArray, boolArrayLength, enumArray));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(1, countMetrics.data_size());
-
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-}
-
-TEST(CountMetricE2eTest, TestMatchRepeatedFieldPositionAny) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedStateAnyOnAtomMatcher =
-            CreateTestAtomRepeatedStateAnyOnAtomMatcher();
-    *config.add_atom_matcher() = testAtomReportedStateAnyOnAtomMatcher;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(testAtomReportedStateAnyOnAtomMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(123, 987);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> enumArrayOnFirst = {TestAtomReported::ON, TestAtomReported::OFF};
-    vector<int> enumArrayOnLast = {TestAtomReported::OFF, TestAtomReported::ON};
-    vector<int> enumArrayNoOn = {TestAtomReported::OFF, TestAtomReported::OFF};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnFirst));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayNoOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 60 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnLast));
-    // No matching is done on empty array.
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 80 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs * 2 + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(1, countMetrics.data_size());
-
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-}
-
-TEST(CountMetricE2eTest, TestRepeatedFieldDimension_PositionFirst) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(testAtomReportedAtomMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    *countMetric->mutable_dimensions_in_what() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {14 /*repeated_enum_field*/}, {Position::FIRST});
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(2000, 921);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> enumArrayOnOff = {TestAtomReported::ON, TestAtomReported::OFF};
-    vector<int> enumArrayOnOn = {TestAtomReported::ON, TestAtomReported::ON};
-    vector<int> enumArrayOffOn = {TestAtomReported::OFF, TestAtomReported::ON};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnOff));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOffOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 60 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 80 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(3, countMetrics.data_size());
-
-    // Empty dimensions case.
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 0);
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::OFF);
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::ON);
-}
-
-TEST(CountMetricE2eTest, TestRepeatedFieldDimension_PositionLast) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(testAtomReportedAtomMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    *countMetric->mutable_dimensions_in_what() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {14 /*repeated_enum_field*/}, {Position::LAST});
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(2000, 921);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> enumArrayOnOff = {TestAtomReported::ON, TestAtomReported::OFF};
-    vector<int> enumArrayOffOff = {TestAtomReported::OFF, TestAtomReported::OFF};
-    vector<int> enumArrayOffOn = {TestAtomReported::OFF, TestAtomReported::ON};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnOff));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOffOff));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 60 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOffOn));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(2, countMetrics.data_size());
-
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::OFF);
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::ON);
-}
-
-TEST(CountMetricE2eTest, TestRepeatedFieldDimension_PositionAll) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(testAtomReportedAtomMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    *countMetric->mutable_dimensions_in_what() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {14 /*repeated_enum_field*/}, {Position::ALL});
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(2000, 921);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> enumArrayOnOff = {TestAtomReported::ON, TestAtomReported::OFF};
-    vector<int> enumArrayOnOn = {TestAtomReported::ON, TestAtomReported::ON};
-    vector<int> enumArrayOffOn = {TestAtomReported::OFF, TestAtomReported::ON};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnOff));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOffOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 60 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOffOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOnOff));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOffOn));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    // Don't need to backfill dimension path because dimensions with position ALL are not encoded
-    // with the path format.
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(3, countMetrics.data_size());
-
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        3);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::OFF);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(),
-              TestAtomReported::ON);
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::ON);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(),
-              TestAtomReported::OFF);
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::ON);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(),
-              TestAtomReported::ON);
-}
-
-TEST(CountMetricE2eTest, TestMultipleRepeatedFieldDimensions_PositionFirst) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(testAtomReportedAtomMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    *countMetric->mutable_dimensions_in_what() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/, 14 /*repeated_enum_field*/},
-            {Position::FIRST, Position::FIRST});
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(2000, 921);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> intArrayThree = {3, 6, 9};
-    vector<int> intArraySix = {6, 9};
-    vector<int> enumArrayOn = {TestAtomReported::ON, TestAtomReported::OFF};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, intArrayThree, {}, {}, {}, {}, 0, enumArrayOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, intArraySix, {}, {}, {}, {}, 0, enumArrayOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 60 * NS_PER_SEC, intArrayThree, {}, {}, {}, {}, 0, enumArrayOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 80 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayOn));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 100 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 120 * NS_PER_SEC, intArraySix, {}, {}, {}, {}, 0, {}));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(5, countMetrics.data_size());
-
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 0);
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 6);
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 1);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::ON);
-
-    data = countMetrics.data(3);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 3);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(),
-              TestAtomReported::ON);
-
-    data = countMetrics.data(4);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 6);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(),
-              TestAtomReported::ON);
-}
-
-TEST(CountMetricE2eTest, TestMultipleRepeatedFieldDimensions_PositionAll) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(testAtomReportedAtomMatcher.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    *countMetric->mutable_dimensions_in_what() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/, 14 /*repeated_enum_field*/},
-            {Position::ALL, Position::ALL});
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(2000, 921);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> intArray1 = {3, 6};
-    vector<int> intArray2 = {6, 9};
-    vector<int> enumArray = {TestAtomReported::ON, TestAtomReported::OFF};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, intArray1, {}, {}, {}, {}, 0, enumArray));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 40 * NS_PER_SEC, intArray2, {}, {}, {}, {}, 0, enumArray));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 80 * NS_PER_SEC, intArray1, {}, {}, {}, {}, 0, enumArray));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 100 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArray));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 120 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 140 * NS_PER_SEC, intArray2, {}, {}, {}, {}, 0, {}));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(5, countMetrics.data_size());
-
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 0);
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 6);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(), 9);
-
-    data = countMetrics.data(2);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 2);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(),
-              TestAtomReported::ON);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(),
-              TestAtomReported::OFF);
-
-    data = countMetrics.data(3);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 4);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 3);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(), 6);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(2).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(2).value_int(),
-              TestAtomReported::ON);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(3).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(3).value_int(),
-              TestAtomReported::OFF);
-
-    data = countMetrics.data(4);
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    EXPECT_EQ(util::TEST_ATOM_REPORTED, data.dimensions_in_what().field());
-    ASSERT_EQ(data.dimensions_in_what().value_tuple().dimensions_value_size(), 4);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(0).value_int(), 6);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).field(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(1).value_int(), 9);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(2).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(2).value_int(),
-              TestAtomReported::ON);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(3).field(), 14);
-    EXPECT_EQ(data.dimensions_in_what().value_tuple().dimensions_value(3).value_int(),
-              TestAtomReported::OFF);
-}
-
-TEST(CountMetricE2eTest, TestConditionSlicedByRepeatedUidWithUidDimension) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher uidProcessStateChangedAtomMatcher = CreateUidProcessStateChangedAtomMatcher();
-    AtomMatcher repeatedStateFirstOffAtomMatcher = CreateTestAtomRepeatedStateFirstOffAtomMatcher();
-    AtomMatcher repeatedStateFirstOnAtomMatcher = CreateTestAtomRepeatedStateFirstOnAtomMatcher();
-    *config.add_atom_matcher() = uidProcessStateChangedAtomMatcher;
-    *config.add_atom_matcher() = repeatedStateFirstOffAtomMatcher;
-    *config.add_atom_matcher() = repeatedStateFirstOnAtomMatcher;
-
-    Predicate testAtomRepeatedStateFirstOffPerUidPredicate =
-            CreateTestAtomRepeatedStateFirstOffPredicate();
-    FieldMatcher* dimensions =
-            testAtomRepeatedStateFirstOffPerUidPredicate.mutable_simple_predicate()
-                    ->mutable_dimensions();
-    *dimensions = CreateRepeatedDimensions(util::TEST_ATOM_REPORTED, {9 /* repeated uid*/},
-                                           {Position::FIRST});
-    *config.add_predicate() = testAtomRepeatedStateFirstOffPerUidPredicate;
-
-    int64_t metricId = 123456;
-    CountMetric* countMetric = config.add_count_metric();
-    countMetric->set_id(metricId);
-    countMetric->set_what(uidProcessStateChangedAtomMatcher.id());
-    countMetric->set_condition(testAtomRepeatedStateFirstOffPerUidPredicate.id());
-    countMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    *countMetric->mutable_dimensions_in_what() =
-            CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /*uid*/});
-    MetricConditionLink* links = countMetric->add_links();
-    links->set_condition(testAtomRepeatedStateFirstOffPerUidPredicate.id());
-    *links->mutable_fields_in_what() =
-            CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /* uid*/});
-    *links->mutable_fields_in_condition() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {9 /* repeated uid*/}, {Position::FIRST});
-
-    // Initialize StatsLogProcessor.
-    ConfigKey cfgKey(2000, 921);
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    const uint64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.count_metric(0).bucket()) * 1000000LL;
-    const uint64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    vector<int> intArray1 = {1, 2};
-    vector<int> intArray2 = {2, 1};
-    vector<int> enumArrayOn = {TestAtomReported::ON, TestAtomReported::OFF};
-    vector<int> enumArrayOff = {TestAtomReported::OFF, TestAtomReported::ON};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    // Set condition to true for uid 1.
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, intArray1, {}, {}, {}, {}, 0, enumArrayOff));
-
-    // Uid 1 process state changed.
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 40 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
-    // Uid 2 process state changed. Should not be counted.
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 60 * NS_PER_SEC, 2 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
-
-    // Set condition to true for uid 2.
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 80 * NS_PER_SEC, intArray2, {}, {}, {}, {}, 0, enumArrayOff));
-    // Uid 1 process state changed.
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 100 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
-    // Uid 2 process state changed.
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucketStartTimeNs + 120 * NS_PER_SEC, 2 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
-
-    // Bucket 2
-    // Set condition to false for uid 1.
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucket2StartTimeNs + 20 * NS_PER_SEC, intArray1, {}, {}, {}, {}, 0, enumArrayOn));
-    // Uid 1 process state changed. Should not be counted.
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucket2StartTimeNs + 40 * NS_PER_SEC, 1 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
-    // Uid 2 process state changed.
-    events.push_back(CreateUidProcessStateChangedEvent(
-            bucket2StartTimeNs + 60 * NS_PER_SEC, 2 /*uid*/,
-            android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    // Check dump report.
-    vector<uint8_t> buffer;
-    ConfigMetricsReportList reports;
-    processor->onDumpReport(cfgKey, bucket2StartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
-                            FAST, &buffer);
-    ASSERT_GT(buffer.size(), 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    StatsLogReport::CountMetricDataWrapper countMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
-    ASSERT_EQ(2, countMetrics.data_size());
-
-    CountMetricData data = countMetrics.data(0);
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(1, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        2);
-
-    data = countMetrics.data(1);
-    ASSERT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value_size());
-    EXPECT_EQ(1, data.dimensions_in_what().value_tuple().dimensions_value(0).field());
-    EXPECT_EQ(2, data.dimensions_in_what().value_tuple().dimensions_value(0).value_int());
-    ASSERT_EQ(2, data.bucket_info_size());
-    ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, bucketStartTimeNs + bucketSizeNs,
-                        1);
-    ValidateCountBucket(data.bucket_info(1), bucket2StartTimeNs, bucket2StartTimeNs + bucketSizeNs,
-                        1);
-}
-
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/statsd/tests/e2e/DurationMetric_e2e_test.cpp
index 3202368..8a4c962 100644
--- a/statsd/tests/e2e/DurationMetric_e2e_test.cpp
+++ b/statsd/tests/e2e/DurationMetric_e2e_test.cpp
@@ -1562,93 +1562,6 @@
     EXPECT_EQ(baseTimeNs + bucketSizeNs * 2, data.bucket_info(0).end_bucket_elapsed_nanos());
 }
 
-TEST(DurationMetricE2eTest, TestConditionOnRepeatedEnumField) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher repeatedStateFirstOffAtomMatcher = CreateTestAtomRepeatedStateFirstOffAtomMatcher();
-    AtomMatcher repeatedStateFirstOnAtomMatcher = CreateTestAtomRepeatedStateFirstOnAtomMatcher();
-    *config.add_atom_matcher() = repeatedStateFirstOffAtomMatcher;
-    *config.add_atom_matcher() = repeatedStateFirstOnAtomMatcher;
-
-    Predicate durationPredicate = CreateTestAtomRepeatedStateFirstOffPredicate();
-    *config.add_predicate() = durationPredicate;
-
-    int64_t metricId = 123456;
-    DurationMetric* durationMetric = config.add_duration_metric();
-    durationMetric->set_id(metricId);
-    durationMetric->set_what(durationPredicate.id());
-    durationMetric->set_bucket(FIVE_MINUTES);
-    durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
-
-    const int64_t baseTimeNs = 0;                                   // 0:00
-    const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC;  // 0:01
-    const int64_t bucketSizeNs =
-            TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
-
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
-
-    vector<int> intArray = {3, 6};
-    vector<int64_t> longArray = {1000L, 10002L};
-    vector<float> floatArray = {0.3f, 0.09f};
-    vector<string> stringArray = {"str1", "str2"};
-    int boolArrayLength = 2;
-    bool boolArray[boolArrayLength];
-    boolArray[0] = 1;
-    boolArray[1] = 0;
-    vector<int> enumArrayOff = {TestAtomReported::OFF, TestAtomReported::ON};
-    vector<int> enumArrayOn = {TestAtomReported::ON, TestAtomReported::OFF};
-
-    std::vector<std::unique_ptr<LogEvent>> events;
-    uint64_t falseDurationStartNs = configAddedTimeNs + 10 * NS_PER_SEC;
-    uint64_t durationStartNs = configAddedTimeNs + 20 * NS_PER_SEC;
-    uint64_t durationEndNs = durationStartNs + 50 * NS_PER_SEC;
-
-    // Condition false
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(falseDurationStartNs, {}, {},
-                                                                       {}, {}, {}, 0, enumArrayOn));
-    // Condition true - start collecting duration.
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(durationStartNs, {}, {}, {},
-                                                                       {}, {}, 0, enumArrayOff));
-    // Condition false - stop collecting duration.
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(durationEndNs, {}, {}, {},
-                                                                       {}, {}, 0, enumArrayOn));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
-                            ADB_DUMP, FAST, &buffer);  // 10:01
-    EXPECT_TRUE(buffer.size() > 0);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillDimensionPath(&reports);
-    backfillStartEndTimestamp(&reports);
-    ASSERT_EQ(1, reports.reports_size());
-    ASSERT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
-    EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-
-    StatsLogReport::DurationMetricDataWrapper durationMetrics;
-    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
-                                    &durationMetrics);
-    ASSERT_EQ(1, durationMetrics.data_size());
-
-    DurationMetricData data = durationMetrics.data(0);
-    ASSERT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
-}
-
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/statsd/tests/e2e/EventMetric_e2e_test.cpp b/statsd/tests/e2e/EventMetric_e2e_test.cpp
index 81a6d91..0f66a5a 100644
--- a/statsd/tests/e2e/EventMetric_e2e_test.cpp
+++ b/statsd/tests/e2e/EventMetric_e2e_test.cpp
@@ -101,162 +101,6 @@
     EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl2");
 }
 
-TEST_F(EventMetricE2eTest, TestRepeatedFieldsAndEmptyArrays) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    EventMetric testAtomReportedEventMetric =
-            createEventMetric("EventTestAtomReported", testAtomReportedAtomMatcher.id(), nullopt);
-    *config.add_event_metric() = testAtomReportedEventMetric;
-
-    ConfigKey key(123, 987);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
-
-    // Initialize log events before update.
-    std::vector<std::unique_ptr<LogEvent>> events;
-
-    vector<int> intArray = {3, 6};
-    vector<int64_t> longArray = {1000L, 10002L};
-    vector<float> floatArray = {0.3f, 0.09f};
-    vector<string> stringArray = {"str1", "str2"};
-    int boolArrayLength = 2;
-    bool boolArray[boolArrayLength];
-    boolArray[0] = 1;
-    boolArray[1] = 0;
-    vector<bool> boolArrayVector = {1, 0};
-    vector<int> enumArray = {TestAtomReported::ON, TestAtomReported::OFF};
-
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 10 * NS_PER_SEC, intArray, longArray, floatArray, stringArray,
-            boolArray, boolArrayLength, enumArray));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 30 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArray));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    uint64_t dumpTimeNs = bucketStartTimeNs + 100 * NS_PER_SEC;
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    backfillAggregatedAtoms(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-
-    ConfigMetricsReport report = reports.reports(0);
-    ASSERT_EQ(report.metrics_size(), 1);
-    StatsLogReport testAtomEventMetricReport = report.metrics(0);
-    EXPECT_EQ(testAtomEventMetricReport.metric_id(), testAtomReportedEventMetric.id());
-    EXPECT_TRUE(testAtomEventMetricReport.has_event_metrics());
-    ASSERT_EQ(testAtomEventMetricReport.event_metrics().data_size(), 3);
-
-    EventMetricData data = testAtomEventMetricReport.event_metrics().data(0);
-    EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 10 * NS_PER_SEC);
-    TestAtomReported atom = data.atom().test_atom_reported();
-    EXPECT_THAT(atom.repeated_int_field(), ElementsAreArray(intArray));
-    EXPECT_THAT(atom.repeated_long_field(), ElementsAreArray(longArray));
-    EXPECT_THAT(atom.repeated_float_field(), ElementsAreArray(floatArray));
-    EXPECT_THAT(atom.repeated_string_field(), ElementsAreArray(stringArray));
-    EXPECT_THAT(atom.repeated_boolean_field(), ElementsAreArray(boolArrayVector));
-    EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
-
-    data = testAtomEventMetricReport.event_metrics().data(1);
-    atom = data.atom().test_atom_reported();
-    EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 20 * NS_PER_SEC);
-    EXPECT_EQ(atom.repeated_int_field_size(), 0);
-    EXPECT_EQ(atom.repeated_long_field_size(), 0);
-    EXPECT_EQ(atom.repeated_float_field_size(), 0);
-    EXPECT_EQ(atom.repeated_string_field_size(), 0);
-    EXPECT_EQ(atom.repeated_boolean_field_size(), 0);
-    EXPECT_EQ(atom.repeated_enum_field_size(), 0);
-
-    data = testAtomEventMetricReport.event_metrics().data(2);
-    atom = data.atom().test_atom_reported();
-    EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 30 * NS_PER_SEC);
-    EXPECT_EQ(atom.repeated_int_field_size(), 0);
-    EXPECT_EQ(atom.repeated_long_field_size(), 0);
-    EXPECT_EQ(atom.repeated_float_field_size(), 0);
-    EXPECT_EQ(atom.repeated_string_field_size(), 0);
-    EXPECT_EQ(atom.repeated_boolean_field_size(), 0);
-    EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
-}
-
-TEST_F(EventMetricE2eTest, TestMatchRepeatedFieldPositionFirst) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedStateFirstOnAtomMatcher =
-            CreateTestAtomRepeatedStateFirstOnAtomMatcher();
-    *config.add_atom_matcher() = testAtomReportedStateFirstOnAtomMatcher;
-
-    EventMetric testAtomReportedEventMetric = createEventMetric(
-            "EventTestAtomReported", testAtomReportedStateFirstOnAtomMatcher.id(), nullopt);
-    *config.add_event_metric() = testAtomReportedEventMetric;
-
-    ConfigKey key(123, 987);
-    uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
-
-    // Initialize log events before update.
-    std::vector<std::unique_ptr<LogEvent>> events;
-
-    vector<int> enumArrayNoMatch = {TestAtomReported::OFF, TestAtomReported::ON};
-    vector<int> enumArrayMatch = {TestAtomReported::ON, TestAtomReported::OFF};
-
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 10 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayNoMatch));
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, enumArrayMatch));
-    // No matching is done on an empty array.
-    events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-            bucketStartTimeNs + 30 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-
-    // Send log events to StatsLogProcessor.
-    for (auto& event : events) {
-        processor->OnLogEvent(event.get());
-    }
-
-    uint64_t dumpTimeNs = bucketStartTimeNs + 100 * NS_PER_SEC;
-    ConfigMetricsReportList reports;
-    vector<uint8_t> buffer;
-    processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
-    EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-    backfillStringInReport(&reports);
-    backfillStartEndTimestamp(&reports);
-    backfillAggregatedAtoms(&reports);
-    ASSERT_EQ(reports.reports_size(), 1);
-
-    ConfigMetricsReport report = reports.reports(0);
-    ASSERT_EQ(report.metrics_size(), 1);
-    StatsLogReport testAtomEventMetricReport = report.metrics(0);
-    EXPECT_EQ(testAtomEventMetricReport.metric_id(), testAtomReportedEventMetric.id());
-    EXPECT_TRUE(testAtomEventMetricReport.has_event_metrics());
-    ASSERT_EQ(testAtomEventMetricReport.event_metrics().data_size(), 1);
-
-    EventMetricData data = testAtomEventMetricReport.event_metrics().data(0);
-    EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 20 * NS_PER_SEC);
-    TestAtomReported atom = data.atom().test_atom_reported();
-    ASSERT_EQ(atom.repeated_int_field_size(), 0);
-    ASSERT_EQ(atom.repeated_long_field_size(), 0);
-    ASSERT_EQ(atom.repeated_float_field_size(), 0);
-    ASSERT_EQ(atom.repeated_string_field_size(), 0);
-    ASSERT_EQ(atom.repeated_boolean_field_size(), 0);
-    EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArrayMatch));
-}
-
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
index f5a0158..a4489ba 100644
--- a/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ b/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
@@ -69,50 +69,6 @@
     return config;
 }
 
-StatsdConfig CreateStatsdConfigForRepeatedFieldsPushedEvent(
-        const GaugeMetric::SamplingType sampling_type) {
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedAtomMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedAtomMatcher;
-
-    GaugeMetric* gaugeMetric = config.add_gauge_metric();
-    gaugeMetric->set_id(123456);
-    gaugeMetric->set_what(testAtomReportedAtomMatcher.id());
-    gaugeMetric->set_sampling_type(sampling_type);
-    FieldMatcher* fieldMatcher = gaugeMetric->mutable_gauge_fields_filter()->mutable_fields();
-    fieldMatcher->set_field(util::TEST_ATOM_REPORTED);
-
-    FieldMatcher* childFieldMatcher = fieldMatcher->add_child();
-    childFieldMatcher->set_field(9);  // repeated_int_field
-    childFieldMatcher->set_position(Position::FIRST);
-
-    childFieldMatcher = fieldMatcher->add_child();
-    childFieldMatcher->set_field(10);  // repeated_long_field
-    childFieldMatcher->set_position(Position::LAST);
-
-    childFieldMatcher = fieldMatcher->add_child();
-    childFieldMatcher->set_field(11);  // repeated_float_field
-    childFieldMatcher->set_position(Position::ALL);
-
-    childFieldMatcher = fieldMatcher->add_child();
-    childFieldMatcher->set_field(12);  // repeated_string_field
-    childFieldMatcher->set_position(Position::FIRST);
-
-    childFieldMatcher = fieldMatcher->add_child();
-    childFieldMatcher->set_field(13);  // repeated_boolean_field
-    childFieldMatcher->set_position(Position::LAST);
-
-    childFieldMatcher = fieldMatcher->add_child();
-    childFieldMatcher->set_field(14);  // repeated_enum_field
-    childFieldMatcher->set_position(Position::ALL);
-
-    gaugeMetric->set_bucket(FIVE_MINUTES);
-    return config;
-}
-
 }  // namespace
 
 // Setup for test fixture.
@@ -321,99 +277,6 @@
     }
 }
 
-TEST_F(GaugeMetricE2ePushedTest, TestRepeatedFieldsForPushedEvent) {
-    for (const auto& sampling_type :
-         {GaugeMetric::FIRST_N_SAMPLES, GaugeMetric::RANDOM_ONE_SAMPLE}) {
-        StatsdConfig config = CreateStatsdConfigForRepeatedFieldsPushedEvent(sampling_type);
-        int64_t bucketStartTimeNs = 10000000000;
-        int64_t bucketSizeNs =
-                TimeUnitToBucketSizeInMillis(config.gauge_metric(0).bucket()) * 1000000;
-
-        ConfigKey cfgKey;
-        sp<StatsLogProcessor> processor =
-                CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-        std::vector<std::unique_ptr<LogEvent>> events;
-
-        vector<int> intArray = {3, 6};
-        vector<int64_t> longArray = {1000L, 10002L};
-        vector<float> floatArray = {0.3f, 0.09f};
-        vector<string> stringArray = {"str1", "str2"};
-        int boolArrayLength = 2;
-        bool boolArray[boolArrayLength];
-        boolArray[0] = 1;
-        boolArray[1] = 0;
-        vector<bool> boolArrayVector = {1, 0};
-        vector<int> enumArray = {TestAtomReported::ON, TestAtomReported::OFF};
-
-        events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-                bucketStartTimeNs + 10 * NS_PER_SEC, intArray, longArray, floatArray, stringArray,
-                boolArray, boolArrayLength, enumArray));
-        events.push_back(CreateTestAtomReportedEventVariableRepeatedFields(
-                bucketStartTimeNs + 20 * NS_PER_SEC, {}, {}, {}, {}, {}, 0, {}));
-
-        for (const auto& event : events) {
-            processor->OnLogEvent(event.get());
-        }
-
-        ConfigMetricsReportList reports;
-        vector<uint8_t> buffer;
-        processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true, ADB_DUMP,
-                                FAST, &buffer);
-        EXPECT_TRUE(buffer.size() > 0);
-        EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
-        backfillDimensionPath(&reports);
-        backfillStringInReport(&reports);
-        backfillStartEndTimestamp(&reports);
-        backfillAggregatedAtoms(&reports);
-
-        ASSERT_EQ(1, reports.reports_size());
-        ASSERT_EQ(1, reports.reports(0).metrics_size());
-        StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
-        sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).gauge_metrics(),
-                                        &gaugeMetrics);
-        ASSERT_EQ(1, gaugeMetrics.data_size());
-
-        GaugeMetricData data = gaugeMetrics.data(0);
-        ASSERT_EQ(1, data.bucket_info_size());
-        if (sampling_type == GaugeMetric::FIRST_N_SAMPLES) {
-            EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
-                      data.bucket_info(0).end_bucket_elapsed_nanos());
-            ASSERT_EQ(2, data.bucket_info(0).atom_size());
-
-            TestAtomReported atom = data.bucket_info(0).atom(0).test_atom_reported();
-            EXPECT_THAT(atom.repeated_int_field(), ElementsAreArray({3}));
-            EXPECT_THAT(atom.repeated_long_field(), ElementsAreArray({10002L}));
-            EXPECT_THAT(atom.repeated_float_field(), ElementsAreArray(floatArray));
-            EXPECT_THAT(atom.repeated_string_field(), ElementsAreArray({"str1"}));
-            EXPECT_THAT(atom.repeated_boolean_field(), ElementsAreArray({0}));
-            EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
-
-            atom = data.bucket_info(0).atom(1).test_atom_reported();
-            EXPECT_EQ(atom.repeated_int_field_size(), 0);
-            EXPECT_EQ(atom.repeated_long_field_size(), 0);
-            EXPECT_EQ(atom.repeated_float_field_size(), 0);
-            EXPECT_EQ(atom.repeated_string_field_size(), 0);
-            EXPECT_EQ(atom.repeated_boolean_field_size(), 0);
-            EXPECT_EQ(atom.repeated_enum_field_size(), 0);
-        } else {
-            EXPECT_EQ(bucketStartTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
-            EXPECT_EQ(bucketStartTimeNs + bucketSizeNs,
-                      data.bucket_info(0).end_bucket_elapsed_nanos());
-            ASSERT_EQ(1, data.bucket_info(0).atom_size());
-
-            TestAtomReported atom = data.bucket_info(0).atom(0).test_atom_reported();
-            EXPECT_THAT(atom.repeated_int_field(), ElementsAreArray({3}));
-            EXPECT_THAT(atom.repeated_long_field(), ElementsAreArray({10002L}));
-            EXPECT_THAT(atom.repeated_float_field(), ElementsAreArray(floatArray));
-            EXPECT_THAT(atom.repeated_string_field(), ElementsAreArray({"str1"}));
-            EXPECT_THAT(atom.repeated_boolean_field(), ElementsAreArray({0}));
-            EXPECT_THAT(atom.repeated_enum_field(), ElementsAreArray(enumArray));
-        }
-    }
-}
-
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/statsd/tests/e2e/KllMetric_e2e_test.cpp b/statsd/tests/e2e/KllMetric_e2e_test.cpp
index b62a133..aae5bae 100644
--- a/statsd/tests/e2e/KllMetric_e2e_test.cpp
+++ b/statsd/tests/e2e/KllMetric_e2e_test.cpp
@@ -89,36 +89,6 @@
     EXPECT_EQ(metricReport.kll_metrics().skipped_size(), 0);
 }
 
-TEST_F(KllMetricE2eTest, TestInitWithKllFieldPositionALL) {
-    // Create config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedMatcher;
-
-    // Create kll metric.
-    int64_t metricId = 123456;
-    KllMetric* kllMetric = config.add_kll_metric();
-    kllMetric->set_id(metricId);
-    kllMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    kllMetric->set_what(testAtomReportedMatcher.id());
-    *kllMetric->mutable_kll_field() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Config initialization fails.
-    ASSERT_EQ(0, processor->mMetricsManagers.size());
-}
-
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index 176fd9c..fe2bdcf 100644
--- a/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -20,7 +20,6 @@
 
 #include "src/StatsLogProcessor.h"
 #include "src/StatsService.h"
-#include "src/packages/UidMap.h"
 #include "src/stats_log_util.h"
 #include "tests/statsd_test_util.h"
 
@@ -123,8 +122,7 @@
 }  // anonymous namespace
 
 TEST(PartialBucketE2eTest, TestCountMetricWithoutSplit) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeCountMetricConfig({true}));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -139,8 +137,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnNewApp) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeCountMetricConfig({true}));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -160,8 +157,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnUpgrade) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeCountMetricConfig({true}));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -195,8 +191,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnRemoval) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeCountMetricConfig({true}));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -229,8 +224,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricSplitOnBoot) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     SendConfig(service, MakeCountMetricConfig(std::nullopt));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
                                              // initialized with.
@@ -259,8 +253,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricNoSplitOnUpgradeWhenDisabled) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     StatsdConfig config = MakeCountMetricConfig({false});
     SendConfig(service, config);
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
@@ -288,8 +281,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     service->mPullerManager->RegisterPullAtomCallback(
             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
             SharedRefBase::make<FakeSubsystemSleepCallback>());
@@ -320,8 +312,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricWithMinPartialBucket) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     service->mPullerManager->RegisterPullAtomCallback(
             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
             SharedRefBase::make<FakeSubsystemSleepCallback>());
@@ -353,8 +344,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestValueMetricOnBootWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     // Initial pull will fail since puller is not registered.
     SendConfig(service, MakeValueMetricConfig(0));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
@@ -387,8 +377,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     service->mPullerManager->RegisterPullAtomCallback(
             /*uid=*/0, util::SUBSYSTEM_SLEEP_STATE, NS_PER_SEC, NS_PER_SEC * 10, {},
             SharedRefBase::make<FakeSubsystemSleepCallback>());
@@ -413,8 +402,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricWithMinPartialBucket) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     // Partial buckets don't occur when app is first installed.
     service->mUidMap->updateApp(1, String16(kApp1.c_str()), 1, 1, String16("v1"), String16(""),
                                 /* certificateHash */ {});
@@ -444,8 +432,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestGaugeMetricOnBootWithoutMinPartialBucket) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     // Initial pull will fail since puller hasn't been registered.
     SendConfig(service, MakeGaugeMetricConfig(0));
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
@@ -475,8 +462,7 @@
 }
 
 TEST(PartialBucketE2eTest, TestCountMetricNoSplitByDefault) {
-    shared_ptr<StatsService> service =
-            SharedRefBase::make<StatsService>(new UidMap(), /* queue */ nullptr);
+    shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
     StatsdConfig config = MakeCountMetricConfig({nullopt});  // Do not set the value in the metric.
     SendConfig(service, config);
     int64_t start = getElapsedRealtimeNs();  // This is the start-time the metrics producers are
diff --git a/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index 1ea757a..c0059a2 100644
--- a/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -670,36 +670,6 @@
     ASSERT_EQ(0, processor->mMetricsManagers.size());
 }
 
-TEST(ValueMetricE2eTest, TestInitWithValueFieldPositionALL) {
-    // Create config.
-    StatsdConfig config;
-    config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
-
-    AtomMatcher testAtomReportedMatcher =
-            CreateSimpleAtomMatcher("TestAtomReportedMatcher", util::TEST_ATOM_REPORTED);
-    *config.add_atom_matcher() = testAtomReportedMatcher;
-
-    // Create value metric.
-    int64_t metricId = 123456;
-    ValueMetric* valueMetric = config.add_value_metric();
-    valueMetric->set_id(metricId);
-    valueMetric->set_bucket(TimeUnit::FIVE_MINUTES);
-    valueMetric->set_what(testAtomReportedMatcher.id());
-    *valueMetric->mutable_value_field() = CreateRepeatedDimensions(
-            util::TEST_ATOM_REPORTED, {9 /*repeated_int_field*/}, {Position::ALL});
-
-    // Initialize StatsLogProcessor.
-    const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
-    int uid = 12345;
-    int64_t cfgId = 98765;
-    ConfigKey cfgKey(uid, cfgId);
-    sp<StatsLogProcessor> processor =
-            CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
-
-    // Config initialization fails.
-    ASSERT_EQ(0, processor->mMetricsManagers.size());
-}
-
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
 #endif
diff --git a/statsd/tests/external/puller_util_test.cpp b/statsd/tests/external/puller_util_test.cpp
index 25c0c7e..0fca512 100644
--- a/statsd/tests/external/puller_util_test.cpp
+++ b/statsd/tests/external/puller_util_test.cpp
@@ -430,217 +430,6 @@
               actualFieldValues->at(5).mValue.int_value);
 }
 
-// Test that repeated fields are treated as non-additive fields even when marked as additive.
-TEST(PullerUtilTest, RepeatedAdditiveField) {
-    vector<int> int32Array1 = {3, 6};
-    vector<int> int32Array2 = {6, 9};
-
-    vector<shared_ptr<LogEvent>> data = {
-            // 30->22->{3,6}
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
-                            int32Array1),
-
-            // 30->22->{6,9}
-            makeUidLogEvent(uidAtomTagId, timestamp, isolatedUid1, hostNonAdditiveData,
-                            int32Array2),
-
-            // 20->22->{3,6}
-            makeUidLogEvent(uidAtomTagId, timestamp, hostUid, hostNonAdditiveData, int32Array1),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
-    ASSERT_EQ(2, (int)data.size());
-    // Events 1 and 3 are merged - non-additive fields, including the repeated additive field, are
-    // equal.
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(4, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(3, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(6, actualFieldValues->at(3).mValue.int_value);
-
-    // Event 2 isn't merged - repeated additive field is not equal.
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(4, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(6, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(9, actualFieldValues->at(3).mValue.int_value);
-}
-
-// Test that repeated uid events are sorted and merged correctly.
-TEST(PullerUtilTest, RepeatedUidField) {
-    vector<int> uidArray1 = {isolatedUid1, hostUid};
-    vector<int> uidArray2 = {isolatedUid1, isolatedUid3};
-    vector<int> uidArray3 = {isolatedUid1, hostUid, isolatedUid2};
-
-    vector<shared_ptr<LogEvent>> data = {
-            // {30, 20}->22->21
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostNonAdditiveData,
-                                    hostAdditiveData),
-
-            // {30, 3000}->22->21 (different uid, not merged)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray2, hostNonAdditiveData,
-                                    hostAdditiveData),
-
-            // {30, 20}->22->31 (different additive field, merged)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostNonAdditiveData,
-                                    isolatedAdditiveData),
-
-            // {30, 20}->32->21 (different non-additive field, not merged)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, isolatedNonAdditiveData,
-                                    hostAdditiveData),
-
-            // {30, 20, 40}->22->21 (different repeated uid length, not merged)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray3, hostNonAdditiveData,
-                                    hostAdditiveData),
-
-            // {30, 20}->22->21 (same as first event, merged)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostNonAdditiveData,
-                                    hostAdditiveData),
-    };
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, additiveFields);
-
-    ASSERT_EQ(4, (int)data.size());
-    // Events 1 and 3 and 6 are merged.
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(4, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData + isolatedAdditiveData + hostAdditiveData,
-              actualFieldValues->at(3).mValue.int_value);
-
-    // Event 4 isn't merged - different non-additive data.
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(4, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(isolatedNonAdditiveData, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(3).mValue.int_value);
-
-    // Event 2 isn't merged - different uid.
-    actualFieldValues = &data[2]->getValues();
-    ASSERT_EQ(4, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid2, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(3).mValue.int_value);
-
-    // Event 5 isn't merged - different repeated uid length.
-    actualFieldValues = &data[3]->getValues();
-    ASSERT_EQ(5, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(hostNonAdditiveData, actualFieldValues->at(3).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(4).mValue.int_value);
-}
-
-// Test that repeated uid events with multiple repeated non-additive fields are sorted and merged
-// correctly.
-TEST(PullerUtilTest, MultipleRepeatedFields) {
-    vector<int> uidArray1 = {isolatedUid1, hostUid};
-    vector<int> uidArray2 = {isolatedUid1, isolatedUid3};
-    vector<int> uidArray3 = {isolatedUid1, hostUid, isolatedUid2};
-
-    vector<int> nonAdditiveArray1 = {1, 2, 3};
-    vector<int> nonAdditiveArray2 = {1, 5, 3};
-    vector<int> nonAdditiveArray3 = {1, 2};
-
-    const vector<int> secondAdditiveField = {2};
-
-    vector<shared_ptr<LogEvent>> data = {
-            // TODO: Once b/224880904 is fixed, can use different additive data without
-            // having the sort order messed up.
-
-            // Event 1 {30, 20}->21->{1, 2, 3} (merged with event 4)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostAdditiveData,
-                                    nonAdditiveArray1),
-
-            // Event 2 {30, 3000}->21->{1, 2, 3} (different uid, not merged)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray2, hostAdditiveData,
-                                    nonAdditiveArray1),
-
-            // Event 3 {30, 20, 40}->21->{1, 2} (different repeated fields with total length equal
-            // to event 1, merged with event 6)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray3, hostAdditiveData,
-                                    nonAdditiveArray3),
-
-            // Event 4 {30, 20}->21->{1, 2, 3} (merged with event 1)
-            // TODO: once sorting bug is fixed, can change this additive field
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostAdditiveData,
-                                    nonAdditiveArray1),
-
-            // Event 5 {30, 20}->21->{1, 5, 3} (different repeated field, not merged)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray1, hostAdditiveData,
-                                    nonAdditiveArray2),
-
-            // Event 6 {30, 20, 40}->22->{1, 2} (different repeated fields with total length equal
-            // to event 1, merged with event 3)
-            makeRepeatedUidLogEvent(uidAtomTagId, timestamp, uidArray3, isolatedAdditiveData,
-                                    nonAdditiveArray3),
-    };
-
-    // Expected event ordering after the sort:
-    // Event 3 {30, 20, 40}->21->{1, 2} (total size equal to event 1, merged with event 6)
-    // Event 6 {30, 20, 40}->22->{1, 2} (total size equal to event 1, merged with event 3)
-    // Event 1 {30, 20}->21->{1, 2, 3}
-    // Event 4 {30, 20}->21->{1, 2, 3} (merged with event 1)
-    // Event 5 {30, 20}->21->{1, 5, 3} (different repeated field, not merged)
-    // Event 2 {30, 3000}->21->{1, 2, 3} (different uid, not merged)
-
-    sp<MockUidMap> uidMap = makeMockUidMap();
-    mapAndMergeIsolatedUidsToHostUid(data, uidMap, uidAtomTagId, secondAdditiveField);
-
-    ASSERT_EQ(4, (int)data.size());
-
-    // Events 3 and 6 are merged. Not merged with event 1 because different repeated uids and
-    // fields, though length is same.
-    const vector<FieldValue>* actualFieldValues = &data[0]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData + isolatedAdditiveData, actualFieldValues->at(3).mValue.int_value);
-    EXPECT_EQ(1, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(2, actualFieldValues->at(5).mValue.int_value);
-
-    // Events 1 and 4 are merged.
-    actualFieldValues = &data[1]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData + hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(1, actualFieldValues->at(3).mValue.int_value);
-    EXPECT_EQ(2, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(3, actualFieldValues->at(5).mValue.int_value);
-
-    // Event 5 isn't merged - different repeated field.
-    actualFieldValues = &data[2]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(1, actualFieldValues->at(3).mValue.int_value);
-    EXPECT_EQ(5, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(3, actualFieldValues->at(5).mValue.int_value);
-
-    // Event 2 isn't merged - different uid.
-    actualFieldValues = &data[3]->getValues();
-    ASSERT_EQ(6, actualFieldValues->size());
-    EXPECT_EQ(hostUid, actualFieldValues->at(0).mValue.int_value);
-    EXPECT_EQ(hostUid2, actualFieldValues->at(1).mValue.int_value);
-    EXPECT_EQ(hostAdditiveData, actualFieldValues->at(2).mValue.int_value);
-    EXPECT_EQ(1, actualFieldValues->at(3).mValue.int_value);
-    EXPECT_EQ(2, actualFieldValues->at(4).mValue.int_value);
-    EXPECT_EQ(3, actualFieldValues->at(5).mValue.int_value);
-}
-
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/metrics/KllMetricProducer_test.cpp b/statsd/tests/metrics/KllMetricProducer_test.cpp
index e84efb0..334a21b 100644
--- a/statsd/tests/metrics/KllMetricProducer_test.cpp
+++ b/statsd/tests/metrics/KllMetricProducer_test.cpp
@@ -121,8 +121,7 @@
                 TimeUnitToBucketSizeInMillisGuardrailed(kConfigKey.GetUid(), metric.bucket()));
         const bool containsAnyPositionInDimensionsInWhat =
                 HasPositionANY(metric.dimensions_in_what());
-        const bool shouldUseNestedDimensions =
-                ShouldUseNestedDimensions(metric.dimensions_in_what());
+        const bool sliceByPositionAll = HasPositionALL(metric.dimensions_in_what());
 
         vector<Matcher> fieldMatchers;
         translateFieldMatcher(metric.kll_field(), &fieldMatchers);
@@ -140,8 +139,7 @@
                 kConfigKey, metric, protoHash, {/*pullAtomId=*/-1, /*pullerManager=*/nullptr},
                 {timeBaseNs, startTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
                  /*conditionCorrectionThresholdNs=*/nullopt, metric.split_bucket_for_app_upgrade()},
-                {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions,
-                 logEventMatcherIndex,
+                {containsAnyPositionInDimensionsInWhat, sliceByPositionAll, logEventMatcherIndex,
                  /*eventMatcherWizard=*/nullptr, metric.dimensions_in_what(), fieldMatchers},
                 {conditionIndex, metric.links(), initialConditionCache, wizard},
                 {metric.state_link(), slicedStateAtoms, stateGroupMap},
diff --git a/statsd/tests/metrics/NumericValueMetricProducer_test.cpp b/statsd/tests/metrics/NumericValueMetricProducer_test.cpp
index 1b5abaf..35e31a0 100644
--- a/statsd/tests/metrics/NumericValueMetricProducer_test.cpp
+++ b/statsd/tests/metrics/NumericValueMetricProducer_test.cpp
@@ -186,8 +186,7 @@
                 TimeUnitToBucketSizeInMillisGuardrailed(kConfigKey.GetUid(), metric.bucket()));
         const bool containsAnyPositionInDimensionsInWhat =
                 HasPositionANY(metric.dimensions_in_what());
-        const bool shouldUseNestedDimensions =
-                ShouldUseNestedDimensions(metric.dimensions_in_what());
+        const bool sliceByPositionAll = HasPositionALL(metric.dimensions_in_what());
 
         vector<Matcher> fieldMatchers;
         translateFieldMatcher(metric.value_field(), &fieldMatchers);
@@ -211,9 +210,8 @@
                 kConfigKey, metric, protoHash, {pullAtomId, pullerManager},
                 {timeBaseNs, startTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
                  conditionCorrectionThresholdNs, metric.split_bucket_for_app_upgrade()},
-                {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions,
-                 logEventMatcherIndex, eventMatcherWizard, metric.dimensions_in_what(),
-                 fieldMatchers},
+                {containsAnyPositionInDimensionsInWhat, sliceByPositionAll, logEventMatcherIndex,
+                 eventMatcherWizard, metric.dimensions_in_what(), fieldMatchers},
                 {conditionIndex, metric.links(), initialConditionCache, wizard},
                 {metric.state_link(), slicedStateAtoms, stateGroupMap},
                 {/*eventActivationMap=*/{}, /*eventDeactivationMap=*/{}},
@@ -255,25 +253,24 @@
         metric.add_slice_by_state(StringToId(state));
         return metric;
     }
-
-    static ValueMetric createMetricWithRepeatedValueField() {
-        ValueMetric metric;
-        metric.set_id(metricId);
-        metric.set_bucket(ONE_MINUTE);
-        metric.mutable_value_field()->set_field(tagId);
-        FieldMatcher* valueChild = metric.mutable_value_field()->add_child();
-        valueChild->set_field(3);
-        valueChild->set_position(Position::FIRST);
-        metric.set_max_pull_delay_sec(INT_MAX);
-        metric.set_split_bucket_for_app_upgrade(true);
-        metric.set_aggregation_type(ValueMetric_AggregationType_SUM);
-        return metric;
-    }
 };
 
 // Setup for parameterized tests.
 class NumericValueMetricProducerTest_PartialBucket : public TestWithParam<BucketSplitEvent> {};
 
+class NumericValueMetricProducerTest_SubsetDimensions : public ::testing::Test {
+    void SetUp() override {
+        FlagProvider::getInstance().overrideFuncs(&isAtLeastSFuncTrue);
+        FlagProvider::getInstance().overrideFlag(VALUE_METRIC_SUBSET_DIMENSION_AGGREGATION_FLAG,
+                                                 FLAG_FALSE,
+                                                 /*isBootFlag=*/true);
+    }
+
+    void TearDown() override {
+        FlagProvider::getInstance().resetOverrides();
+    }
+};
+
 INSTANTIATE_TEST_SUITE_P(NumericValueMetricProducerTest_PartialBucket,
                          NumericValueMetricProducerTest_PartialBucket,
                          testing::Values(APP_UPGRADE, BOOT_COMPLETE));
@@ -7340,7 +7337,10 @@
                         60 * NS_PER_SEC, 0);
 }
 
-TEST(NumericValueMetricProducerTest, TestSubsetDimensions) {
+TEST_F(NumericValueMetricProducerTest_SubsetDimensions, TestSubsetDimensions_FlagTrue) {
+    FlagProvider::getInstance().overrideFlag(VALUE_METRIC_SUBSET_DIMENSION_AGGREGATION_FLAG,
+                                             FLAG_TRUE, /*isBootFlag=*/true);
+
     // Create metric with subset of dimensions.
     ValueMetric metric = NumericValueMetricProducerTestHelper::createMetric();
     *metric.mutable_dimensions_in_what() = CreateDimensions(tagId, {1 /*uid*/});
@@ -7426,36 +7426,41 @@
     ValidateValueBucket(data.bucket_info(1), bucket2StartTimeNs, dumpReportTimeNs, {26}, -1, 0);
 }
 
-TEST(NumericValueMetricProducerTest, TestRepeatedValueFieldAndDimensions) {
-    ValueMetric metric = NumericValueMetricProducerTestHelper::createMetricWithRepeatedValueField();
-    metric.mutable_dimensions_in_what()->set_field(tagId);
-    FieldMatcher* valueChild = metric.mutable_dimensions_in_what()->add_child();
-    valueChild->set_field(1);
-    valueChild->set_position(Position::FIRST);
+TEST_F(NumericValueMetricProducerTest_SubsetDimensions, TestSubsetDimensions_FlagFalse) {
+    // Create metric with subset of dimensions.
+    ValueMetric metric = NumericValueMetricProducerTestHelper::createMetric();
+    *metric.mutable_dimensions_in_what() = CreateDimensions(tagId, {1 /*uid*/});
 
     sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
 
     EXPECT_CALL(*pullerManager, Pull(tagId, kConfigKey, _, _))
-            // First field is a dimension field (repeated, position FIRST).
-            // Third field is the value field (repeated, position FIRST).
-            // NumericValueMetricProducer initialized.
+            // First and third fields are dimension fields. Second field is the value field.
+            // First bucket pull.
             .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data) {
                 data->clear();
                 data->push_back(
-                        makeRepeatedUidLogEvent(tagId, bucketStartTimeNs + 1, {1, 10}, 5, {2, 3}));
+                        CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 1, 1 /*uid*/, 5, 5));
                 data->push_back(
-                        makeRepeatedUidLogEvent(tagId, bucketStartTimeNs + 1, {2, 10}, 5, {3, 4}));
+                        CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 1, 1 /*uid*/, 5, 7));
+                data->push_back(
+                        CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 1, 2 /*uid*/, 6, 5));
+                data->push_back(
+                        CreateThreeValueLogEvent(tagId, bucketStartTimeNs + 1, 2 /*uid*/, 6, 7));
                 return true;
             }))
-            // Dump report pull.
+            // Dump report.
             .WillOnce(Invoke([](int tagId, const ConfigKey&, const int64_t eventTimeNs,
                                 vector<std::shared_ptr<LogEvent>>* data) {
                 data->clear();
-                data->push_back(makeRepeatedUidLogEvent(tagId, bucket2StartTimeNs + 10000000000,
-                                                        {1, 10}, 5, {10, 3}));
-                data->push_back(makeRepeatedUidLogEvent(tagId, bucket2StartTimeNs + 10000000000,
-                                                        {2, 10}, 5, {14, 4}));
+                data->push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 10000000000,
+                                                         1 /*uid*/, 13, 5));
+                data->push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 10000000000,
+                                                         1 /*uid*/, 15, 7));
+                data->push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 10000000000,
+                                                         2 /*uid*/, 21, 5));
+                data->push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 10000000000,
+                                                         2 /*uid*/, 22, 7));
                 return true;
             }));
 
@@ -7466,8 +7471,10 @@
     // Bucket 2 start.
     vector<shared_ptr<LogEvent>> allData;
     allData.clear();
-    allData.push_back(makeRepeatedUidLogEvent(tagId, bucket2StartTimeNs + 1, {1, 10}, 5, {5, 7}));
-    allData.push_back(makeRepeatedUidLogEvent(tagId, bucket2StartTimeNs + 1, {2, 10}, 5, {7, 5}));
+    allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, 1 /*uid*/, 10, 5));
+    allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, 1 /*uid*/, 11, 7));
+    allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, 2 /*uid*/, 8, 5));
+    allData.push_back(CreateThreeValueLogEvent(tagId, bucket2StartTimeNs + 1, 2 /*uid*/, 9, 7));
     valueProducer->onDataPulled(allData, /** succeed */ true, bucket2StartTimeNs);
 
     // Check dump report.
@@ -7490,19 +7497,19 @@
     ValueMetricData data = valueMetrics.data(0);
     ValidateUidDimension(data.dimensions_in_what(), tagId, 1);
     ASSERT_EQ(2, data.bucket_info_size());
-    ValidateValueBucket(data.bucket_info(0), bucketStartTimeNs, bucket2StartTimeNs, {3}, -1,
-                        0);  // Summed diffs of 2, 5
-    ValidateValueBucket(data.bucket_info(1), bucket2StartTimeNs, dumpReportTimeNs, {5}, -1,
-                        0);  // Summed diffs of 5, 10
+    ValidateValueBucket(data.bucket_info(0), bucketStartTimeNs, bucket2StartTimeNs, {6}, -1,
+                        0);  // Summed diffs of 5, 5, 10, 11
+    ValidateValueBucket(data.bucket_info(1), bucket2StartTimeNs, dumpReportTimeNs, {4}, -1,
+                        0);  // Summed diffs of 11, 13, 15
 
     // Check data keyed to uid 2.
     data = valueMetrics.data(1);
     ValidateUidDimension(data.dimensions_in_what(), tagId, 2);
     ASSERT_EQ(2, data.bucket_info_size());
-    ValidateValueBucket(data.bucket_info(0), bucketStartTimeNs, bucket2StartTimeNs, {4}, -1,
-                        0);  // Summed diffs of 3, 7
-    ValidateValueBucket(data.bucket_info(1), bucket2StartTimeNs, dumpReportTimeNs, {7}, -1,
-                        0);  // Summed diffs of 7, 14
+    ValidateValueBucket(data.bucket_info(0), bucketStartTimeNs, bucket2StartTimeNs, {3}, -1,
+                        0);  // Summed diffs of 6, 6, 8, 9
+    ValidateValueBucket(data.bucket_info(1), bucket2StartTimeNs, dumpReportTimeNs, {13}, -1,
+                        0);  // Summed diffs of 9, 21, 22
 }
 
 }  // namespace statsd
diff --git a/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp b/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
index 16180c0..b9eb28e 100644
--- a/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
+++ b/statsd/tests/metrics/parsing_utils/config_update_utils_test.cpp
@@ -63,57 +63,41 @@
         /*minDiffToUpdateRegisteredAlarmTimeSec=*/0,
         [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
         [](const shared_ptr<IStatsCompanionService>&) {});
-unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+set<int> allTagIds;
 vector<sp<AtomMatchingTracker>> oldAtomMatchingTrackers;
 unordered_map<int64_t, int> oldAtomMatchingTrackerMap;
 vector<sp<ConditionTracker>> oldConditionTrackers;
 unordered_map<int64_t, int> oldConditionTrackerMap;
 vector<sp<MetricProducer>> oldMetricProducers;
 unordered_map<int64_t, int> oldMetricProducerMap;
-vector<sp<AnomalyTracker>> oldAnomalyTrackers;
+std::vector<sp<AnomalyTracker>> oldAnomalyTrackers;
 unordered_map<int64_t, int> oldAlertTrackerMap;
-vector<sp<AlarmTracker>> oldAlarmTrackers;
-unordered_map<int, vector<int>> tmpConditionToMetricMap;
-unordered_map<int, vector<int>> tmpTrackerToMetricMap;
-unordered_map<int, vector<int>> tmpTrackerToConditionMap;
-unordered_map<int, vector<int>> tmpActivationAtomTrackerToMetricMap;
-unordered_map<int, vector<int>> tmpDeactivationAtomTrackerToMetricMap;
+std::vector<sp<AlarmTracker>> oldAlarmTrackers;
+unordered_map<int, std::vector<int>> tmpConditionToMetricMap;
+unordered_map<int, std::vector<int>> tmpTrackerToMetricMap;
+unordered_map<int, std::vector<int>> tmpTrackerToConditionMap;
+unordered_map<int, std::vector<int>> tmpActivationAtomTrackerToMetricMap;
+unordered_map<int, std::vector<int>> tmpDeactivationAtomTrackerToMetricMap;
 vector<int> metricsWithActivation;
 map<int64_t, uint64_t> oldStateHashes;
-set<int64_t> noReportMetricIds;
+std::set<int64_t> noReportMetricIds;
 
 bool initConfig(const StatsdConfig& config) {
     return initStatsdConfig(
             key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseNs, timeBaseNs, allTagIdsToMatchersMap, oldAtomMatchingTrackers,
-            oldAtomMatchingTrackerMap, oldConditionTrackers, oldConditionTrackerMap,
-            oldMetricProducers, oldMetricProducerMap, oldAnomalyTrackers, oldAlarmTrackers,
-            tmpConditionToMetricMap, tmpTrackerToMetricMap, tmpTrackerToConditionMap,
-            tmpActivationAtomTrackerToMetricMap, tmpDeactivationAtomTrackerToMetricMap,
-            oldAlertTrackerMap, metricsWithActivation, oldStateHashes, noReportMetricIds);
+            timeBaseNs, timeBaseNs, allTagIds, oldAtomMatchingTrackers, oldAtomMatchingTrackerMap,
+            oldConditionTrackers, oldConditionTrackerMap, oldMetricProducers, oldMetricProducerMap,
+            oldAnomalyTrackers, oldAlarmTrackers, tmpConditionToMetricMap, tmpTrackerToMetricMap,
+            tmpTrackerToConditionMap, tmpActivationAtomTrackerToMetricMap,
+            tmpDeactivationAtomTrackerToMetricMap, oldAlertTrackerMap, metricsWithActivation,
+            oldStateHashes, noReportMetricIds);
 }
-
-vector<int> filterMatcherIndexesById(const vector<sp<AtomMatchingTracker>>& atomMatchingTrackers,
-                                     const vector<int64_t>& ids) {
-    vector<int> result;
-
-    for (auto& id : ids) {
-        for (int i = 0; i < atomMatchingTrackers.size(); i++) {
-            if (atomMatchingTrackers[i]->getId() == id) {
-                result.push_back(i);
-            }
-        }
-    }
-
-    return result;
-}
-
 }  // anonymous namespace
 
 class ConfigUpdateTest : public ::testing::Test {
 public:
     void SetUp() override {
-        allTagIdsToMatchersMap.clear();
+        allTagIds.clear();
         oldAtomMatchingTrackers.clear();
         oldAtomMatchingTrackerMap.clear();
         oldConditionTrackers.clear();
@@ -398,7 +382,7 @@
     *newConfig.add_atom_matcher() = simple4;
     *newConfig.add_atom_matcher() = combination1;
 
-    unordered_map<int, vector<int>> newTagIds;
+    set<int> newTagIds;
     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
     set<int64_t> replacedMatchers;
@@ -411,19 +395,6 @@
     EXPECT_EQ(newTagIds.count(111), 1);
     EXPECT_EQ(newTagIds.count(13), 1);
 
-    EXPECT_EQ(newTagIds[10].size(), 3);  // simple1, combination1, combination2
-    EXPECT_THAT(newTagIds[10], UnorderedElementsAreArray(filterMatcherIndexesById(
-                                       newAtomMatchingTrackers,
-                                       {simple1.id(), combination1.id(), combination2.id()})));
-    EXPECT_EQ(newTagIds[111].size(), 3);  // simple2, combination2, combination3
-    EXPECT_THAT(newTagIds[111], UnorderedElementsAreArray(filterMatcherIndexesById(
-                                        newAtomMatchingTrackers,
-                                        {simple2.id(), combination2.id(), combination3.id()})));
-    EXPECT_EQ(newTagIds[13].size(), 2);  // simple4, combination3
-    EXPECT_THAT(newTagIds[13],
-                UnorderedElementsAreArray(filterMatcherIndexesById(
-                        newAtomMatchingTrackers, {simple4.id(), combination3.id()})));
-
     ASSERT_EQ(newAtomMatchingTrackerMap.size(), 6);
     EXPECT_EQ(newAtomMatchingTrackerMap.at(combination3Id), 0);
     EXPECT_EQ(newAtomMatchingTrackerMap.at(simple2Id), 1);
@@ -828,8 +799,8 @@
     unordered_map<int64_t, int> newConditionTrackerMap;
     vector<sp<ConditionTracker>> newConditionTrackers;
     unordered_map<int, vector<int>> trackerToConditionMap;
-    vector<ConditionState> conditionCache;
-    set<int64_t> replacedConditions;
+    std::vector<ConditionState> conditionCache;
+    std::set<int64_t> replacedConditions;
     EXPECT_TRUE(updateConditions(key, newConfig, newAtomMatchingTrackerMap, replacedMatchers,
                                  oldConditionTrackerMap, oldConditionTrackers,
                                  newConditionTrackerMap, newConditionTrackers,
diff --git a/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp b/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
index 8aa7f46..85806e7 100644
--- a/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
+++ b/statsd/tests/metrics/parsing_utils/metrics_manager_util_test.cpp
@@ -384,20 +384,20 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildConfigWithDifferentPredicates();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
@@ -405,10 +405,10 @@
 
     EXPECT_TRUE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
     ASSERT_EQ(4u, allMetricProducers.size());
@@ -429,11 +429,6 @@
     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[1]->mCondition);
     EXPECT_EQ(ConditionState::kFalse, allMetricProducers[2]->mCondition);
     EXPECT_EQ(ConditionState::kUnknown, allMetricProducers[3]->mCondition);
-
-    EXPECT_EQ(allTagIdsToMatchersMap.size(), 3);
-    EXPECT_EQ(allTagIdsToMatchersMap[util::SCREEN_STATE_CHANGED].size(), 2);
-    EXPECT_EQ(allTagIdsToMatchersMap[util::PLUGGED_STATE_CHANGED].size(), 2);
-    EXPECT_EQ(allTagIdsToMatchersMap[util::SUBSYSTEM_SLEEP_STATE].size(), 1);
 }
 
 TEST(MetricsManagerTest, TestGoodConfig) {
@@ -442,20 +437,20 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildGoodConfig();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
@@ -463,10 +458,10 @@
 
     EXPECT_TRUE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
     ASSERT_EQ(1u, allMetricProducers.size());
@@ -484,20 +479,20 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildDimensionMetricsWithMultiTags();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
@@ -505,10 +500,10 @@
 
     EXPECT_FALSE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
 }
@@ -519,20 +514,20 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildCircleMatchers();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
@@ -540,10 +535,10 @@
 
     EXPECT_FALSE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
 }
@@ -554,30 +549,30 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildMissingMatchers();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
     std::set<int64_t> noReportMetricIds;
     EXPECT_FALSE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
 }
@@ -588,30 +583,30 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildMissingPredicate();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
     std::set<int64_t> noReportMetricIds;
     EXPECT_FALSE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
 }
@@ -622,20 +617,20 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildCirclePredicates();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
@@ -643,10 +638,10 @@
 
     EXPECT_FALSE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
 }
@@ -657,20 +652,20 @@
     sp<AlarmMonitor> anomalyAlarmMonitor;
     sp<AlarmMonitor> periodicAlarmMonitor;
     StatsdConfig config = buildAlertWithUnknownMetric();
-    unordered_map<int, vector<int>> allTagIdsToMatchersMap;
+    set<int> allTagIds;
     vector<sp<AtomMatchingTracker>> allAtomMatchingTrackers;
     unordered_map<int64_t, int> atomMatchingTrackerMap;
     vector<sp<ConditionTracker>> allConditionTrackers;
     unordered_map<int64_t, int> conditionTrackerMap;
     vector<sp<MetricProducer>> allMetricProducers;
     unordered_map<int64_t, int> metricProducerMap;
-    vector<sp<AnomalyTracker>> allAnomalyTrackers;
-    vector<sp<AlarmTracker>> allAlarmTrackers;
-    unordered_map<int, vector<int>> conditionToMetricMap;
-    unordered_map<int, vector<int>> trackerToMetricMap;
-    unordered_map<int, vector<int>> trackerToConditionMap;
-    unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
-    unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
+    std::vector<sp<AnomalyTracker>> allAnomalyTrackers;
+    std::vector<sp<AlarmTracker>> allAlarmTrackers;
+    unordered_map<int, std::vector<int>> conditionToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToMetricMap;
+    unordered_map<int, std::vector<int>> trackerToConditionMap;
+    unordered_map<int, std::vector<int>> activationAtomTrackerToMetricMap;
+    unordered_map<int, std::vector<int>> deactivationAtomTrackerToMetricMap;
     unordered_map<int64_t, int> alertTrackerMap;
     vector<int> metricsWithActivation;
     map<int64_t, uint64_t> stateProtoHashes;
@@ -678,10 +673,10 @@
 
     EXPECT_FALSE(initStatsdConfig(
             kConfigKey, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
-            timeBaseSec, timeBaseSec, allTagIdsToMatchersMap, allAtomMatchingTrackers,
-            atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap, allMetricProducers,
-            metricProducerMap, allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap,
-            trackerToMetricMap, trackerToConditionMap, activationAtomTrackerToMetricMap,
+            timeBaseSec, timeBaseSec, allTagIds, allAtomMatchingTrackers, atomMatchingTrackerMap,
+            allConditionTrackers, conditionTrackerMap, allMetricProducers, metricProducerMap,
+            allAnomalyTrackers, allAlarmTrackers, conditionToMetricMap, trackerToMetricMap,
+            trackerToConditionMap, activationAtomTrackerToMetricMap,
             deactivationAtomTrackerToMetricMap, alertTrackerMap, metricsWithActivation,
             stateProtoHashes, noReportMetricIds));
 }
diff --git a/statsd/tests/statsd_test_util.cpp b/statsd/tests/statsd_test_util.cpp
index 6101f65..8afd54c 100644
--- a/statsd/tests/statsd_test_util.cpp
+++ b/statsd/tests/statsd_test_util.cpp
@@ -252,35 +252,6 @@
     return CreateSimpleAtomMatcher("AppStartOccurredMatcher", util::APP_START_OCCURRED);
 }
 
-AtomMatcher CreateTestAtomRepeatedStateAtomMatcher(const string& name,
-                                                   TestAtomReported::State state,
-                                                   Position position) {
-    AtomMatcher atom_matcher;
-    atom_matcher.set_id(StringToId(name));
-    auto simple_atom_matcher = atom_matcher.mutable_simple_atom_matcher();
-    simple_atom_matcher->set_atom_id(util::TEST_ATOM_REPORTED);
-    auto field_value_matcher = simple_atom_matcher->add_field_value_matcher();
-    field_value_matcher->set_field(14);  // Repeated enum field.
-    field_value_matcher->set_eq_int(state);
-    field_value_matcher->set_position(position);
-    return atom_matcher;
-}
-
-AtomMatcher CreateTestAtomRepeatedStateFirstOffAtomMatcher() {
-    return CreateTestAtomRepeatedStateAtomMatcher("TestFirstStateOff", TestAtomReported::OFF,
-                                                  Position::FIRST);
-}
-
-AtomMatcher CreateTestAtomRepeatedStateFirstOnAtomMatcher() {
-    return CreateTestAtomRepeatedStateAtomMatcher("TestFirstStateOn", TestAtomReported::ON,
-                                                  Position::FIRST);
-}
-
-AtomMatcher CreateTestAtomRepeatedStateAnyOnAtomMatcher() {
-    return CreateTestAtomRepeatedStateAtomMatcher("TestAnyStateOn", TestAtomReported::ON,
-                                                  Position::ANY);
-}
-
 void addMatcherToMatcherCombination(const AtomMatcher& matcher, AtomMatcher* combinationMatcher) {
     combinationMatcher->mutable_combination()->add_matcher(matcher.id());
 }
@@ -349,14 +320,6 @@
     return predicate;
 }
 
-Predicate CreateTestAtomRepeatedStateFirstOffPredicate() {
-    Predicate predicate;
-    predicate.set_id(StringToId("TestFirstStateIsOff"));
-    predicate.mutable_simple_predicate()->set_start(StringToId("TestFirstStateOff"));
-    predicate.mutable_simple_predicate()->set_stop(StringToId("TestFirstStateOn"));
-    return predicate;
-}
-
 State CreateScreenState() {
     State state;
     state.set_id(StringToId("ScreenState"));
@@ -487,22 +450,6 @@
     return dimensions;
 }
 
-FieldMatcher CreateRepeatedDimensions(const int atomId, const std::vector<int>& fields,
-                                      const std::vector<Position>& positions) {
-    FieldMatcher dimensions;
-    if (fields.size() != positions.size()) {
-        return dimensions;
-    }
-
-    dimensions.set_field(atomId);
-    for (size_t i = 0; i < fields.size(); i++) {
-        auto child = dimensions.add_child();
-        child->set_field(fields[i]);
-        child->set_position(positions[i]);
-    }
-    return dimensions;
-}
-
 FieldMatcher CreateAttributionUidAndOtherDimensions(const int atomId,
                                                     const std::vector<Position>& positions,
                                                     const std::vector<int>& fields) {
@@ -797,19 +744,6 @@
     return statsEvent;
 }
 
-AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
-                               const vector<int>& data2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-    AStatsEvent_writeInt32(statsEvent, uid);
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_writeInt32(statsEvent, data1);
-    AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
-
-    return statsEvent;
-}
-
 shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
                                      int data2) {
     AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
@@ -819,15 +753,6 @@
     return logEvent;
 }
 
-shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
-                                     const vector<int>& data2) {
-    AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid, data1, data2);
-
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
 shared_ptr<LogEvent> makeExtraUidsLogEvent(int atomId, int64_t eventTimeNs, int uid1, int data1,
                                            int data2, const vector<int>& extraUids) {
     AStatsEvent* statsEvent = makeUidStatsEvent(atomId, eventTimeNs, uid1, data1, data2);
@@ -841,53 +766,6 @@
     return logEvent;
 }
 
-shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
-                                             const vector<int>& uids) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-    AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-
-    return logEvent;
-}
-
-shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
-                                             const vector<int>& uids, int data1, int data2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-    AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_writeInt32(statsEvent, data1);
-    AStatsEvent_writeInt32(statsEvent, data2);
-
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-
-    return logEvent;
-}
-
-shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
-                                             const vector<int>& uids, int data1,
-                                             const vector<int>& data2) {
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, atomId);
-    AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
-    AStatsEvent_writeInt32Array(statsEvent, uids.data(), uids.size());
-    AStatsEvent_addBoolAnnotation(statsEvent, ANNOTATION_ID_IS_UID, true);
-    AStatsEvent_writeInt32(statsEvent, data1);
-    AStatsEvent_writeInt32Array(statsEvent, data2.data(), data2.size());
-
-    shared_ptr<LogEvent> logEvent = std::make_shared<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-
-    return logEvent;
-}
-
 shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
                                              const vector<int>& uids, const vector<string>& tags,
                                              int data1, int data2) {
@@ -1020,57 +898,6 @@
                                                ScheduledJobStateChanged::FINISHED, timestampNs);
 }
 
-std::unique_ptr<LogEvent> CreateTestAtomReportedEventVariableRepeatedFields(
-        uint64_t timestampNs, const vector<int>& repeatedIntField,
-        const vector<int64_t>& repeatedLongField, const vector<float>& repeatedFloatField,
-        const vector<string>& repeatedStringField, const bool* repeatedBoolField,
-        const size_t repeatedBoolFieldLength, const vector<int>& repeatedEnumField) {
-    return CreateTestAtomReportedEvent(timestampNs, {1001, 1002}, {"app1", "app2"}, 5, 1000l, 21.9f,
-                                       "string", 1, TestAtomReported::ON, {8, 1, 8, 2, 8, 3},
-                                       repeatedIntField, repeatedLongField, repeatedFloatField,
-                                       repeatedStringField, repeatedBoolField,
-                                       repeatedBoolFieldLength, repeatedEnumField);
-}
-
-std::unique_ptr<LogEvent> CreateTestAtomReportedEvent(
-        uint64_t timestampNs, const vector<int>& attributionUids,
-        const vector<string>& attributionTags, const int intField, const long longField,
-        const float floatField, const string& stringField, const bool boolField,
-        const TestAtomReported::State enumField, const vector<uint8_t>& bytesField,
-        const vector<int>& repeatedIntField, const vector<int64_t>& repeatedLongField,
-        const vector<float>& repeatedFloatField, const vector<string>& repeatedStringField,
-        const bool* repeatedBoolField, const size_t repeatedBoolFieldLength,
-        const vector<int>& repeatedEnumField) {
-    vector<const char*> cRepeatedStringField(repeatedStringField.size());
-    for (int i = 0; i < cRepeatedStringField.size(); i++) {
-        cRepeatedStringField[i] = repeatedStringField[i].c_str();
-    }
-
-    AStatsEvent* statsEvent = AStatsEvent_obtain();
-    AStatsEvent_setAtomId(statsEvent, util::TEST_ATOM_REPORTED);
-    AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
-
-    writeAttribution(statsEvent, attributionUids, attributionTags);
-    AStatsEvent_writeInt32(statsEvent, intField);
-    AStatsEvent_writeInt64(statsEvent, longField);
-    AStatsEvent_writeFloat(statsEvent, floatField);
-    AStatsEvent_writeString(statsEvent, stringField.c_str());
-    AStatsEvent_writeBool(statsEvent, boolField);
-    AStatsEvent_writeInt32(statsEvent, enumField);
-    AStatsEvent_writeByteArray(statsEvent, bytesField.data(), bytesField.size());
-    AStatsEvent_writeInt32Array(statsEvent, repeatedIntField.data(), repeatedIntField.size());
-    AStatsEvent_writeInt64Array(statsEvent, repeatedLongField.data(), repeatedLongField.size());
-    AStatsEvent_writeFloatArray(statsEvent, repeatedFloatField.data(), repeatedFloatField.size());
-    AStatsEvent_writeStringArray(statsEvent, cRepeatedStringField.data(),
-                                 repeatedStringField.size());
-    AStatsEvent_writeBoolArray(statsEvent, repeatedBoolField, repeatedBoolFieldLength);
-    AStatsEvent_writeInt32Array(statsEvent, repeatedEnumField.data(), repeatedEnumField.size());
-
-    std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
-    parseStatsEventToLogEvent(statsEvent, logEvent.get());
-    return logEvent;
-}
-
 std::unique_ptr<LogEvent> CreateWakelockStateChangedEvent(uint64_t timestampNs,
                                                           const vector<int>& attributionUids,
                                                           const vector<string>& attributionTags,
@@ -1736,13 +1563,14 @@
 
 bool backfillDimensionPath(const DimensionsValue& path,
                            const google::protobuf::RepeatedPtrField<DimensionsValue>& leafValues,
-                           int* leafIndex, DimensionsValue* dimension) {
+                           int* leafIndex,
+                           DimensionsValue* dimension) {
     dimension->set_field(path.field());
     if (path.has_value_tuple()) {
         for (int i = 0; i < path.value_tuple().dimensions_value_size(); ++i) {
-            if (!backfillDimensionPath(path.value_tuple().dimensions_value(i), leafValues,
-                                       leafIndex,
-                                       dimension->mutable_value_tuple()->add_dimensions_value())) {
+            if (!backfillDimensionPath(
+                path.value_tuple().dimensions_value(i), leafValues, leafIndex,
+                dimension->mutable_value_tuple()->add_dimensions_value())) {
                 return false;
             }
         }
@@ -1972,72 +1800,6 @@
                              flagName.c_str()),
                 flagValue);
 }
-
-PackageInfoSnapshot getPackageInfoSnapshot(const sp<UidMap> uidMap) {
-    ProtoOutputStream protoOutputStream;
-    uidMap->writeUidMapSnapshot(/* timestamp */ 1, /* includeVersionStrings */ true,
-                                /* includeInstaller */ true, /* certificateHashSize */ UINT8_MAX,
-                                /* interestingUids */ {},
-                                /* installerIndices */ nullptr, /* str_set */ nullptr,
-                                &protoOutputStream);
-
-    PackageInfoSnapshot packageInfoSnapshot;
-    outputStreamToProto(&protoOutputStream, &packageInfoSnapshot);
-    return packageInfoSnapshot;
-}
-
-PackageInfo buildPackageInfo(const string& name, const int32_t uid, const int64_t version,
-                             const string& versionString, const optional<string> installer,
-                             const vector<uint8_t>& certHash, const bool deleted,
-                             const bool hashStrings, const optional<uint32_t> installerIndex) {
-    PackageInfo packageInfo;
-    packageInfo.set_version(version);
-    packageInfo.set_uid(uid);
-    packageInfo.set_deleted(deleted);
-    if (!certHash.empty()) {
-        packageInfo.set_truncated_certificate_hash(certHash.data(), certHash.size());
-    }
-    if (hashStrings) {
-        packageInfo.set_name_hash(Hash64(name));
-        packageInfo.set_version_string_hash(Hash64(versionString));
-    } else {
-        packageInfo.set_name(name);
-        packageInfo.set_version_string(versionString);
-    }
-    if (installer) {
-        if (installerIndex) {
-            packageInfo.set_installer_index(*installerIndex);
-        } else if (hashStrings) {
-            packageInfo.set_installer_hash(Hash64(*installer));
-        } else {
-            packageInfo.set_installer(*installer);
-        }
-    }
-    return packageInfo;
-}
-
-vector<PackageInfo> buildPackageInfos(
-        const vector<string>& names, const vector<int32_t>& uids, const vector<int64_t>& versions,
-        const vector<string>& versionStrings, const vector<string>& installers,
-        const vector<vector<uint8_t>>& certHashes, const vector<bool>& deleted,
-        const vector<uint32_t>& installerIndices, const bool hashStrings) {
-    vector<PackageInfo> packageInfos;
-    for (int i = 0; i < uids.size(); i++) {
-        const optional<uint32_t> installerIndex =
-                installerIndices.empty() ? nullopt : optional<uint32_t>(installerIndices[i]);
-        const optional<string> installer =
-                installers.empty() ? nullopt : optional<string>(installers[i]);
-        vector<uint8_t> certHash;
-        if (!certHashes.empty()) {
-            certHash = certHashes[i];
-        }
-        packageInfos.emplace_back(buildPackageInfo(names[i], uids[i], versions[i],
-                                                   versionStrings[i], installer, certHash,
-                                                   deleted[i], hashStrings, installerIndex));
-    }
-    return packageInfos;
-}
-
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/statsd_test_util.h b/statsd/tests/statsd_test_util.h
index 59b134c..e5f2e96 100644
--- a/statsd/tests/statsd_test_util.h
+++ b/statsd/tests/statsd_test_util.h
@@ -19,7 +19,6 @@
 #include <aidl/android/os/IPullAtomCallback.h>
 #include <aidl/android/os/IPullAtomResultReceiver.h>
 #include <gmock/gmock.h>
-#include <google/protobuf/util/message_differencer.h>
 #include <gtest/gtest.h>
 
 #include "src/StatsLogProcessor.h"
@@ -44,10 +43,7 @@
 using ::aidl::android::os::IPullAtomResultReceiver;
 using android::util::ProtoReader;
 using google::protobuf::RepeatedPtrField;
-using google::protobuf::util::MessageDifferencer;
 using Status = ::ndk::ScopedAStatus;
-using PackageInfoSnapshot = UidMapping_PackageInfoSnapshot;
-using PackageInfo = UidMapping_PackageInfoSnapshot_PackageInfo;
 
 // Wrapper for assertion helpers called from tests to keep track of source location of failures.
 // Example usage:
@@ -155,20 +151,6 @@
 // Create AtomMatcher proto for app launches.
 AtomMatcher CreateAppStartOccurredAtomMatcher();
 
-// Create AtomMatcher proto for test atom repeated state.
-AtomMatcher CreateTestAtomRepeatedStateAtomMatcher(const string& name,
-                                                   TestAtomReported::State state,
-                                                   Position position);
-
-// Create AtomMatcher proto for test atom repeated state is off, first position.
-AtomMatcher CreateTestAtomRepeatedStateFirstOffAtomMatcher();
-
-// Create AtomMatcher proto for test atom repeated state is on, first position.
-AtomMatcher CreateTestAtomRepeatedStateFirstOnAtomMatcher();
-
-// Create AtomMatcher proto for test atom repeated state is on, any position.
-AtomMatcher CreateTestAtomRepeatedStateAnyOnAtomMatcher();
-
 // Add an AtomMatcher to a combination AtomMatcher.
 void addMatcherToMatcherCombination(const AtomMatcher& matcher, AtomMatcher* combinationMatcher);
 
@@ -196,9 +178,6 @@
 // Create a Predicate proto for app is in background.
 Predicate CreateIsInBackgroundPredicate();
 
-// Create a Predicate proto for test atom repeated state field is off.
-Predicate CreateTestAtomRepeatedStateFirstOffPredicate();
-
 // Create State proto for screen state atom.
 State CreateScreenState();
 
@@ -238,10 +217,6 @@
 // Create dimensions from primitive fields.
 FieldMatcher CreateDimensions(const int atomId, const std::vector<int>& fields);
 
-// Create dimensions from repeated primitive fields.
-FieldMatcher CreateRepeatedDimensions(const int atomId, const std::vector<int>& fields,
-                                      const std::vector<Position>& positions);
-
 // Create dimensions by attribution uid and tag.
 FieldMatcher CreateAttributionUidAndTagDimensions(const int atomId,
                                                   const std::vector<Position>& positions);
@@ -328,28 +303,12 @@
 
 AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1, int data2);
 
-AStatsEvent* makeUidStatsEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
-                               const vector<int>& data2);
-
 std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
                                           int data2);
 
-std::shared_ptr<LogEvent> makeUidLogEvent(int atomId, int64_t eventTimeNs, int uid, int data1,
-                                          const vector<int>& data2);
-
 shared_ptr<LogEvent> makeExtraUidsLogEvent(int atomId, int64_t eventTimeNs, int uid1, int data1,
                                            int data2, const std::vector<int>& extraUids);
 
-std::shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
-                                                  const std::vector<int>& uids);
-
-shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
-                                             const vector<int>& uids, int data1, int data2);
-
-shared_ptr<LogEvent> makeRepeatedUidLogEvent(int atomId, int64_t eventTimeNs,
-                                             const vector<int>& uids, int data1,
-                                             const vector<int>& data2);
-
 std::shared_ptr<LogEvent> makeAttributionLogEvent(int atomId, int64_t eventTimeNs,
                                                   const vector<int>& uids,
                                                   const vector<string>& tags, int data1, int data2);
@@ -441,22 +400,6 @@
         AppStartOccurred::TransitionType type, const string& activity_name,
         const string& calling_pkg_name, const bool is_instant_app, int64_t activity_start_msec);
 
-std::unique_ptr<LogEvent> CreateTestAtomReportedEventVariableRepeatedFields(
-        uint64_t timestampNs, const vector<int>& repeatedIntField,
-        const vector<int64_t>& repeatedLongField, const vector<float>& repeatedFloatField,
-        const vector<string>& repeatedStringField, const bool* repeatedBoolField,
-        const size_t repeatedBoolFieldLength, const vector<int>& repeatedEnumField);
-
-std::unique_ptr<LogEvent> CreateTestAtomReportedEvent(
-        uint64_t timestampNs, const vector<int>& attributionUids,
-        const vector<string>& attributionTags, const int intField, const long longField,
-        const float floatField, const string& stringField, const bool boolField,
-        const TestAtomReported::State enumField, const vector<uint8_t>& bytesField,
-        const vector<int>& repeatedIntField, const vector<int64_t>& repeatedLongField,
-        const vector<float>& repeatedFloatField, const vector<string>& repeatedStringField,
-        const bool* repeatedBoolField, const size_t repeatedBoolFieldLength,
-        const vector<int>& repeatedEnumField);
-
 // Create a statsd log event processor upon the start time in seconds, config and key.
 sp<StatsLogProcessor> CreateStatsLogProcessor(const int64_t timeBaseNs, const int64_t currentTimeNs,
                                               const StatsdConfig& config, const ConfigKey& key,
@@ -658,13 +601,6 @@
     }
 }
 
-template <typename P>
-void outputStreamToProto(ProtoOutputStream* outputStream, P* proto) {
-    vector<uint8_t> bytes;
-    outputStream->serializeToVector(&bytes);
-    proto->ParseFromArray(bytes.data(), bytes.size());
-}
-
 inline bool isAtLeastSFuncTrue() {
     return true;
 }
@@ -689,38 +625,6 @@
 
 void writeBootFlag(const std::string& flagName, const std::string& flagValue);
 
-PackageInfoSnapshot getPackageInfoSnapshot(const sp<UidMap> uidMap);
-
-PackageInfo buildPackageInfo(const std::string& name, const int32_t uid, const int64_t version,
-                             const std::string& versionString,
-                             const std::optional<std::string> installer,
-                             const std::vector<uint8_t>& certHash, const bool deleted,
-                             const bool hashStrings, const optional<uint32_t> installerIndex);
-
-std::vector<PackageInfo> buildPackageInfos(
-        const std::vector<string>& names, const std::vector<int32_t>& uids,
-        const std::vector<int64_t>& versions, const std::vector<std::string>& versionStrings,
-        const std::vector<std::string>& installers,
-        const std::vector<std::vector<uint8_t>>& certHashes, const std::vector<bool>& deleted,
-        const std::vector<uint32_t>& installerIndices, const bool hashStrings);
-
-// Checks equality on explicitly set values.
-MATCHER(ProtoEq, "") {
-    return MessageDifferencer::Equals(std::get<0>(arg), std::get<1>(arg));
-}
-
-// Checks equality on explicitly and implicitly set values.
-// Implicitly set values comes from fields with a default value specifier.
-MATCHER(ProtoEquiv, "") {
-    return MessageDifferencer::Equivalent(std::get<0>(arg), std::get<1>(arg));
-}
-
-template <typename T>
-std::vector<T> concatenate(const vector<T>& a, const vector<T>& b) {
-    vector<T> result(a);
-    result.insert(result.end(), b.begin(), b.end());
-    return result;
-}
 }  // namespace statsd
 }  // namespace os
 }  // namespace android
diff --git a/statsd/tests/statsd_test_util_test.cpp b/statsd/tests/statsd_test_util_test.cpp
deleted file mode 100644
index 9b28446..0000000
--- a/statsd/tests/statsd_test_util_test.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright (C) 2022 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "statsd_test_util.h"
-
-#include "src/stats_log.pb.h"
-
-namespace android {
-namespace os {
-namespace statsd {
-
-#ifdef __ANDROID__
-
-namespace {
-const string appName = "app1";
-const int32_t uid = 1000;
-const int64_t version = 1;
-const string versionString = "v1";
-const string installer = "com.android.vending";
-}  // anonymous namespace
-
-TEST(StatsdTestUtil_PackageInfo, TestBuildPackageInfo) {
-    PackageInfo packageInfo = buildPackageInfo(appName, uid, version, versionString,
-                                               /* installer */ nullopt, /* certHash */ {},
-                                               /* deleted */ false, /* hashStrings */ false,
-                                               /* installerIndex */ nullopt);
-
-    EXPECT_THAT(packageInfo.version(), Eq(version));
-    EXPECT_THAT(packageInfo.uid(), Eq(uid));
-    EXPECT_THAT(packageInfo.deleted(), Eq(false));
-}
-
-// Set up parameterized test for testing with different values for pacakage certificate hashes.
-class StatsdTestUtil_PackageInfo_CertificateHash : public TestWithParam<vector<uint8_t>> {};
-INSTANTIATE_TEST_SUITE_P(
-        CertificateHashSizes, StatsdTestUtil_PackageInfo_CertificateHash,
-        Values(vector<uint8_t>(), vector<uint8_t>{'a'}, vector<uint8_t>{'a', 'b'}),
-        [](const TestParamInfo<StatsdTestUtil_PackageInfo_CertificateHash::ParamType>& info) {
-            if (info.param.empty()) {
-                return string("empty");
-            }
-            return string(info.param.begin(), info.param.end());
-        });
-TEST_P(StatsdTestUtil_PackageInfo_CertificateHash, TestBuildPackageInfoCertificateHash) {
-    const vector<uint8_t>& certHash = GetParam();
-    PackageInfo packageInfo = buildPackageInfo(appName, uid, version, versionString,
-                                               /* installer */ nullopt, certHash,
-                                               /* deleted */ false, /* hashStrings */ false,
-                                               /* installerIndex */ nullopt);
-
-    EXPECT_THAT(packageInfo.has_truncated_certificate_hash(), !certHash.empty());
-    string expectedCertHash(certHash.begin(), certHash.end());
-    EXPECT_THAT(packageInfo.truncated_certificate_hash(), Eq(expectedCertHash));
-}
-
-TEST(StatsdTestUtil_PackageInfo, TestBuildPackageInfoHashStrings) {
-    PackageInfo packageInfo = buildPackageInfo(appName, uid, version, versionString,
-                                               /* installer */ nullopt, /* certHash */ {},
-                                               /* deleted */ false, /* hashStrings */ true,
-                                               /* installerIndex */ nullopt);
-
-    EXPECT_TRUE(packageInfo.has_name_hash());
-    EXPECT_THAT(packageInfo.name_hash(), Eq(Hash64(appName)));
-    EXPECT_FALSE(packageInfo.has_name());
-
-    EXPECT_TRUE(packageInfo.has_version_string_hash());
-    EXPECT_THAT(packageInfo.version_string_hash(), Eq(Hash64(versionString)));
-    EXPECT_FALSE(packageInfo.has_version_string());
-}
-
-TEST(StatsdTestUtil_PackageInfo, TestBuildPackageInfoNoHashStrings) {
-    PackageInfo packageInfo = buildPackageInfo(appName, uid, version, versionString,
-                                               /* installer */ nullopt, /* certHash */ {},
-                                               /* deleted */ false, /* hashStrings */ false,
-                                               /* installerIndex */ nullopt);
-
-    EXPECT_TRUE(packageInfo.has_name());
-    EXPECT_THAT(packageInfo.name(), Eq(appName));
-    EXPECT_FALSE(packageInfo.has_name_hash());
-
-    EXPECT_TRUE(packageInfo.has_version_string());
-    EXPECT_THAT(packageInfo.version_string(), Eq(versionString));
-    EXPECT_FALSE(packageInfo.has_version_string_hash());
-}
-
-// Test with multiple permutations of installerIndex(uint32_t) and hashString(bool) tuples.
-class StatsdTestUtil_PackageInfo_InstallerIndexAndHashStrings
-    : public TestWithParam<tuple<optional<uint32_t>, bool>> {};
-INSTANTIATE_TEST_SUITE_P(InstallerIndexAndHashStrings,
-                         StatsdTestUtil_PackageInfo_InstallerIndexAndHashStrings,
-                         Combine(Values(optional(2), nullopt), Bool()));
-TEST_P(StatsdTestUtil_PackageInfo_InstallerIndexAndHashStrings, TestBuildPackageInfoNoInstaller) {
-    const auto& [installerIndex, hashStrings] = GetParam();
-
-    PackageInfo packageInfo = buildPackageInfo(appName, uid, version, versionString,
-                                               /* installer */ nullopt, /* certHash */ {},
-                                               /* deleted */ false, hashStrings, installerIndex);
-
-    EXPECT_FALSE(packageInfo.has_installer_index());
-    EXPECT_FALSE(packageInfo.has_installer_hash());
-    EXPECT_FALSE(packageInfo.has_installer());
-}
-
-// Set up parameterized test for testing with different boolean values for hashStrings parameter
-// in buildPackageInfo()/buildPackageInfos()
-class StatsdTestUtil_PackageInfo_HashStrings : public TestWithParam<bool> {};
-INSTANTIATE_TEST_SUITE_P(HashStrings, StatsdTestUtil_PackageInfo_HashStrings, Bool(),
-                         PrintToStringParamName());
-TEST_P(StatsdTestUtil_PackageInfo_HashStrings, TestBuildPackageInfoWithInstallerAndInstallerIndex) {
-    const bool hashStrings = GetParam();
-    PackageInfo packageInfo = buildPackageInfo(appName, uid, version, versionString, installer,
-                                               /* certHash */ {}, /* deleted */ false, hashStrings,
-                                               /* installerIndex */ 1);
-
-    EXPECT_THAT(packageInfo.installer_index(), Eq(1));
-    EXPECT_FALSE(packageInfo.has_installer_hash());
-    EXPECT_FALSE(packageInfo.has_installer());
-}
-
-TEST(StatsdTestUtil_PackageInfo, TestBuildPackageInfoWithInstallerNoInstallerIndexHashStrings) {
-    PackageInfo packageInfo =
-            buildPackageInfo(appName, uid, version, versionString, installer, /* certHash */ {},
-                             /* deleted */ false, /* hashStrings */ true,
-                             /* installerIndex */ nullopt);
-
-    EXPECT_FALSE(packageInfo.has_installer_index());
-    EXPECT_THAT(packageInfo.installer_hash(), Eq(Hash64(installer)));
-    EXPECT_FALSE(packageInfo.has_installer());
-}
-
-TEST(StatsdTestUtil_PackageInfo, TestBuildPackageInfoWithInstallerNoInstallerIndexNoHashStrings) {
-    PackageInfo packageInfo =
-            buildPackageInfo(appName, uid, version, versionString, installer, /* certHash */ {},
-                             /* deleted */ false, /* hashStrings */ false,
-                             /* installerIndex */ nullopt);
-
-    EXPECT_FALSE(packageInfo.has_installer_index());
-    EXPECT_THAT(packageInfo.installer(), Eq(installer));
-    EXPECT_FALSE(packageInfo.has_installer_hash());
-}
-
-TEST_P(StatsdTestUtil_PackageInfo_HashStrings, TestBuildPackageInfosEmptyOptionalParams) {
-    const bool hashStrings = GetParam();
-    vector<PackageInfo> packageInfos = buildPackageInfos(
-            {appName}, {uid}, {version}, {versionString}, /* installers */ {}, /* certHashes */ {},
-            /* deleted */ {false}, /* installerIndices */ {}, hashStrings);
-
-    PackageInfo packageInfo = buildPackageInfo(
-            appName, uid, version, versionString, /* installer */ nullopt, /* certHash */ {},
-            /* deleted */ false, hashStrings, /* installerIndex */ nullopt);
-
-    EXPECT_THAT(packageInfos, Pointwise(ProtoEq(), {packageInfo}));
-}
-
-TEST_P(StatsdTestUtil_PackageInfo_HashStrings, TestBuildPackageInfosNonEmptyOptionalParams) {
-    const bool hashStrings = GetParam();
-    vector<PackageInfo> packageInfos = buildPackageInfos(
-            {appName}, {uid}, {version}, {versionString}, {installer}, /* certHashes */ {{'a'}},
-            /* deleted */ {false}, /* installerIndices */ {3}, hashStrings);
-
-    PackageInfo packageInfo =
-            buildPackageInfo(appName, uid, version, versionString, installer, /* certHash */ {'a'},
-                             /* deleted */ false, hashStrings, /* installerIndex */ 3);
-
-    EXPECT_THAT(packageInfos, Pointwise(ProtoEq(), {packageInfo}));
-}
-
-#else
-GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
-
-}  // namespace statsd
-}  // namespace os
-}  // namespace android
diff --git a/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java b/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
index d02d2c4..7f8a93c 100644
--- a/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
+++ b/statsd/tools/localtools/src/com/android/statsd/shelltools/testdrive/TestDrive.java
@@ -89,7 +89,6 @@
     @VisibleForTesting
     Dumper mDumper = new BasicDumper();
     boolean mPressToContinue = false;
-    Integer mReportCollectionDelayMillis = 60_000;
 
     public static void main(String[] args) {
         final Configuration configuration = new Configuration();
@@ -109,29 +108,13 @@
         }
     }
 
-    static void printUsageMessage() {
-        LOGGER.severe("Usage: ./test_drive [options] <atomId1> <atomId2> ... <atomIdN>");
-        LOGGER.severe("OPTIONS");
-        LOGGER.severe("-h, --help");
-        LOGGER.severe("\tPrint this message");
-        LOGGER.severe("-one");
-        LOGGER.severe("\tCreating one event metric to catch all pushed atoms");
-        LOGGER.severe("-terse");
-        LOGGER.severe("\tTerse output format.");
-        LOGGER.severe("-p additional_allowed_package");
-        LOGGER.severe("\tAllows collection atoms from an additional package");
-        LOGGER.severe("-s DEVICE_SERIAL_NUMBER");
-        LOGGER.severe("\tDevice serial number to use for adb communication");
-        LOGGER.severe("-e");
-        LOGGER.severe("\tWait for Enter key press before collecting report");
-        LOGGER.severe("-d delay_ms");
-        LOGGER.severe("\tWait for delay_ms before collecting report, default is 60000 ms");
-    }
-
     boolean processArgs(Configuration configuration, String[] args, List<String> connectedDevices,
             String defaultDevice) {
         if (args.length < 1) {
-            printUsageMessage();
+            LOGGER.severe("Usage: ./test_drive [-one] "
+                    + "[-p additional_allowed_package] "
+                    + "[-s DEVICE_SERIAL_NUMBER] "
+                    + "<atomId1> <atomId2> ... <atomIdN>");
             return false;
         }
 
@@ -152,12 +135,6 @@
                 mDeviceSerial = args[++first_arg];
             } else if (remaining_args >= 2 && arg.equals("-e")) {
                 mPressToContinue = true;
-            } else if (remaining_args >= 2 && arg.equals("-d")) {
-                mPressToContinue = false;
-                mReportCollectionDelayMillis = Integer.parseInt(args[++first_arg]);
-            } else if (arg.equals("-h") || arg.equals("--help")) {
-                printUsageMessage();
-                return false;
             } else {
                 break;  // Found the atom list
             }
@@ -198,15 +175,13 @@
             }
             if (!hasPulledAtoms) {
                 if (mPressToContinue) {
-                    LOGGER.info("Press Enter after you finish playing with the device...");
+                    LOGGER.info("Press enter after you finish playing with the device...");
                     Scanner scanner = new Scanner(System.in);
                     scanner.nextLine();
                 } else {
                     LOGGER.info(
-                            String.format(
-                                    "All events should be dumped after %d ms ...",
-                                    mReportCollectionDelayMillis));
-                    Thread.sleep(mReportCollectionDelayMillis);
+                            "All events should be dumped after 1 min ...");
+                    Thread.sleep(60_000);
                 }
             } else {
                 LOGGER.info("All events should be dumped after 1.5 minutes ...");
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index be8a12a..451ad73 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -20,7 +20,6 @@
     <option name="config-descriptor:metadata" key="parameter" value="instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
-    <option name="config-descriptor:metadata" key="parameter" value="all_foldable_states" />
     <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
         <option name="jar" value="CtsStatsdHostTestCases.jar" />
     </test>
diff --git a/tests/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/tests/src/android/cts/statsd/atom/DeviceAtomTestCase.java
index dacbac9..03facd0 100644
--- a/tests/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ b/tests/src/android/cts/statsd/atom/DeviceAtomTestCase.java
@@ -167,24 +167,14 @@
      */
     protected int getUid() throws Exception {
         int currentUser = getDevice().getCurrentUser();
-        final String packages = getDevice().executeShellCommand("cmd package list packages -U"
-                + " --user " + currentUser + " " + DEVICE_SIDE_TEST_PACKAGE);
-
-        // Split package list by lines
-        // Sample packages response:
-        // package:com.android.server.cts.device.statsd.host uid:1010033
-        // package:com.android.server.cts.device.statsd uid:1010034
-        final String[] lines = packages.split("[\\r\\n]+");
-        for (final String line : lines) {
-            if (line.startsWith("package:" + DEVICE_SIDE_TEST_PACKAGE + " ")) {
-                final int uidIndex = line.lastIndexOf(":") + 1;
-                final int uid = Integer.parseInt(line.substring(uidIndex).trim());
-                assertThat(uid).isGreaterThan(10_000);
-                return uid;
-            }
-        }
-        throw new Error(
-                String.format("Could not find installed package: %s", DEVICE_SIDE_TEST_PACKAGE));
+        String uidLine = getDevice().executeShellCommand("cmd package list packages -U --user "
+                + currentUser + " " + DEVICE_SIDE_TEST_PACKAGE);
+        String[] uidLineParts = uidLine.split(":");
+        // 3rd entry is package uid
+        assertThat(uidLineParts.length).isGreaterThan(2);
+        int uid = Integer.parseInt(uidLineParts[2].trim());
+        assertThat(uid).isGreaterThan(10000);
+        return uid;
     }
 
     /**