Merge "Statsd test mapping" into rvc-dev
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 65061d0..b357904 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -301,6 +301,8 @@
         "-Wno-unused-parameter",
     ],
 
+    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.
@@ -373,10 +375,6 @@
         include_dirs: ["external/protobuf/src"],
     },
 
-    shared_libs: [
-        "libprotobuf-cpp-lite",
-    ],
-
 }
 
 //#############################
diff --git a/cmds/statsd/AndroidTest.xml b/cmds/statsd/AndroidTest.xml
deleted file mode 100644
index afe30a2..0000000
--- a/cmds/statsd/AndroidTest.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 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.
--->
-<configuration description="Config for statsd_test">
-    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
-        <option name="cleanup" value="true" />
-        <option name="push" value="statsd_test->/data/nativetest/statsd_test" />
-    </target_preparer>
-    <option name="test-suite-tag" value="apct" />
-    <test class="com.android.tradefed.testtype.GTest" >
-        <option name="native-test-device-path" value="/data/nativetest" />
-        <option name="module-name" value="statsd_test" />
-    </test>
-</configuration>
\ No newline at end of file
diff --git a/cmds/statsd/TEST_MAPPING b/cmds/statsd/TEST_MAPPING
new file mode 100644
index 0000000..8dee073
--- /dev/null
+++ b/cmds/statsd/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+  "presubmit" : [
+    {
+      "name" : "statsd_test"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index ed98f50..f4247ec 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -181,12 +181,15 @@
 message GaugeMetricData {
   optional DimensionsValue dimensions_in_what = 1;
 
-  optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
+  // Currently unsupported
+  repeated StateValue slice_by_state = 6;
 
   repeated GaugeBucketInfo bucket_info = 3;
 
   repeated DimensionsValue dimension_leaf_values_in_what = 4;
 
+  optional DimensionsValue dimensions_in_condition = 2 [deprecated = true];
+
   repeated DimensionsValue dimension_leaf_values_in_condition = 5 [deprecated = true];
 }
 
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 9e7b7c8..d29394b 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -1564,7 +1564,7 @@
 
     // Trigger Activation 1 for Metric 1. Should activate on boot.
     // Trigger Activation 4 for Metric 2. Should activate immediately.
-    long configAddedTimeNs = metricsManager1->mLastReportTimeNs;
+    int64_t configAddedTimeNs = metricsManager1->mLastReportTimeNs;
     std::vector<int> attributionUids = {111};
     std::vector<string> attributionTags = {"App1"};
     std::unique_ptr<LogEvent> event1 = CreateAcquireWakelockEvent(
diff --git a/cmds/statsd/tests/StatsService_test.cpp b/cmds/statsd/tests/StatsService_test.cpp
index 86f786e..cc38c4a 100644
--- a/cmds/statsd/tests/StatsService_test.cpp
+++ b/cmds/statsd/tests/StatsService_test.cpp
@@ -65,7 +65,6 @@
     args.push(String8("-1"));
     args.push(String8("0"));
     args.push(String8("1"));
-    args.push(String8("9999999999999999999999999999999999"));
     args.push(String8("a1"));
     args.push(String8(""));
 
@@ -85,14 +84,11 @@
     EXPECT_TRUE(service->getUidFromArgs(args, 2, uid));
     EXPECT_EQ(1, uid);
 
-    // "999999999999999999"
+    // "a1"
     EXPECT_FALSE(service->getUidFromArgs(args, 3, uid));
 
-    // "a1"
-    EXPECT_FALSE(service->getUidFromArgs(args, 4, uid));
-
     // ""
-    EXPECT_FALSE(service->getUidFromArgs(args, 5, uid));
+    EXPECT_FALSE(service->getUidFromArgs(args, 4, uid));
 
     // For a non-userdebug, uid "1" cannot be impersonated.
     service->mEngBuild = false;
diff --git a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
index 69326cb..a5da9c8 100644
--- a/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/CountMetric_e2e_test.cpp
@@ -141,36 +141,38 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    EXPECT_EQ(3, reports.reports(0).metrics(0).count_metrics().data_size());
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(3, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
-    auto data = reports.reports(0).metrics(0).count_metrics().data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-    EXPECT_EQ(1, data.bucket_info(1).count());
-
-    data = reports.reports(0).metrics(0).count_metrics().data(1);
+    auto data = countMetrics.data(0);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_UNKNOWN,
               data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
 
-    data = reports.reports(0).metrics(0).count_metrics().data(2);
+    data = countMetrics.data(1);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(2, data.bucket_info(1).count());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_value());
+    EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
+    ASSERT_EQ(2, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+    EXPECT_EQ(1, data.bucket_info(1).count());
 }
 
 /**
@@ -191,7 +193,9 @@
     auto syncStartMatcher = CreateSyncStartAtomMatcher();
     *config.add_atom_matcher() = syncStartMatcher;
 
-    auto state = CreateScreenStateWithOnOffMap();
+    int64_t screenOnId = 4444;
+    int64_t screenOffId = 9876;
+    auto state = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
     *config.add_state() = state;
 
     // Create count metric that slices by screen state with on/off map.
@@ -321,11 +325,13 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    EXPECT_EQ(3, reports.reports(0).metrics(0).count_metrics().data_size());
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(3, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
-    auto data = reports.reports(0).metrics(0).count_metrics().data(0);
+    auto data = countMetrics.data(0);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -333,23 +339,23 @@
     EXPECT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
 
-    data = reports.reports(0).metrics(0).count_metrics().data(1);
+    data = countMetrics.data(1);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_OFF"), data.slice_by_state(0).group_id());
-    EXPECT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(4, data.bucket_info(0).count());
-    EXPECT_EQ(2, data.bucket_info(1).count());
-
-    data = reports.reports(0).metrics(0).count_metrics().data(2);
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_ON"), data.slice_by_state(0).group_id());
+    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
     EXPECT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(1, data.bucket_info(1).count());
+
+    data = countMetrics.data(2);
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
+    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
+    EXPECT_EQ(2, data.bucket_info_size());
+    EXPECT_EQ(4, data.bucket_info(0).count());
+    EXPECT_EQ(2, data.bucket_info(1).count());
 }
 
 /**
@@ -499,50 +505,52 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    EXPECT_EQ(5, reports.reports(0).metrics(0).count_metrics().data_size());
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(5, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
-    auto data = reports.reports(0).metrics(0).count_metrics().data(0);
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = reports.reports(0).metrics(0).count_metrics().data(1);
+    auto data = countMetrics.data(0);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(-1 /* StateTracker::kStateUnknown */, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
 
-    data = reports.reports(0).metrics(0).count_metrics().data(2);
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(2, data.bucket_info(0).count());
-
-    data = reports.reports(0).metrics(0).count_metrics().data(3);
+    data = countMetrics.data(1);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(2, data.bucket_info(0).count());
 
-    data = reports.reports(0).metrics(0).count_metrics().data(4);
+    data = countMetrics.data(2);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
     EXPECT_EQ(2, data.bucket_info(1).count());
+
+    data = countMetrics.data(3);
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_value());
+    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(0).value());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(2, data.bucket_info(0).count());
+
+    data = countMetrics.data(4);
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_value());
+    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(0).value());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
 }
 
 TEST(CountMetricE2eTest, TestMultipleSlicedStates) {
@@ -554,7 +562,9 @@
             CreateSimpleAtomMatcher("APP_CRASH_OCCURRED", util::APP_CRASH_OCCURRED);
     *config.add_atom_matcher() = appCrashMatcher;
 
-    auto state1 = CreateScreenStateWithOnOffMap();
+    int64_t screenOnId = 4444;
+    int64_t screenOffId = 9876;
+    auto state1 = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
     *config.add_state() = state1;
     auto state2 = CreateUidProcessState();
     *config.add_state() = state2;
@@ -725,22 +735,13 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_count_metrics());
-    EXPECT_EQ(6, reports.reports(0).metrics(0).count_metrics().data_size());
+    StatsLogReport::CountMetricDataWrapper countMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
+    EXPECT_EQ(6, countMetrics.data_size());
 
     // For each CountMetricData, check StateValue info is correct and buckets
     // have correct counts.
-    auto data = reports.reports(0).metrics(0).count_metrics().data(0);
-    EXPECT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_OFF"), data.slice_by_state(0).group_id());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(1).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(1, data.bucket_info(0).count());
-
-    data = reports.reports(0).metrics(0).count_metrics().data(1);
+    auto data = countMetrics.data(0);
     EXPECT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -748,53 +749,64 @@
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
     EXPECT_TRUE(data.slice_by_state(1).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
 
-    data = reports.reports(0).metrics(0).count_metrics().data(2);
+    data = countMetrics.data(1);
     EXPECT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_OFF"), data.slice_by_state(0).group_id());
+    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
     EXPECT_TRUE(data.slice_by_state(1).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
-    EXPECT_EQ(2, data.bucket_info_size());
-    EXPECT_EQ(2, data.bucket_info(0).count());
-    EXPECT_EQ(1, data.bucket_info(1).count());
-
-    data = reports.reports(0).metrics(0).count_metrics().data(3);
-    EXPECT_EQ(2, data.slice_by_state_size());
-    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_ON"), data.slice_by_state(0).group_id());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
-    EXPECT_TRUE(data.slice_by_state(1).has_value());
-    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
 
-    data = reports.reports(0).metrics(0).count_metrics().data(4);
+    data = countMetrics.data(2);
     EXPECT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_ON"), data.slice_by_state(0).group_id());
+    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
     EXPECT_TRUE(data.slice_by_state(1).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_BACKGROUND, data.slice_by_state(1).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(1, data.bucket_info(0).count());
 
-    data = reports.reports(0).metrics(0).count_metrics().data(5);
+    data = countMetrics.data(3);
     EXPECT_EQ(2, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_OFF"), data.slice_by_state(0).group_id());
+    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
     EXPECT_TRUE(data.slice_by_state(1).has_value());
     EXPECT_EQ(android::app::PROCESS_STATE_TOP, data.slice_by_state(1).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(2, data.bucket_info(0).count());
+
+    data = countMetrics.data(4);
+    EXPECT_EQ(2, data.slice_by_state_size());
+    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
+    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
+    EXPECT_TRUE(data.slice_by_state(1).has_value());
+    EXPECT_EQ(android::app::PROCESS_STATE_FOREGROUND_SERVICE, data.slice_by_state(1).value());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(1, data.bucket_info(0).count());
+
+    data = countMetrics.data(5);
+    EXPECT_EQ(2, data.slice_by_state_size());
+    EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_group_id());
+    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(1).atom_id());
+    EXPECT_TRUE(data.slice_by_state(1).has_value());
+    EXPECT_EQ(android::app::PROCESS_STATE_IMPORTANT_FOREGROUND, data.slice_by_state(1).value());
+    ASSERT_EQ(2, data.bucket_info_size());
+    EXPECT_EQ(2, data.bucket_info(0).count());
+    EXPECT_EQ(1, data.bucket_info(1).count());
 }
 
 }  // namespace statsd
diff --git a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
index 2659944..ba09a35 100644
--- a/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/DurationMetric_e2e_test.cpp
@@ -98,8 +98,9 @@
     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
 
-    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
-            reports.reports(0).metrics(0).duration_metrics();
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
     EXPECT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
@@ -180,8 +181,9 @@
     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
 
-    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
-            reports.reports(0).metrics(0).duration_metrics();
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
     EXPECT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
@@ -350,8 +352,9 @@
     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
 
-    const StatsLogReport::DurationMetricDataWrapper& durationMetrics =
-            reports.reports(0).metrics(0).duration_metrics();
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
     EXPECT_EQ(1, durationMetrics.data_size());
 
     DurationMetricData data = durationMetrics.data(0);
@@ -433,9 +436,12 @@
 
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
+    EXPECT_EQ(1, durationMetrics.data_size());
 
-    DurationMetricData data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    DurationMetricData data = durationMetrics.data(0);
 
     // Validate bucket info.
     EXPECT_EQ(1, data.bucket_info_size());
@@ -532,9 +538,12 @@
 
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
+    EXPECT_EQ(1, durationMetrics.data_size());
 
-    DurationMetricData data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    DurationMetricData data = durationMetrics.data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
                                     util::WAKELOCK_STATE_CHANGED, appUid);
@@ -690,9 +699,12 @@
 
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(1, reports.reports(0).metrics(0).duration_metrics().data_size());
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
+    EXPECT_EQ(1, durationMetrics.data_size());
 
-    DurationMetricData data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    DurationMetricData data = durationMetrics.data(0);
     // Validate dimension value.
     ValidateAttributionUidDimension(data.dimensions_in_what(),
                                     util::WAKELOCK_STATE_CHANGED, appUid);
@@ -811,9 +823,12 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    EXPECT_EQ(3, reports.reports(0).metrics(0).duration_metrics().data_size());
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
+    EXPECT_EQ(3, durationMetrics.data_size());
 
-    DurationMetricData data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    DurationMetricData data = durationMetrics.data(0);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -826,7 +841,7 @@
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(1);
+    data = durationMetrics.data(1);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -839,7 +854,7 @@
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(2);
+    data = durationMetrics.data(2);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -970,9 +985,12 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    EXPECT_EQ(3, reports.reports(0).metrics(0).duration_metrics().data_size());
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
+    EXPECT_EQ(3, durationMetrics.data_size());
 
-    DurationMetricData data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    DurationMetricData data = durationMetrics.data(0);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -985,7 +1003,7 @@
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(2);
+    data = durationMetrics.data(1);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -998,7 +1016,7 @@
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(1);
+    data = durationMetrics.data(2);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
@@ -1020,7 +1038,9 @@
     auto batterySaverModePredicate = CreateBatterySaverModePredicate();
     *config.add_predicate() = batterySaverModePredicate;
 
-    auto screenStateWithMap = CreateScreenStateWithOnOffMap();
+    int64_t screenOnId = 4444;
+    int64_t screenOffId = 9876;
+    auto screenStateWithMap = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
     *config.add_state() = screenStateWithMap;
 
     // Create duration metric that slices by mapped screen state.
@@ -1123,13 +1143,16 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    EXPECT_EQ(2, reports.reports(0).metrics(0).duration_metrics().data_size());
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
+    EXPECT_EQ(2, durationMetrics.data_size());
 
-    DurationMetricData data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    DurationMetricData data = durationMetrics.data(0);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_ON"), data.slice_by_state(0).group_id());
+    EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
     EXPECT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(130 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1138,11 +1161,11 @@
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(1);
+    data = durationMetrics.data(1);
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
-    EXPECT_EQ(StringToId("SCREEN_OFF"), data.slice_by_state(0).group_id());
+    EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
     EXPECT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
@@ -1314,47 +1337,25 @@
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
-    EXPECT_EQ(9, reports.reports(0).metrics(0).duration_metrics().data_size());
+    StatsLogReport::DurationMetricDataWrapper durationMetrics;
+    sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
+                                    &durationMetrics);
+    EXPECT_EQ(9, durationMetrics.data_size());
 
-    DurationMetricData data = reports.reports(0).metrics(0).duration_metrics().data(0);
+    DurationMetricData data = durationMetrics.data(0);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
-                                                  "wakelock2");
+                                                  "wakelock1");
     EXPECT_EQ(1, data.slice_by_state_size());
     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
               data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(1);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
-                                                  "wakelock2");
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
-              data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(140 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = reports.reports(0).metrics(0).duration_metrics().data(2);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
-                                                  "wakelock1");
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = reports.reports(0).metrics(0).duration_metrics().data(3);
+    data = durationMetrics.data(1);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
                                                   "wakelock1");
     EXPECT_EQ(1, data.slice_by_state_size());
@@ -1362,7 +1363,7 @@
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
               data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(240 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -1370,7 +1371,45 @@
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(4);
+    data = durationMetrics.data(2);
+    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
+                                                  "wakelock2");
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_value());
+    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
+              data.slice_by_state(0).value());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
+    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = durationMetrics.data(3);
+    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
+                                                  "wakelock2");
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_value());
+    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
+              data.slice_by_state(0).value());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(140 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
+    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = durationMetrics.data(4);
+    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
+                                                  "wakelock1");
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_value());
+    EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
+    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = durationMetrics.data(5);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock1");
     EXPECT_EQ(1, data.slice_by_state_size());
@@ -1378,12 +1417,24 @@
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
               data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(5);
+    data = durationMetrics.data(6);
+    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
+                                                  "wakelock2");
+    EXPECT_EQ(1, data.slice_by_state_size());
+    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
+    EXPECT_TRUE(data.slice_by_state(0).has_value());
+    EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
+    ASSERT_EQ(1, data.bucket_info_size());
+    EXPECT_EQ(15 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
+    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
+    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
+
+    data = durationMetrics.data(7);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock2");
     EXPECT_EQ(1, data.slice_by_state_size());
@@ -1391,7 +1442,7 @@
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
               data.slice_by_state(0).value());
-    EXPECT_EQ(2, data.bucket_info_size());
+    ASSERT_EQ(2, data.bucket_info_size());
     EXPECT_EQ(180 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
@@ -1399,32 +1450,7 @@
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
     EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
 
-    data = reports.reports(0).metrics(0).duration_metrics().data(6);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
-                                                  "wakelock2");
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(15 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = reports.reports(0).metrics(0).duration_metrics().data(7);
-    ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
-                                                  "wakelock1");
-    EXPECT_EQ(1, data.slice_by_state_size());
-    EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
-    EXPECT_TRUE(data.slice_by_state(0).has_value());
-    EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
-              data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
-    EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
-    EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
-    EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
-
-    data = reports.reports(0).metrics(0).duration_metrics().data(8);
+    data = durationMetrics.data(8);
     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
                                                   "wakelock2");
     EXPECT_EQ(1, data.slice_by_state_size());
@@ -1432,7 +1458,7 @@
     EXPECT_TRUE(data.slice_by_state(0).has_value());
     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
               data.slice_by_state(0).value());
-    EXPECT_EQ(1, data.bucket_info_size());
+    ASSERT_EQ(1, data.bucket_info_size());
     EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index f1e2744..ba8d283 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -391,7 +391,6 @@
     backfillStartEndTimestamp(&reports);
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(4, reports.reports(0).metrics(0).count_metrics().data_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
@@ -699,7 +698,6 @@
     backfillStartEndTimestamp(&reports);
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(5, reports.reports(0).metrics(0).count_metrics().data_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
@@ -1033,7 +1031,6 @@
     backfillStartEndTimestamp(&reports);
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(5, reports.reports(0).metrics(0).count_metrics().data_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
@@ -1257,7 +1254,6 @@
     backfillStartEndTimestamp(&reports);
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(1, reports.reports(0).metrics_size());
-    EXPECT_EQ(3, reports.reports(0).metrics(0).count_metrics().data_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).count_metrics(), &countMetrics);
@@ -1695,8 +1691,6 @@
     backfillStartEndTimestamp(&reports);
     EXPECT_EQ(1, reports.reports_size());
     EXPECT_EQ(2, reports.reports(0).metrics_size());
-    EXPECT_EQ(5, reports.reports(0).metrics(0).count_metrics().data_size());
-    EXPECT_EQ(5, reports.reports(0).metrics(1).count_metrics().data_size());
 
     StatsLogReport::CountMetricDataWrapper countMetrics;
 
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 009e49a..3b4d646 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -3726,7 +3726,8 @@
                 return true;
             }));
 
-    const StateMap& stateMap = CreateScreenStateOnOffMap();
+    const StateMap& stateMap =
+            CreateScreenStateOnOffMap(/*screen on id=*/321, /*screen off id=*/123);
     const StateMap_StateGroup screenOnGroup = stateMap.group(0);
     const StateMap_StateGroup screenOffGroup = stateMap.group(1);
 
diff --git a/cmds/statsd/tests/statsd_test_util.cpp b/cmds/statsd/tests/statsd_test_util.cpp
index ed3cf5b..687014f 100644
--- a/cmds/statsd/tests/statsd_test_util.cpp
+++ b/cmds/statsd/tests/statsd_test_util.cpp
@@ -324,40 +324,29 @@
     return state;
 }
 
-State CreateScreenStateWithOnOffMap() {
+State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId) {
     State state;
     state.set_id(StringToId("ScreenStateOnOff"));
     state.set_atom_id(util::SCREEN_STATE_CHANGED);
 
-    auto map = CreateScreenStateOnOffMap();
+    auto map = CreateScreenStateOnOffMap(screenOnId, screenOffId);
     *state.mutable_map() = map;
 
     return state;
 }
 
-State CreateScreenStateWithInDozeMap() {
-    State state;
-    state.set_id(StringToId("ScreenStateInDoze"));
-    state.set_atom_id(util::SCREEN_STATE_CHANGED);
-
-    auto map = CreateScreenStateInDozeMap();
-    *state.mutable_map() = map;
-
-    return state;
-}
-
-StateMap_StateGroup CreateScreenStateOnGroup() {
+StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId) {
     StateMap_StateGroup group;
-    group.set_group_id(StringToId("SCREEN_ON"));
+    group.set_group_id(screenOnId);
     group.add_value(2);
     group.add_value(5);
     group.add_value(6);
     return group;
 }
 
-StateMap_StateGroup CreateScreenStateOffGroup() {
+StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId) {
     StateMap_StateGroup group;
-    group.set_group_id(StringToId("SCREEN_OFF"));
+    group.set_group_id(screenOffId);
     group.add_value(0);
     group.add_value(1);
     group.add_value(3);
@@ -365,36 +354,10 @@
     return group;
 }
 
-StateMap CreateScreenStateOnOffMap() {
+StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId) {
     StateMap map;
-    *map.add_group() = CreateScreenStateOnGroup();
-    *map.add_group() = CreateScreenStateOffGroup();
-    return map;
-}
-
-StateMap_StateGroup CreateScreenStateInDozeGroup() {
-    StateMap_StateGroup group;
-    group.set_group_id(StringToId("SCREEN_DOZE"));
-    group.add_value(3);
-    group.add_value(4);
-    return group;
-}
-
-StateMap_StateGroup CreateScreenStateNotDozeGroup() {
-    StateMap_StateGroup group;
-    group.set_group_id(StringToId("SCREEN_NOT_DOZE"));
-    group.add_value(0);
-    group.add_value(1);
-    group.add_value(2);
-    group.add_value(5);
-    group.add_value(6);
-    return group;
-}
-
-StateMap CreateScreenStateInDozeMap() {
-    StateMap map;
-    *map.add_group() = CreateScreenStateInDozeGroup();
-    *map.add_group() = CreateScreenStateNotDozeGroup();
+    *map.add_group() = CreateScreenStateOnGroup(screenOnId);
+    *map.add_group() = CreateScreenStateOffGroup(screenOffId);
     return map;
 }
 
@@ -1038,6 +1001,27 @@
     }
 }
 
+bool LessThan(const google::protobuf::RepeatedPtrField<StateValue>& s1,
+              const google::protobuf::RepeatedPtrField<StateValue>& s2) {
+    if (s1.size() != s2.size()) {
+        return s1.size() < s2.size();
+    }
+    for (int i = 0; i < s1.size(); i++) {
+        const StateValue& state1 = s1[i];
+        const StateValue& state2 = s2[i];
+        if (state1.atom_id() != state2.atom_id()) {
+            return state1.atom_id() < state2.atom_id();
+        }
+        if (state1.value() != state2.value()) {
+            return state1.value() < state2.value();
+        }
+        if (state1.group_id() != state2.group_id()) {
+            return state1.group_id() < state2.group_id();
+        }
+    }
+    return false;
+}
+
 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2) {
     if (s1.field() != s2.field()) {
         return s1.field() < s2.field();
@@ -1086,7 +1070,7 @@
         return false;
     }
 
-    return LessThan(s1.dimInCondition, s2.dimInCondition);
+    return LessThan(s1.stateValues, s2.stateValues);
 }
 
 void backfillStringInDimension(const std::map<uint64_t, string>& str_map,
diff --git a/cmds/statsd/tests/statsd_test_util.h b/cmds/statsd/tests/statsd_test_util.h
index d6ea77eb..37b9889 100644
--- a/cmds/statsd/tests/statsd_test_util.h
+++ b/cmds/statsd/tests/statsd_test_util.h
@@ -138,27 +138,16 @@
 // Create State proto for overlay state atom.
 State CreateOverlayState();
 
-State CreateScreenStateWithOnOffMap();
-
-State CreateScreenStateWithInDozeMap();
+State CreateScreenStateWithOnOffMap(int64_t screenOnId, int64_t screenOffId);
 
 // Create StateGroup proto for ScreenState ON group
-StateMap_StateGroup CreateScreenStateOnGroup();
+StateMap_StateGroup CreateScreenStateOnGroup(int64_t screenOnId);
 
 // Create StateGroup proto for ScreenState OFF group
-StateMap_StateGroup CreateScreenStateOffGroup();
+StateMap_StateGroup CreateScreenStateOffGroup(int64_t screenOffId);
 
 // Create StateMap proto for ScreenState ON/OFF map
-StateMap CreateScreenStateOnOffMap();
-
-// Create StateGroup proto for ScreenState IN DOZE group
-StateMap_StateGroup CreateScreenStateInDozeGroup();
-
-// Create StateGroup proto for ScreenState NOT IN DOZE group
-StateMap_StateGroup CreateScreenStateNotDozeGroup();
-
-// Create StateMap proto for ScreenState IN DOZE map
-StateMap CreateScreenStateInDozeMap();
+StateMap CreateScreenStateOnOffMap(int64_t screenOnId, int64_t screenOffId);
 
 // Add a predicate to the predicate combination.
 void addPredicateToPredicateCombination(const Predicate& predicate, Predicate* combination);
@@ -319,12 +308,14 @@
     const DimensionsValue& value, int node_idx, int atomId, int uid, const std::string& tag);
 
 struct DimensionsPair {
-    DimensionsPair(DimensionsValue m1, DimensionsValue m2) : dimInWhat(m1), dimInCondition(m2){};
+    DimensionsPair(DimensionsValue m1, google::protobuf::RepeatedPtrField<StateValue> m2)
+        : dimInWhat(m1), stateValues(m2){};
 
     DimensionsValue dimInWhat;
-    DimensionsValue dimInCondition;
+    google::protobuf::RepeatedPtrField<StateValue> stateValues;
 };
 
+bool LessThan(const StateValue& s1, const StateValue& s2);
 bool LessThan(const DimensionsValue& s1, const DimensionsValue& s2);
 bool LessThan(const DimensionsPair& s1, const DimensionsPair& s2);
 
@@ -393,7 +384,7 @@
     for (int i = 0; i < metricData.data_size(); ++i) {
         dimensionIndexMap.insert(
                 std::make_pair(DimensionsPair(metricData.data(i).dimensions_in_what(),
-                                              metricData.data(i).dimensions_in_condition()),
+                                              metricData.data(i).slice_by_state()),
                                i));
     }
     for (const auto& itr : dimensionIndexMap) {