• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <gtest/gtest.h>
16 
17 #include <vector>
18 
19 #include "src/StatsLogProcessor.h"
20 #include "src/state/StateTracker.h"
21 #include "src/stats_log_util.h"
22 #include "tests/statsd_test_util.h"
23 
24 namespace android {
25 namespace os {
26 namespace statsd {
27 
28 #ifdef __ANDROID__
29 
TEST(DurationMetricE2eTest,TestOneBucket)30 TEST(DurationMetricE2eTest, TestOneBucket) {
31     StatsdConfig config;
32     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
33 
34     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
35     auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
36     *config.add_atom_matcher() = screenOnMatcher;
37     *config.add_atom_matcher() = screenOffMatcher;
38 
39     auto durationPredicate = CreateScreenIsOnPredicate();
40     *config.add_predicate() = durationPredicate;
41 
42     int64_t metricId = 123456;
43     auto durationMetric = config.add_duration_metric();
44     durationMetric->set_id(metricId);
45     durationMetric->set_what(durationPredicate.id());
46     durationMetric->set_bucket(FIVE_MINUTES);
47     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
48 
49     const int64_t baseTimeNs = 0;                                   // 0:00
50     const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC;  // 0:01
51     const int64_t bucketSizeNs =
52             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
53 
54     int uid = 12345;
55     int64_t cfgId = 98765;
56     ConfigKey cfgKey(uid, cfgId);
57 
58     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
59 
60     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
61     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
62     EXPECT_TRUE(metricsManager->isConfigValid());
63     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
64     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
65     EXPECT_TRUE(metricsManager->isActive());
66     EXPECT_TRUE(metricProducer->mIsActive);
67 
68     std::unique_ptr<LogEvent> event;
69 
70     // Screen is off at start of bucket.
71     event = CreateScreenStateChangedEvent(configAddedTimeNs,
72                                           android::view::DISPLAY_STATE_OFF);  // 0:01
73     processor->OnLogEvent(event.get());
74 
75     // Turn screen on.
76     const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC;  // 0:11
77     event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
78     processor->OnLogEvent(event.get());
79 
80     // Turn off screen 30 seconds after turning on.
81     const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC;  // 0:41
82     event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
83     processor->OnLogEvent(event.get());
84 
85     event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64);  // 0:42
86     processor->OnLogEvent(event.get());
87 
88     ConfigMetricsReportList reports;
89     vector<uint8_t> buffer;
90     processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
91                             ADB_DUMP, FAST, &buffer);  // 5:01
92     EXPECT_TRUE(buffer.size() > 0);
93     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
94     backfillDimensionPath(&reports);
95     backfillStartEndTimestamp(&reports);
96     ASSERT_EQ(1, reports.reports_size());
97     ASSERT_EQ(1, reports.reports(0).metrics_size());
98     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
99     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
100 
101     StatsLogReport::DurationMetricDataWrapper durationMetrics;
102     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
103                                     &durationMetrics);
104     ASSERT_EQ(1, durationMetrics.data_size());
105 
106     DurationMetricData data = durationMetrics.data(0);
107     ASSERT_EQ(1, data.bucket_info_size());
108     EXPECT_EQ(durationEndNs - durationStartNs, data.bucket_info(0).duration_nanos());
109     EXPECT_EQ(configAddedTimeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
110     EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).end_bucket_elapsed_nanos());
111 }
112 
TEST(DurationMetricE2eTest,TestTwoBuckets)113 TEST(DurationMetricE2eTest, TestTwoBuckets) {
114     StatsdConfig config;
115     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
116 
117     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
118     auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
119     *config.add_atom_matcher() = screenOnMatcher;
120     *config.add_atom_matcher() = screenOffMatcher;
121 
122     auto durationPredicate = CreateScreenIsOnPredicate();
123     *config.add_predicate() = durationPredicate;
124 
125     int64_t metricId = 123456;
126     auto durationMetric = config.add_duration_metric();
127     durationMetric->set_id(metricId);
128     durationMetric->set_what(durationPredicate.id());
129     durationMetric->set_bucket(FIVE_MINUTES);
130     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
131 
132     const int64_t baseTimeNs = 0;                                   // 0:00
133     const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC;  // 0:01
134     const int64_t bucketSizeNs =
135             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
136 
137     int uid = 12345;
138     int64_t cfgId = 98765;
139     ConfigKey cfgKey(uid, cfgId);
140 
141     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
142 
143     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
144     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
145     EXPECT_TRUE(metricsManager->isConfigValid());
146     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
147     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
148     EXPECT_TRUE(metricsManager->isActive());
149     EXPECT_TRUE(metricProducer->mIsActive);
150 
151     std::unique_ptr<LogEvent> event;
152 
153     // Screen is off at start of bucket.
154     event = CreateScreenStateChangedEvent(configAddedTimeNs,
155                                           android::view::DISPLAY_STATE_OFF);  // 0:01
156     processor->OnLogEvent(event.get());
157 
158     // Turn screen on.
159     const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC;  // 0:11
160     event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
161     processor->OnLogEvent(event.get());
162 
163     // Turn off screen 30 seconds after turning on.
164     const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC;  // 0:41
165     event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
166     processor->OnLogEvent(event.get());
167 
168     event = CreateScreenBrightnessChangedEvent(durationEndNs + 1 * NS_PER_SEC, 64);  // 0:42
169     processor->OnLogEvent(event.get());
170 
171     ConfigMetricsReportList reports;
172     vector<uint8_t> buffer;
173     processor->onDumpReport(cfgKey, configAddedTimeNs + 2 * bucketSizeNs + 1 * NS_PER_SEC, false,
174                             true, ADB_DUMP, FAST, &buffer);  // 10:01
175     EXPECT_TRUE(buffer.size() > 0);
176     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
177     backfillDimensionPath(&reports);
178     backfillStartEndTimestamp(&reports);
179     ASSERT_EQ(1, reports.reports_size());
180     ASSERT_EQ(1, reports.reports(0).metrics_size());
181     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
182     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
183 
184     StatsLogReport::DurationMetricDataWrapper durationMetrics;
185     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
186                                     &durationMetrics);
187     ASSERT_EQ(1, durationMetrics.data_size());
188 
189     DurationMetricData data = durationMetrics.data(0);
190     ASSERT_EQ(1, data.bucket_info_size());
191 
192     auto bucketInfo = data.bucket_info(0);
193     EXPECT_EQ(0, bucketInfo.bucket_num());
194     EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
195     EXPECT_EQ(configAddedTimeNs, bucketInfo.start_bucket_elapsed_nanos());
196     EXPECT_EQ(baseTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
197 }
198 
TEST(DurationMetricE2eTest,TestWithActivation)199 TEST(DurationMetricE2eTest, TestWithActivation) {
200     StatsdConfig config;
201     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
202 
203     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
204     auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
205     auto crashMatcher = CreateProcessCrashAtomMatcher();
206     *config.add_atom_matcher() = screenOnMatcher;
207     *config.add_atom_matcher() = screenOffMatcher;
208     *config.add_atom_matcher() = crashMatcher;
209 
210     auto durationPredicate = CreateScreenIsOnPredicate();
211     *config.add_predicate() = durationPredicate;
212 
213     int64_t metricId = 123456;
214     auto durationMetric = config.add_duration_metric();
215     durationMetric->set_id(metricId);
216     durationMetric->set_what(durationPredicate.id());
217     durationMetric->set_bucket(FIVE_MINUTES);
218     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
219 
220     auto metric_activation1 = config.add_metric_activation();
221     metric_activation1->set_metric_id(metricId);
222     auto event_activation1 = metric_activation1->add_event_activation();
223     event_activation1->set_atom_matcher_id(crashMatcher.id());
224     event_activation1->set_ttl_seconds(30);  // 30 secs.
225 
226     const int64_t bucketStartTimeNs = 10000000000;
227     const int64_t bucketSizeNs =
228             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
229 
230     int uid = 12345;
231     int64_t cfgId = 98765;
232     ConfigKey cfgKey(uid, cfgId);
233 
234     sp<UidMap> m = new UidMap();
235     sp<StatsPullerManager> pullerManager = new StatsPullerManager();
236     sp<AlarmMonitor> anomalyAlarmMonitor;
237     sp<AlarmMonitor> subscriberAlarmMonitor;
238     vector<int64_t> activeConfigsBroadcast;
239 
240     int broadcastCount = 0;
241     StatsLogProcessor processor(
242             m, pullerManager, anomalyAlarmMonitor, subscriberAlarmMonitor, bucketStartTimeNs,
243             [](const ConfigKey& key) { return true; },
244             [&uid, &broadcastCount, &activeConfigsBroadcast](const int& broadcastUid,
245                                                              const vector<int64_t>& activeConfigs) {
246                 broadcastCount++;
247                 EXPECT_EQ(broadcastUid, uid);
248                 activeConfigsBroadcast.clear();
249                 activeConfigsBroadcast.insert(activeConfigsBroadcast.end(), activeConfigs.begin(),
250                                               activeConfigs.end());
251                 return true;
252             });
253 
254     processor.OnConfigUpdated(bucketStartTimeNs, cfgKey, config);  // 0:00
255 
256     ASSERT_EQ(processor.mMetricsManagers.size(), 1u);
257     sp<MetricsManager> metricsManager = processor.mMetricsManagers.begin()->second;
258     EXPECT_TRUE(metricsManager->isConfigValid());
259     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
260     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
261     auto& eventActivationMap = metricProducer->mEventActivationMap;
262 
263     EXPECT_FALSE(metricsManager->isActive());
264     EXPECT_FALSE(metricProducer->mIsActive);
265     ASSERT_EQ(eventActivationMap.size(), 1u);
266     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
267     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
268     EXPECT_EQ(eventActivationMap[2]->start_ns, 0);
269     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
270 
271     std::unique_ptr<LogEvent> event;
272 
273     // Turn screen off.
274     event = CreateScreenStateChangedEvent(bucketStartTimeNs + 2 * NS_PER_SEC,
275                                           android::view::DISPLAY_STATE_OFF);  // 0:02
276     processor.OnLogEvent(event.get(), bucketStartTimeNs + 2 * NS_PER_SEC);
277 
278     // Turn screen on.
279     const int64_t durationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC;  // 0:05
280     event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
281     processor.OnLogEvent(event.get(), durationStartNs);
282 
283     // Activate metric.
284     const int64_t activationStartNs = bucketStartTimeNs + 5 * NS_PER_SEC;  // 0:10
285     const int64_t activationEndNs =
286             activationStartNs + event_activation1->ttl_seconds() * NS_PER_SEC;  // 0:40
287     event = CreateAppCrashEvent(activationStartNs, 111);
288     processor.OnLogEvent(event.get(), activationStartNs);
289     EXPECT_TRUE(metricsManager->isActive());
290     EXPECT_TRUE(metricProducer->mIsActive);
291     EXPECT_EQ(broadcastCount, 1);
292     ASSERT_EQ(activeConfigsBroadcast.size(), 1);
293     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
294     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
295     EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
296     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
297 
298     // Expire activation.
299     const int64_t expirationNs = activationEndNs + 7 * NS_PER_SEC;
300     event = CreateScreenBrightnessChangedEvent(expirationNs, 64);  // 0:47
301     processor.OnLogEvent(event.get(), expirationNs);
302     EXPECT_FALSE(metricsManager->isActive());
303     EXPECT_FALSE(metricProducer->mIsActive);
304     EXPECT_EQ(broadcastCount, 2);
305     ASSERT_EQ(activeConfigsBroadcast.size(), 0);
306     ASSERT_EQ(eventActivationMap.size(), 1u);
307     EXPECT_TRUE(eventActivationMap.find(2) != eventActivationMap.end());
308     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kNotActive);
309     EXPECT_EQ(eventActivationMap[2]->start_ns, activationStartNs);
310     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
311 
312     // Turn off screen 10 seconds after activation expiration.
313     const int64_t durationEndNs = activationEndNs + 10 * NS_PER_SEC;  // 0:50
314     event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
315     processor.OnLogEvent(event.get(), durationEndNs);
316 
317     // Turn screen on.
318     const int64_t duration2StartNs = durationEndNs + 5 * NS_PER_SEC;  // 0:55
319     event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
320     processor.OnLogEvent(event.get(), duration2StartNs);
321 
322     // Turn off screen.
323     const int64_t duration2EndNs = duration2StartNs + 10 * NS_PER_SEC;  // 1:05
324     event = CreateScreenStateChangedEvent(duration2EndNs, android::view::DISPLAY_STATE_OFF);
325     processor.OnLogEvent(event.get(), duration2EndNs);
326 
327     // Activate metric.
328     const int64_t activation2StartNs = duration2EndNs + 5 * NS_PER_SEC;  // 1:10
329     const int64_t activation2EndNs =
330             activation2StartNs + event_activation1->ttl_seconds() * NS_PER_SEC;  // 1:40
331     event = CreateAppCrashEvent(activation2StartNs, 211);
332     processor.OnLogEvent(event.get(), activation2StartNs);
333     EXPECT_TRUE(metricsManager->isActive());
334     EXPECT_TRUE(metricProducer->mIsActive);
335     EXPECT_EQ(broadcastCount, 3);
336     ASSERT_EQ(activeConfigsBroadcast.size(), 1);
337     EXPECT_EQ(activeConfigsBroadcast[0], cfgId);
338     EXPECT_EQ(eventActivationMap[2]->state, ActivationState::kActive);
339     EXPECT_EQ(eventActivationMap[2]->start_ns, activation2StartNs);
340     EXPECT_EQ(eventActivationMap[2]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
341 
342     ConfigMetricsReportList reports;
343     vector<uint8_t> buffer;
344     processor.onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1 * NS_PER_SEC, false, true,
345                            ADB_DUMP, FAST, &buffer);  // 5:01
346     EXPECT_TRUE(buffer.size() > 0);
347     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
348     backfillDimensionPath(&reports);
349     backfillStartEndTimestamp(&reports);
350     ASSERT_EQ(1, reports.reports_size());
351     ASSERT_EQ(1, reports.reports(0).metrics_size());
352     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
353     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
354 
355     StatsLogReport::DurationMetricDataWrapper durationMetrics;
356     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
357                                     &durationMetrics);
358     ASSERT_EQ(1, durationMetrics.data_size());
359 
360     DurationMetricData data = durationMetrics.data(0);
361     ASSERT_EQ(1, data.bucket_info_size());
362 
363     auto bucketInfo = data.bucket_info(0);
364     EXPECT_EQ(0, bucketInfo.bucket_num());
365     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
366     EXPECT_EQ(expirationNs, bucketInfo.end_bucket_elapsed_nanos());
367     EXPECT_EQ(expirationNs - durationStartNs, bucketInfo.duration_nanos());
368 }
369 
TEST(DurationMetricE2eTest,TestWithCondition)370 TEST(DurationMetricE2eTest, TestWithCondition) {
371     StatsdConfig config;
372     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
373     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
374     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
375     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
376     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
377 
378     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
379     *config.add_predicate() = holdingWakelockPredicate;
380 
381     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
382     *config.add_predicate() = isInBackgroundPredicate;
383 
384     auto durationMetric = config.add_duration_metric();
385     durationMetric->set_id(StringToId("WakelockDuration"));
386     durationMetric->set_what(holdingWakelockPredicate.id());
387     durationMetric->set_condition(isInBackgroundPredicate.id());
388     durationMetric->set_aggregation_type(DurationMetric::SUM);
389     durationMetric->set_bucket(FIVE_MINUTES);
390 
391     ConfigKey cfgKey;
392     uint64_t bucketStartTimeNs = 10000000000;
393     uint64_t bucketSizeNs =
394             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
395     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
396     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
397     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
398     EXPECT_TRUE(metricsManager->isConfigValid());
399     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
400     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
401     auto& eventActivationMap = metricProducer->mEventActivationMap;
402     EXPECT_TRUE(metricsManager->isActive());
403     EXPECT_TRUE(metricProducer->mIsActive);
404     EXPECT_TRUE(eventActivationMap.empty());
405 
406     int appUid = 123;
407     vector<int> attributionUids1 = {appUid};
408     vector<string> attributionTags1 = {"App1"};
409 
410     auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
411                                             attributionTags1,
412                                             "wl1");  // 0:10
413     processor->OnLogEvent(event.get());
414 
415     event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid);  // 0:22
416     processor->OnLogEvent(event.get());
417 
418     event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
419                                         appUid);  // 3:15
420     processor->OnLogEvent(event.get());
421 
422     event = CreateReleaseWakelockEvent(bucketStartTimeNs + 4 * 60 * NS_PER_SEC, attributionUids1,
423                                        attributionTags1,
424                                        "wl1");  // 4:00
425     processor->OnLogEvent(event.get());
426 
427     vector<uint8_t> buffer;
428     ConfigMetricsReportList reports;
429     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
430                             FAST, &buffer);
431     ASSERT_GT(buffer.size(), 0);
432     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
433     backfillDimensionPath(&reports);
434     backfillStringInReport(&reports);
435     backfillStartEndTimestamp(&reports);
436 
437     ASSERT_EQ(1, reports.reports_size());
438     ASSERT_EQ(1, reports.reports(0).metrics_size());
439     StatsLogReport::DurationMetricDataWrapper durationMetrics;
440     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
441                                     &durationMetrics);
442     ASSERT_EQ(1, durationMetrics.data_size());
443 
444     DurationMetricData data = durationMetrics.data(0);
445 
446     // Validate bucket info.
447     ASSERT_EQ(1, data.bucket_info_size());
448 
449     auto bucketInfo = data.bucket_info(0);
450     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
451     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
452     EXPECT_EQ((2 * 60 + 53) * NS_PER_SEC, bucketInfo.duration_nanos());
453 }
454 
TEST(DurationMetricE2eTest,TestWithSlicedCondition)455 TEST(DurationMetricE2eTest, TestWithSlicedCondition) {
456     StatsdConfig config;
457     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
458     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
459     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
460     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
461     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
462     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
463 
464     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
465     // The predicate is dimensioning by first attribution node by uid.
466     FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
467                                                              {Position::FIRST});
468     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
469     *config.add_predicate() = holdingWakelockPredicate;
470 
471     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
472     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
473             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
474     *config.add_predicate() = isInBackgroundPredicate;
475 
476     auto durationMetric = config.add_duration_metric();
477     durationMetric->set_id(StringToId("WakelockDuration"));
478     durationMetric->set_what(holdingWakelockPredicate.id());
479     durationMetric->set_condition(isInBackgroundPredicate.id());
480     durationMetric->set_aggregation_type(DurationMetric::SUM);
481     // The metric is dimensioning by first attribution node and only by uid.
482     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
483             util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
484     durationMetric->set_bucket(FIVE_MINUTES);
485 
486     // Links between wakelock state atom and condition of app is in background.
487     auto links = durationMetric->add_links();
488     links->set_condition(isInBackgroundPredicate.id());
489     *links->mutable_fields_in_what() =
490             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
491     auto dimensionCondition = links->mutable_fields_in_condition();
492     dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
493     dimensionCondition->add_child()->set_field(1);  // uid field.
494 
495     ConfigKey cfgKey;
496     uint64_t bucketStartTimeNs = 10000000000;
497     uint64_t bucketSizeNs =
498             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
499     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
500     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
501     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
502     EXPECT_TRUE(metricsManager->isConfigValid());
503     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
504     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
505     auto& eventActivationMap = metricProducer->mEventActivationMap;
506     EXPECT_TRUE(metricsManager->isActive());
507     EXPECT_TRUE(metricProducer->mIsActive);
508     EXPECT_TRUE(eventActivationMap.empty());
509 
510     int appUid = 123;
511     std::vector<int> attributionUids1 = {appUid};
512     std::vector<string> attributionTags1 = {"App1"};
513 
514     auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
515                                             attributionTags1, "wl1");  // 0:10
516     processor->OnLogEvent(event.get());
517 
518     event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid);  // 0:22
519     processor->OnLogEvent(event.get());
520 
521     event = CreateReleaseWakelockEvent(bucketStartTimeNs + 60 * NS_PER_SEC, attributionUids1,
522                                        attributionTags1, "wl1");  // 1:00
523     processor->OnLogEvent(event.get());
524 
525     event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
526                                         appUid);  // 3:15
527     processor->OnLogEvent(event.get());
528 
529     vector<uint8_t> buffer;
530     ConfigMetricsReportList reports;
531     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
532                             FAST, &buffer);
533     ASSERT_GT(buffer.size(), 0);
534     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
535     backfillDimensionPath(&reports);
536     backfillStringInReport(&reports);
537     backfillStartEndTimestamp(&reports);
538 
539     ASSERT_EQ(1, reports.reports_size());
540     ASSERT_EQ(1, reports.reports(0).metrics_size());
541     StatsLogReport::DurationMetricDataWrapper durationMetrics;
542     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
543                                     &durationMetrics);
544     ASSERT_EQ(1, durationMetrics.data_size());
545 
546     DurationMetricData data = durationMetrics.data(0);
547     // Validate dimension value.
548     ValidateAttributionUidDimension(data.dimensions_in_what(),
549                                     util::WAKELOCK_STATE_CHANGED, appUid);
550     // Validate bucket info.
551     ASSERT_EQ(1, data.bucket_info_size());
552 
553     auto bucketInfo = data.bucket_info(0);
554     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
555     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
556     EXPECT_EQ(38 * NS_PER_SEC, bucketInfo.duration_nanos());
557 }
558 
TEST(DurationMetricE2eTest,TestWithActivationAndSlicedCondition)559 TEST(DurationMetricE2eTest, TestWithActivationAndSlicedCondition) {
560     StatsdConfig config;
561     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
562     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
563     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
564     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
565     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
566     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
567     *config.add_atom_matcher() = screenOnMatcher;
568 
569     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
570     // The predicate is dimensioning by first attribution node by uid.
571     FieldMatcher dimensions = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED,
572                                                              {Position::FIRST});
573     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() = dimensions;
574     *config.add_predicate() = holdingWakelockPredicate;
575 
576     auto isInBackgroundPredicate = CreateIsInBackgroundPredicate();
577     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
578             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {Position::FIRST});
579     *config.add_predicate() = isInBackgroundPredicate;
580 
581     auto durationMetric = config.add_duration_metric();
582     durationMetric->set_id(StringToId("WakelockDuration"));
583     durationMetric->set_what(holdingWakelockPredicate.id());
584     durationMetric->set_condition(isInBackgroundPredicate.id());
585     durationMetric->set_aggregation_type(DurationMetric::SUM);
586     // The metric is dimensioning by first attribution node and only by uid.
587     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidDimensions(
588             util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
589     durationMetric->set_bucket(FIVE_MINUTES);
590 
591     // Links between wakelock state atom and condition of app is in background.
592     auto links = durationMetric->add_links();
593     links->set_condition(isInBackgroundPredicate.id());
594     *links->mutable_fields_in_what() =
595             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
596     auto dimensionCondition = links->mutable_fields_in_condition();
597     dimensionCondition->set_field(util::ACTIVITY_FOREGROUND_STATE_CHANGED);
598     dimensionCondition->add_child()->set_field(1);  // uid field.
599 
600     auto metric_activation1 = config.add_metric_activation();
601     metric_activation1->set_metric_id(durationMetric->id());
602     auto event_activation1 = metric_activation1->add_event_activation();
603     event_activation1->set_atom_matcher_id(screenOnMatcher.id());
604     event_activation1->set_ttl_seconds(60 * 2);  // 2 minutes.
605 
606     ConfigKey cfgKey;
607     uint64_t bucketStartTimeNs = 10000000000;
608     uint64_t bucketSizeNs =
609             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
610     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
611     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
612     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
613     EXPECT_TRUE(metricsManager->isConfigValid());
614     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
615     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
616     auto& eventActivationMap = metricProducer->mEventActivationMap;
617     EXPECT_FALSE(metricsManager->isActive());
618     EXPECT_FALSE(metricProducer->mIsActive);
619     ASSERT_EQ(eventActivationMap.size(), 1u);
620     EXPECT_TRUE(eventActivationMap.find(4) != eventActivationMap.end());
621     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
622     EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
623     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
624 
625     int appUid = 123;
626     std::vector<int> attributionUids1 = {appUid};
627     std::vector<string> attributionTags1 = {"App1"};
628 
629     auto event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
630                                             attributionTags1, "wl1");  // 0:10
631     processor->OnLogEvent(event.get());
632     EXPECT_FALSE(metricsManager->isActive());
633     EXPECT_FALSE(metricProducer->mIsActive);
634     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
635     EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
636     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
637 
638     event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, appUid);  // 0:22
639     processor->OnLogEvent(event.get());
640     EXPECT_FALSE(metricsManager->isActive());
641     EXPECT_FALSE(metricProducer->mIsActive);
642     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
643     EXPECT_EQ(eventActivationMap[4]->start_ns, 0);
644     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
645 
646     const int64_t durationStartNs = bucketStartTimeNs + 30 * NS_PER_SEC;  // 0:30
647     event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
648     processor->OnLogEvent(event.get());
649     EXPECT_TRUE(metricsManager->isActive());
650     EXPECT_TRUE(metricProducer->mIsActive);
651     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
652     EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
653     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
654 
655     const int64_t durationEndNs =
656             durationStartNs + (event_activation1->ttl_seconds() + 30) * NS_PER_SEC;  // 3:00
657     event = CreateAppCrashEvent(durationEndNs, 333);
658     processor->OnLogEvent(event.get());
659     EXPECT_FALSE(metricsManager->isActive());
660     EXPECT_FALSE(metricProducer->mIsActive);
661     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kNotActive);
662     EXPECT_EQ(eventActivationMap[4]->start_ns, durationStartNs);
663     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
664 
665     event = CreateMoveToForegroundEvent(bucketStartTimeNs + (3 * 60 + 15) * NS_PER_SEC,
666                                         appUid);  // 3:15
667     processor->OnLogEvent(event.get());
668 
669     event = CreateReleaseWakelockEvent(bucketStartTimeNs + (4 * 60 + 17) * NS_PER_SEC,
670                                        attributionUids1, attributionTags1, "wl1");  // 4:17
671     processor->OnLogEvent(event.get());
672 
673     event = CreateMoveToBackgroundEvent(bucketStartTimeNs + (4 * 60 + 20) * NS_PER_SEC,
674                                         appUid);  // 4:20
675     processor->OnLogEvent(event.get());
676 
677     event = CreateAcquireWakelockEvent(bucketStartTimeNs + (4 * 60 + 25) * NS_PER_SEC,
678                                        attributionUids1, attributionTags1, "wl1");  // 4:25
679     processor->OnLogEvent(event.get());
680 
681     const int64_t duration2StartNs = bucketStartTimeNs + (4 * 60 + 30) * NS_PER_SEC;  // 4:30
682     event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
683     processor->OnLogEvent(event.get());
684     EXPECT_TRUE(metricsManager->isActive());
685     EXPECT_TRUE(metricProducer->mIsActive);
686     EXPECT_EQ(eventActivationMap[4]->state, ActivationState::kActive);
687     EXPECT_EQ(eventActivationMap[4]->start_ns, duration2StartNs);
688     EXPECT_EQ(eventActivationMap[4]->ttl_ns, event_activation1->ttl_seconds() * NS_PER_SEC);
689 
690     vector<uint8_t> buffer;
691     ConfigMetricsReportList reports;
692     processor->onDumpReport(cfgKey, bucketStartTimeNs + bucketSizeNs + 1, false, true, ADB_DUMP,
693                             FAST, &buffer);
694     ASSERT_GT(buffer.size(), 0);
695     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
696     backfillDimensionPath(&reports);
697     backfillStringInReport(&reports);
698     backfillStartEndTimestamp(&reports);
699 
700     ASSERT_EQ(1, reports.reports_size());
701     ASSERT_EQ(1, reports.reports(0).metrics_size());
702     StatsLogReport::DurationMetricDataWrapper durationMetrics;
703     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
704                                     &durationMetrics);
705     ASSERT_EQ(1, durationMetrics.data_size());
706 
707     DurationMetricData data = durationMetrics.data(0);
708     // Validate dimension value.
709     ValidateAttributionUidDimension(data.dimensions_in_what(),
710                                     util::WAKELOCK_STATE_CHANGED, appUid);
711     // Validate bucket info.
712     ASSERT_EQ(2, data.bucket_info_size());
713 
714     auto bucketInfo = data.bucket_info(0);
715     EXPECT_EQ(bucketStartTimeNs, bucketInfo.start_bucket_elapsed_nanos());
716     EXPECT_EQ(durationEndNs, bucketInfo.end_bucket_elapsed_nanos());
717     EXPECT_EQ(durationEndNs - durationStartNs, bucketInfo.duration_nanos());
718 
719     bucketInfo = data.bucket_info(1);
720     EXPECT_EQ(durationEndNs, bucketInfo.start_bucket_elapsed_nanos());
721     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs, bucketInfo.end_bucket_elapsed_nanos());
722     EXPECT_EQ(bucketStartTimeNs + bucketSizeNs - duration2StartNs, bucketInfo.duration_nanos());
723 }
724 
TEST(DurationMetricE2eTest,TestWithSlicedState)725 TEST(DurationMetricE2eTest, TestWithSlicedState) {
726     // Initialize config.
727     StatsdConfig config;
728     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
729 
730     *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
731     *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
732 
733     auto batterySaverModePredicate = CreateBatterySaverModePredicate();
734     *config.add_predicate() = batterySaverModePredicate;
735 
736     auto screenState = CreateScreenState();
737     *config.add_state() = screenState;
738 
739     // Create duration metric that slices by screen state.
740     auto durationMetric = config.add_duration_metric();
741     durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreen"));
742     durationMetric->set_what(batterySaverModePredicate.id());
743     durationMetric->add_slice_by_state(screenState.id());
744     durationMetric->set_aggregation_type(DurationMetric::SUM);
745     durationMetric->set_bucket(FIVE_MINUTES);
746 
747     // Initialize StatsLogProcessor.
748     int uid = 12345;
749     int64_t cfgId = 98765;
750     ConfigKey cfgKey(uid, cfgId);
751     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
752     uint64_t bucketSizeNs =
753             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
754     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
755 
756     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
757     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
758     EXPECT_TRUE(metricsManager->isConfigValid());
759     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
760     EXPECT_TRUE(metricsManager->isActive());
761     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
762     EXPECT_TRUE(metricProducer->mIsActive);
763     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
764     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
765     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
766 
767     // Check that StateTrackers were initialized correctly.
768     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
769     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
770 
771     /*
772                bucket #1                      bucket #2
773     |     1     2     3     4     5     6     7     8     9     10 (minutes)
774     |-----------------------------|-----------------------------|--
775         ON              OFF     ON                                  (BatterySaverMode)
776       |          |                   |                              (ScreenIsOnEvent)
777            |                  |                                     (ScreenIsOffEvent)
778               |                                                     (ScreenDozeEvent)
779     */
780     // Initialize log events.
781     std::vector<std::unique_ptr<LogEvent>> events;
782     events.push_back(CreateScreenStateChangedEvent(
783             bucketStartTimeNs + 10 * NS_PER_SEC,
784             android::view::DisplayStateEnum::DISPLAY_STATE_ON));                       // 0:20
785     events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC));  // 0:30
786     events.push_back(CreateScreenStateChangedEvent(
787             bucketStartTimeNs + 50 * NS_PER_SEC,
788             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:00
789     events.push_back(CreateScreenStateChangedEvent(
790             bucketStartTimeNs + 80 * NS_PER_SEC,
791             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 1:30
792     events.push_back(CreateScreenStateChangedEvent(
793             bucketStartTimeNs + 120 * NS_PER_SEC,
794             android::view::DisplayStateEnum::DISPLAY_STATE_ON));                         // 2:10
795     events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC));  // 3:30
796     events.push_back(CreateScreenStateChangedEvent(
797             bucketStartTimeNs + 250 * NS_PER_SEC,
798             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));                       // 4:20
799     events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC));  // 4:50
800 
801     // Bucket boundary.
802     events.push_back(CreateScreenStateChangedEvent(
803             bucketStartTimeNs + 310 * NS_PER_SEC,
804             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 5:20
805 
806     // Send log events to StatsLogProcessor.
807     for (auto& event : events) {
808         processor->OnLogEvent(event.get());
809     }
810 
811     // Check dump report.
812     vector<uint8_t> buffer;
813     ConfigMetricsReportList reports;
814     processor->onDumpReport(cfgKey, bucketStartTimeNs + 360 * NS_PER_SEC,
815                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
816                             &buffer);  // 6:10
817     ASSERT_GT(buffer.size(), 0);
818     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
819     backfillDimensionPath(&reports);
820     backfillStringInReport(&reports);
821     backfillStartEndTimestamp(&reports);
822 
823     ASSERT_EQ(1, reports.reports_size());
824     ASSERT_EQ(1, reports.reports(0).metrics_size());
825     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
826     StatsLogReport::DurationMetricDataWrapper durationMetrics;
827     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
828                                     &durationMetrics);
829     ASSERT_EQ(3, durationMetrics.data_size());
830 
831     DurationMetricData data = durationMetrics.data(0);
832     ASSERT_EQ(1, data.slice_by_state_size());
833     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
834     EXPECT_TRUE(data.slice_by_state(0).has_value());
835     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
836     ASSERT_EQ(2, data.bucket_info_size());
837     EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
838     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
839     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
840     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
841     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
842     EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
843 
844     data = durationMetrics.data(1);
845     ASSERT_EQ(1, data.slice_by_state_size());
846     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
847     EXPECT_TRUE(data.slice_by_state(0).has_value());
848     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
849     ASSERT_EQ(2, data.bucket_info_size());
850     EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
851     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
852     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
853     EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
854     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
855     EXPECT_EQ(370 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
856 
857     data = durationMetrics.data(2);
858     ASSERT_EQ(1, data.slice_by_state_size());
859     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
860     EXPECT_TRUE(data.slice_by_state(0).has_value());
861     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
862     ASSERT_EQ(1, data.bucket_info_size());
863     EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
864     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
865     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
866 }
867 
TEST(DurationMetricE2eTest,TestWithConditionAndSlicedState)868 TEST(DurationMetricE2eTest, TestWithConditionAndSlicedState) {
869     // Initialize config.
870     StatsdConfig config;
871     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
872 
873     *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
874     *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
875     *config.add_atom_matcher() = CreateBatteryStateNoneMatcher();
876     *config.add_atom_matcher() = CreateBatteryStateUsbMatcher();
877 
878     auto batterySaverModePredicate = CreateBatterySaverModePredicate();
879     *config.add_predicate() = batterySaverModePredicate;
880 
881     auto deviceUnpluggedPredicate = CreateDeviceUnpluggedPredicate();
882     *config.add_predicate() = deviceUnpluggedPredicate;
883 
884     auto screenState = CreateScreenState();
885     *config.add_state() = screenState;
886 
887     // Create duration metric that has a condition and slices by screen state.
888     auto durationMetric = config.add_duration_metric();
889     durationMetric->set_id(StringToId("DurationBatterySaverModeOnBatterySliceScreen"));
890     durationMetric->set_what(batterySaverModePredicate.id());
891     durationMetric->set_condition(deviceUnpluggedPredicate.id());
892     durationMetric->add_slice_by_state(screenState.id());
893     durationMetric->set_aggregation_type(DurationMetric::SUM);
894     durationMetric->set_bucket(FIVE_MINUTES);
895 
896     // Initialize StatsLogProcessor.
897     int uid = 12345;
898     int64_t cfgId = 98765;
899     ConfigKey cfgKey(uid, cfgId);
900     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
901     uint64_t bucketSizeNs =
902             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
903     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
904 
905     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
906     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
907     EXPECT_TRUE(metricsManager->isConfigValid());
908     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
909     EXPECT_TRUE(metricsManager->isActive());
910     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
911     EXPECT_TRUE(metricProducer->mIsActive);
912     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
913     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
914     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
915 
916     // Check that StateTrackers were initialized correctly.
917     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
918     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
919 
920     /*
921                bucket #1                      bucket #2
922     |       1       2       3       4       5     6     7     8  (minutes)
923     |---------------------------------------|------------------
924              ON                          OFF    ON             (BatterySaverMode)
925                   T            F    T                          (DeviceUnpluggedPredicate)
926          |              |              |                       (ScreenIsOnEvent)
927                 |           |                       |          (ScreenIsOffEvent)
928                                 |                              (ScreenDozeEvent)
929     */
930     // Initialize log events.
931     std::vector<std::unique_ptr<LogEvent>> events;
932     events.push_back(CreateScreenStateChangedEvent(
933             bucketStartTimeNs + 20 * NS_PER_SEC,
934             android::view::DisplayStateEnum::DISPLAY_STATE_ON));                       // 0:30
935     events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 60 * NS_PER_SEC));  // 1:10
936     events.push_back(CreateScreenStateChangedEvent(
937             bucketStartTimeNs + 80 * NS_PER_SEC,
938             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:30
939     events.push_back(
940             CreateBatteryStateChangedEvent(bucketStartTimeNs + 110 * NS_PER_SEC,
941                                            BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));  // 2:00
942     events.push_back(CreateScreenStateChangedEvent(
943             bucketStartTimeNs + 145 * NS_PER_SEC,
944             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:35
945     events.push_back(CreateScreenStateChangedEvent(
946             bucketStartTimeNs + 170 * NS_PER_SEC,
947             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 3:00
948     events.push_back(
949             CreateBatteryStateChangedEvent(bucketStartTimeNs + 180 * NS_PER_SEC,
950                                            BatteryPluggedStateEnum::BATTERY_PLUGGED_USB));  // 3:10
951     events.push_back(CreateScreenStateChangedEvent(
952             bucketStartTimeNs + 200 * NS_PER_SEC,
953             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 3:30
954     events.push_back(
955             CreateBatteryStateChangedEvent(bucketStartTimeNs + 230 * NS_PER_SEC,
956                                            BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));  // 4:00
957     events.push_back(CreateScreenStateChangedEvent(
958             bucketStartTimeNs + 260 * NS_PER_SEC,
959             android::view::DisplayStateEnum::DISPLAY_STATE_ON));                         // 4:30
960     events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 280 * NS_PER_SEC));  // 4:50
961 
962     // Bucket boundary.
963     events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 320 * NS_PER_SEC));  // 5:30
964     events.push_back(CreateScreenStateChangedEvent(
965             bucketStartTimeNs + 380 * NS_PER_SEC,
966             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 6:30
967 
968     // Send log events to StatsLogProcessor.
969     for (auto& event : events) {
970         processor->OnLogEvent(event.get());
971     }
972 
973     // Check dump report.
974     vector<uint8_t> buffer;
975     ConfigMetricsReportList reports;
976     processor->onDumpReport(cfgKey, bucketStartTimeNs + 410 * NS_PER_SEC,
977                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
978                             &buffer);
979     ASSERT_GT(buffer.size(), 0);
980     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
981     backfillDimensionPath(&reports);
982     backfillStringInReport(&reports);
983     backfillStartEndTimestamp(&reports);
984 
985     ASSERT_EQ(1, reports.reports_size());
986     ASSERT_EQ(1, reports.reports(0).metrics_size());
987     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
988     StatsLogReport::DurationMetricDataWrapper durationMetrics;
989     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
990                                     &durationMetrics);
991     ASSERT_EQ(3, durationMetrics.data_size());
992 
993     DurationMetricData data = durationMetrics.data(0);
994     ASSERT_EQ(1, data.slice_by_state_size());
995     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
996     EXPECT_TRUE(data.slice_by_state(0).has_value());
997     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_OFF, data.slice_by_state(0).value());
998     ASSERT_EQ(2, data.bucket_info_size());
999     EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1000     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1001     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1002     EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
1003     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
1004     EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
1005 
1006     data = durationMetrics.data(1);
1007     ASSERT_EQ(1, data.slice_by_state_size());
1008     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1009     EXPECT_TRUE(data.slice_by_state(0).has_value());
1010     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_ON, data.slice_by_state(0).value());
1011     ASSERT_EQ(2, data.bucket_info_size());
1012     EXPECT_EQ(45 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1013     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1014     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1015     EXPECT_EQ(60 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
1016     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
1017     EXPECT_EQ(420 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
1018 
1019     data = durationMetrics.data(2);
1020     ASSERT_EQ(1, data.slice_by_state_size());
1021     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1022     EXPECT_TRUE(data.slice_by_state(0).has_value());
1023     EXPECT_EQ(android::view::DisplayStateEnum::DISPLAY_STATE_DOZE, data.slice_by_state(0).value());
1024     ASSERT_EQ(1, data.bucket_info_size());
1025     EXPECT_EQ(30 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1026     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1027     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1028 }
1029 
TEST(DurationMetricE2eTest,TestWithSlicedStateMapped)1030 TEST(DurationMetricE2eTest, TestWithSlicedStateMapped) {
1031     // Initialize config.
1032     StatsdConfig config;
1033     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
1034 
1035     *config.add_atom_matcher() = CreateBatterySaverModeStartAtomMatcher();
1036     *config.add_atom_matcher() = CreateBatterySaverModeStopAtomMatcher();
1037 
1038     auto batterySaverModePredicate = CreateBatterySaverModePredicate();
1039     *config.add_predicate() = batterySaverModePredicate;
1040 
1041     int64_t screenOnId = 4444;
1042     int64_t screenOffId = 9876;
1043     auto screenStateWithMap = CreateScreenStateWithOnOffMap(screenOnId, screenOffId);
1044     *config.add_state() = screenStateWithMap;
1045 
1046     // Create duration metric that slices by mapped screen state.
1047     auto durationMetric = config.add_duration_metric();
1048     durationMetric->set_id(StringToId("DurationBatterySaverModeSliceScreenMapped"));
1049     durationMetric->set_what(batterySaverModePredicate.id());
1050     durationMetric->add_slice_by_state(screenStateWithMap.id());
1051     durationMetric->set_aggregation_type(DurationMetric::SUM);
1052     durationMetric->set_bucket(FIVE_MINUTES);
1053 
1054     // Initialize StatsLogProcessor.
1055     int uid = 12345;
1056     int64_t cfgId = 98765;
1057     ConfigKey cfgKey(uid, cfgId);
1058     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
1059     uint64_t bucketSizeNs =
1060             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
1061     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
1062 
1063     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
1064     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
1065     EXPECT_TRUE(metricsManager->isConfigValid());
1066     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
1067     EXPECT_TRUE(metricsManager->isActive());
1068     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
1069     EXPECT_TRUE(metricProducer->mIsActive);
1070     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
1071     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), SCREEN_STATE_ATOM_ID);
1072     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 1);
1073 
1074     // Check that StateTrackers were initialized correctly.
1075     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
1076     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(SCREEN_STATE_ATOM_ID));
1077 
1078     /*
1079                bucket #1                      bucket #2
1080     |     1     2     3     4     5     6     7     8     9     10 (minutes)
1081     |-----------------------------|-----------------------------|--
1082         ON              OFF     ON                                  (BatterySaverMode)
1083      ---------------------------------------------------------SCREEN_OFF events
1084            |                  |                                  (ScreenStateOffEvent = 1)
1085               |                                                  (ScreenStateDozeEvent = 3)
1086                                                 |                (ScreenStateDozeSuspendEvent = 4)
1087      ---------------------------------------------------------SCREEN_ON events
1088       |          |                   |                           (ScreenStateOnEvent = 2)
1089                       |                                          (ScreenStateVrEvent = 5)
1090                                             |                    (ScreenStateOnSuspendEvent = 6)
1091     */
1092     // Initialize log events.
1093     std::vector<std::unique_ptr<LogEvent>> events;
1094     events.push_back(CreateScreenStateChangedEvent(
1095             bucketStartTimeNs + 10 * NS_PER_SEC,
1096             android::view::DisplayStateEnum::DISPLAY_STATE_ON));                       // 0:20
1097     events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 20 * NS_PER_SEC));  // 0:30
1098     events.push_back(CreateScreenStateChangedEvent(
1099             bucketStartTimeNs + 70 * NS_PER_SEC,
1100             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // 1:20
1101     events.push_back(CreateScreenStateChangedEvent(
1102             bucketStartTimeNs + 100 * NS_PER_SEC,
1103             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE));  // 1:50
1104     events.push_back(CreateScreenStateChangedEvent(
1105             bucketStartTimeNs + 120 * NS_PER_SEC,
1106             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 2:10
1107     events.push_back(CreateScreenStateChangedEvent(
1108             bucketStartTimeNs + 170 * NS_PER_SEC,
1109             android::view::DisplayStateEnum::DISPLAY_STATE_VR));                         // 3:00
1110     events.push_back(CreateBatterySaverOffEvent(bucketStartTimeNs + 200 * NS_PER_SEC));  // 3:30
1111     events.push_back(CreateScreenStateChangedEvent(
1112             bucketStartTimeNs + 250 * NS_PER_SEC,
1113             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));                       // 4:20
1114     events.push_back(CreateBatterySaverOnEvent(bucketStartTimeNs + 280 * NS_PER_SEC));  // 4:50
1115 
1116     // Bucket boundary 5:10.
1117     events.push_back(CreateScreenStateChangedEvent(
1118             bucketStartTimeNs + 320 * NS_PER_SEC,
1119             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // 5:30
1120     events.push_back(CreateScreenStateChangedEvent(
1121             bucketStartTimeNs + 390 * NS_PER_SEC,
1122             android::view::DisplayStateEnum::DISPLAY_STATE_ON_SUSPEND));  // 6:40
1123     events.push_back(CreateScreenStateChangedEvent(
1124             bucketStartTimeNs + 430 * NS_PER_SEC,
1125             android::view::DisplayStateEnum::DISPLAY_STATE_DOZE_SUSPEND));  // 7:20
1126     // Send log events to StatsLogProcessor.
1127     for (auto& event : events) {
1128         processor->OnLogEvent(event.get());
1129     }
1130 
1131     // Check dump report.
1132     vector<uint8_t> buffer;
1133     ConfigMetricsReportList reports;
1134     processor->onDumpReport(cfgKey, bucketStartTimeNs + 490 * NS_PER_SEC,
1135                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
1136                             &buffer);
1137     ASSERT_GT(buffer.size(), 0);
1138     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1139     backfillDimensionPath(&reports);
1140     backfillStringInReport(&reports);
1141     backfillStartEndTimestamp(&reports);
1142 
1143     ASSERT_EQ(1, reports.reports_size());
1144     ASSERT_EQ(1, reports.reports(0).metrics_size());
1145     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
1146     StatsLogReport::DurationMetricDataWrapper durationMetrics;
1147     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
1148                                     &durationMetrics);
1149     ASSERT_EQ(2, durationMetrics.data_size());
1150 
1151     DurationMetricData data = durationMetrics.data(0);
1152     ASSERT_EQ(1, data.slice_by_state_size());
1153     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1154     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
1155     EXPECT_EQ(screenOnId, data.slice_by_state(0).group_id());
1156     ASSERT_EQ(2, data.bucket_info_size());
1157     EXPECT_EQ(130 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1158     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1159     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1160     EXPECT_EQ(110 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
1161     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
1162     EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
1163 
1164     data = durationMetrics.data(1);
1165     ASSERT_EQ(1, data.slice_by_state_size());
1166     EXPECT_EQ(SCREEN_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1167     EXPECT_TRUE(data.slice_by_state(0).has_group_id());
1168     EXPECT_EQ(screenOffId, data.slice_by_state(0).group_id());
1169     ASSERT_EQ(2, data.bucket_info_size());
1170     EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1171     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1172     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1173     EXPECT_EQ(80 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
1174     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
1175     EXPECT_EQ(500 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
1176 }
1177 
TEST(DurationMetricE2eTest,TestSlicedStatePrimaryFieldsNotSubsetDimInWhat)1178 TEST(DurationMetricE2eTest, TestSlicedStatePrimaryFieldsNotSubsetDimInWhat) {
1179     // Initialize config.
1180     StatsdConfig config;
1181     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
1182 
1183     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1184     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1185 
1186     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1187     *config.add_predicate() = holdingWakelockPredicate;
1188 
1189     auto uidProcessState = CreateUidProcessState();
1190     *config.add_state() = uidProcessState;
1191 
1192     // Create duration metric that slices by uid process state.
1193     auto durationMetric = config.add_duration_metric();
1194     durationMetric->set_id(StringToId("DurationHoldingWakelockSliceUidProcessState"));
1195     durationMetric->set_what(holdingWakelockPredicate.id());
1196     durationMetric->add_slice_by_state(uidProcessState.id());
1197     durationMetric->set_aggregation_type(DurationMetric::SUM);
1198     durationMetric->set_bucket(FIVE_MINUTES);
1199 
1200     // The state has only one primary field (uid).
1201     auto stateLink = durationMetric->add_state_link();
1202     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
1203     auto fieldsInWhat = stateLink->mutable_fields_in_what();
1204     *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1205     auto fieldsInState = stateLink->mutable_fields_in_state();
1206     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
1207 
1208     // Initialize StatsLogProcessor.
1209     int uid = 12345;
1210     int64_t cfgId = 98765;
1211     ConfigKey cfgKey(uid, cfgId);
1212     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
1213     uint64_t bucketSizeNs =
1214             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
1215     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
1216 
1217     // This config is rejected because the dimension in what fields are not a superset of the sliced
1218     // state primary fields.
1219     ASSERT_EQ(processor->mMetricsManagers.size(), 0);
1220 }
1221 
TEST(DurationMetricE2eTest,TestWithSlicedStatePrimaryFieldsSubset)1222 TEST(DurationMetricE2eTest, TestWithSlicedStatePrimaryFieldsSubset) {
1223     // Initialize config.
1224     StatsdConfig config;
1225     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
1226 
1227     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
1228     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
1229 
1230     auto holdingWakelockPredicate = CreateHoldingWakelockPredicate();
1231     *(holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions()) =
1232             CreateAttributionUidAndOtherDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST},
1233                                                    {3 /* tag */});
1234     *config.add_predicate() = holdingWakelockPredicate;
1235 
1236     auto uidProcessState = CreateUidProcessState();
1237     *config.add_state() = uidProcessState;
1238 
1239     // Create duration metric that slices by uid process state.
1240     auto durationMetric = config.add_duration_metric();
1241     durationMetric->set_id(StringToId("DurationPartialWakelockPerTagUidSliceProcessState"));
1242     durationMetric->set_what(holdingWakelockPredicate.id());
1243     durationMetric->add_slice_by_state(uidProcessState.id());
1244     durationMetric->set_aggregation_type(DurationMetric::SUM);
1245     durationMetric->set_bucket(FIVE_MINUTES);
1246 
1247     // The metric is dimensioning by first uid of attribution node and tag.
1248     *durationMetric->mutable_dimensions_in_what() = CreateAttributionUidAndOtherDimensions(
1249             util::WAKELOCK_STATE_CHANGED, {Position::FIRST}, {3 /* tag */});
1250     // The state has only one primary field (uid).
1251     auto stateLink = durationMetric->add_state_link();
1252     stateLink->set_state_atom_id(UID_PROCESS_STATE_ATOM_ID);
1253     auto fieldsInWhat = stateLink->mutable_fields_in_what();
1254     *fieldsInWhat = CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
1255     auto fieldsInState = stateLink->mutable_fields_in_state();
1256     *fieldsInState = CreateDimensions(UID_PROCESS_STATE_ATOM_ID, {1 /* uid */});
1257 
1258     // Initialize StatsLogProcessor.
1259     int uid = 12345;
1260     int64_t cfgId = 98765;
1261     ConfigKey cfgKey(uid, cfgId);
1262     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
1263     uint64_t bucketSizeNs =
1264             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000000LL;
1265     auto processor = CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, cfgKey);
1266 
1267     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
1268     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
1269     EXPECT_TRUE(metricsManager->isConfigValid());
1270     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
1271     EXPECT_TRUE(metricsManager->isActive());
1272     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
1273     EXPECT_TRUE(metricProducer->mIsActive);
1274     ASSERT_EQ(metricProducer->mSlicedStateAtoms.size(), 1);
1275     EXPECT_EQ(metricProducer->mSlicedStateAtoms.at(0), UID_PROCESS_STATE_ATOM_ID);
1276     ASSERT_EQ(metricProducer->mStateGroupMap.size(), 0);
1277 
1278     // Check that StateTrackers were initialized correctly.
1279     EXPECT_EQ(1, StateManager::getInstance().getStateTrackersCount());
1280     EXPECT_EQ(1, StateManager::getInstance().getListenersCount(UID_PROCESS_STATE_ATOM_ID));
1281 
1282     // Initialize log events.
1283     int appUid1 = 1001;
1284     int appUid2 = 1002;
1285     std::vector<int> attributionUids1 = {appUid1};
1286     std::vector<string> attributionTags1 = {"App1"};
1287 
1288     std::vector<int> attributionUids2 = {appUid2};
1289     std::vector<string> attributionTags2 = {"App2"};
1290 
1291     std::vector<std::unique_ptr<LogEvent>> events;
1292     events.push_back(CreateUidProcessStateChangedEvent(
1293             bucketStartTimeNs + 10 * NS_PER_SEC, appUid1,
1294             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));  // 0:20
1295     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
1296                                                 attributionUids1, attributionTags1,
1297                                                 "wakelock1"));  // 0:30
1298     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * NS_PER_SEC,
1299                                                 attributionUids1, attributionTags1,
1300                                                 "wakelock2"));  // 0:35
1301     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 30 * NS_PER_SEC,
1302                                                 attributionUids2, attributionTags2,
1303                                                 "wakelock1"));  // 0:40
1304     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 35 * NS_PER_SEC,
1305                                                 attributionUids2, attributionTags2,
1306                                                 "wakelock2"));  // 0:45
1307     events.push_back(CreateUidProcessStateChangedEvent(
1308             bucketStartTimeNs + 50 * NS_PER_SEC, appUid2,
1309             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 1:00
1310     events.push_back(CreateUidProcessStateChangedEvent(
1311             bucketStartTimeNs + 60 * NS_PER_SEC, appUid1,
1312             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));  // 1:10
1313     events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 100 * NS_PER_SEC,
1314                                                 attributionUids2, attributionTags2,
1315                                                 "wakelock1"));  // 1:50
1316     events.push_back(CreateUidProcessStateChangedEvent(
1317             bucketStartTimeNs + 120 * NS_PER_SEC, appUid2,
1318             android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE));  // 2:10
1319     events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 200 * NS_PER_SEC,
1320                                                 attributionUids1, attributionTags1,
1321                                                 "wakelock2"));  // 3:30
1322 
1323     // Send log events to StatsLogProcessor.
1324     for (auto& event : events) {
1325         processor->OnLogEvent(event.get());
1326     }
1327 
1328     // Check dump report.
1329     vector<uint8_t> buffer;
1330     ConfigMetricsReportList reports;
1331     processor->onDumpReport(cfgKey, bucketStartTimeNs + 320 * NS_PER_SEC,
1332                             true /* include current partial bucket */, true, ADB_DUMP, FAST,
1333                             &buffer);
1334     ASSERT_GT(buffer.size(), 0);
1335     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1336     backfillDimensionPath(&reports);
1337     backfillStringInReport(&reports);
1338     backfillStartEndTimestamp(&reports);
1339 
1340     ASSERT_EQ(1, reports.reports_size());
1341     ASSERT_EQ(1, reports.reports(0).metrics_size());
1342     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
1343     StatsLogReport::DurationMetricDataWrapper durationMetrics;
1344     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
1345                                     &durationMetrics);
1346     ASSERT_EQ(9, durationMetrics.data_size());
1347 
1348     DurationMetricData data = durationMetrics.data(0);
1349     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
1350                                                   "wakelock1");
1351     ASSERT_EQ(1, data.slice_by_state_size());
1352     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1353     EXPECT_TRUE(data.slice_by_state(0).has_value());
1354     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
1355               data.slice_by_state(0).value());
1356     ASSERT_EQ(1, data.bucket_info_size());
1357     EXPECT_EQ(40 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1358     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1359     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1360 
1361     data = durationMetrics.data(1);
1362     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
1363                                                   "wakelock1");
1364     ASSERT_EQ(1, data.slice_by_state_size());
1365     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1366     EXPECT_TRUE(data.slice_by_state(0).has_value());
1367     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
1368               data.slice_by_state(0).value());
1369     ASSERT_EQ(2, data.bucket_info_size());
1370     EXPECT_EQ(240 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1371     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1372     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1373     EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
1374     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
1375     EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
1376 
1377     data = durationMetrics.data(2);
1378     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
1379                                                   "wakelock2");
1380     ASSERT_EQ(1, data.slice_by_state_size());
1381     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1382     EXPECT_TRUE(data.slice_by_state(0).has_value());
1383     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND,
1384               data.slice_by_state(0).value());
1385     ASSERT_EQ(1, data.bucket_info_size());
1386     EXPECT_EQ(35 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1387     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1388     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1389 
1390     data = durationMetrics.data(3);
1391     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid1,
1392                                                   "wakelock2");
1393     ASSERT_EQ(1, data.slice_by_state_size());
1394     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1395     EXPECT_TRUE(data.slice_by_state(0).has_value());
1396     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
1397               data.slice_by_state(0).value());
1398     ASSERT_EQ(1, data.bucket_info_size());
1399     EXPECT_EQ(140 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1400     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1401     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1402 
1403     data = durationMetrics.data(4);
1404     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
1405                                                   "wakelock1");
1406     ASSERT_EQ(1, data.slice_by_state_size());
1407     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1408     EXPECT_TRUE(data.slice_by_state(0).has_value());
1409     EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
1410     ASSERT_EQ(1, data.bucket_info_size());
1411     EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1412     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1413     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1414 
1415     data = durationMetrics.data(5);
1416     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
1417                                                   "wakelock1");
1418     ASSERT_EQ(1, data.slice_by_state_size());
1419     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1420     EXPECT_TRUE(data.slice_by_state(0).has_value());
1421     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
1422               data.slice_by_state(0).value());
1423     ASSERT_EQ(1, data.bucket_info_size());
1424     EXPECT_EQ(50 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1425     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1426     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1427 
1428     data = durationMetrics.data(6);
1429     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
1430                                                   "wakelock2");
1431     ASSERT_EQ(1, data.slice_by_state_size());
1432     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1433     EXPECT_TRUE(data.slice_by_state(0).has_value());
1434     EXPECT_EQ(-1 /* StateTracker:: kStateUnknown */, data.slice_by_state(0).value());
1435     ASSERT_EQ(1, data.bucket_info_size());
1436     EXPECT_EQ(15 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1437     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1438     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1439 
1440     data = durationMetrics.data(7);
1441     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
1442                                                   "wakelock2");
1443     ASSERT_EQ(1, data.slice_by_state_size());
1444     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1445     EXPECT_TRUE(data.slice_by_state(0).has_value());
1446     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_FOREGROUND_SERVICE,
1447               data.slice_by_state(0).value());
1448     ASSERT_EQ(2, data.bucket_info_size());
1449     EXPECT_EQ(180 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1450     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1451     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1452     EXPECT_EQ(20 * NS_PER_SEC, data.bucket_info(1).duration_nanos());
1453     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(1).start_bucket_elapsed_nanos());
1454     EXPECT_EQ(330 * NS_PER_SEC, data.bucket_info(1).end_bucket_elapsed_nanos());
1455 
1456     data = durationMetrics.data(8);
1457     ValidateWakelockAttributionUidAndTagDimension(data.dimensions_in_what(), 10, appUid2,
1458                                                   "wakelock2");
1459     ASSERT_EQ(1, data.slice_by_state_size());
1460     EXPECT_EQ(UID_PROCESS_STATE_ATOM_ID, data.slice_by_state(0).atom_id());
1461     EXPECT_TRUE(data.slice_by_state(0).has_value());
1462     EXPECT_EQ(android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND,
1463               data.slice_by_state(0).value());
1464     ASSERT_EQ(1, data.bucket_info_size());
1465     EXPECT_EQ(70 * NS_PER_SEC, data.bucket_info(0).duration_nanos());
1466     EXPECT_EQ(10 * NS_PER_SEC, data.bucket_info(0).start_bucket_elapsed_nanos());
1467     EXPECT_EQ(310 * NS_PER_SEC, data.bucket_info(0).end_bucket_elapsed_nanos());
1468 }
1469 
TEST(DurationMetricE2eTest,TestUploadThreshold)1470 TEST(DurationMetricE2eTest, TestUploadThreshold) {
1471     StatsdConfig config;
1472     config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
1473 
1474     auto screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
1475     auto screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
1476     *config.add_atom_matcher() = screenOnMatcher;
1477     *config.add_atom_matcher() = screenOffMatcher;
1478 
1479     auto durationPredicate = CreateScreenIsOnPredicate();
1480     *config.add_predicate() = durationPredicate;
1481 
1482     int64_t thresholdDurationNs = 30 * 1000 * 1000 * 1000LL;  // 30 seconds
1483     UploadThreshold threshold;
1484     threshold.set_gt_int(thresholdDurationNs);
1485 
1486     int64_t metricId = 123456;
1487     auto durationMetric = config.add_duration_metric();
1488     durationMetric->set_id(metricId);
1489     durationMetric->set_what(durationPredicate.id());
1490     durationMetric->set_bucket(FIVE_MINUTES);
1491     durationMetric->set_aggregation_type(DurationMetric_AggregationType_SUM);
1492     *durationMetric->mutable_threshold() = threshold;
1493 
1494     const int64_t baseTimeNs = 0;                                   // 0:00
1495     const int64_t configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC;  // 0:01
1496     const int64_t bucketSizeNs =
1497             TimeUnitToBucketSizeInMillis(config.duration_metric(0).bucket()) * 1000LL * 1000LL;
1498 
1499     int uid = 12345;
1500     int64_t cfgId = 98765;
1501     ConfigKey cfgKey(uid, cfgId);
1502 
1503     auto processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, cfgKey);
1504 
1505     ASSERT_EQ(processor->mMetricsManagers.size(), 1u);
1506     sp<MetricsManager> metricsManager = processor->mMetricsManagers.begin()->second;
1507     EXPECT_TRUE(metricsManager->isConfigValid());
1508     ASSERT_EQ(metricsManager->mAllMetricProducers.size(), 1);
1509     sp<MetricProducer> metricProducer = metricsManager->mAllMetricProducers[0];
1510     EXPECT_TRUE(metricsManager->isActive());
1511     EXPECT_TRUE(metricProducer->mIsActive);
1512 
1513     std::unique_ptr<LogEvent> event;
1514 
1515     // Screen is off at start of first bucket.
1516     event = CreateScreenStateChangedEvent(configAddedTimeNs,
1517                                           android::view::DISPLAY_STATE_OFF);  // 0:01
1518     processor->OnLogEvent(event.get());
1519 
1520     // Turn screen on.
1521     const int64_t durationStartNs = configAddedTimeNs + 10 * NS_PER_SEC;  // 0:11
1522     event = CreateScreenStateChangedEvent(durationStartNs, android::view::DISPLAY_STATE_ON);
1523     processor->OnLogEvent(event.get());
1524 
1525     // Turn off screen 30 seconds after turning on.
1526     const int64_t durationEndNs = durationStartNs + 30 * NS_PER_SEC;  // 0:41
1527     event = CreateScreenStateChangedEvent(durationEndNs, android::view::DISPLAY_STATE_OFF);
1528     processor->OnLogEvent(event.get());
1529 
1530     // Turn screen on in second bucket.
1531     const int64_t duration2StartNs = configAddedTimeNs + bucketSizeNs + 10 * NS_PER_SEC;  // 5:11
1532     event = CreateScreenStateChangedEvent(duration2StartNs, android::view::DISPLAY_STATE_ON);
1533     processor->OnLogEvent(event.get());
1534 
1535     // Turn off screen 31 seconds after turning on.
1536     const int64_t duration2EndNs = duration2StartNs + 31 * NS_PER_SEC;  // 5:42
1537     event = CreateScreenStateChangedEvent(duration2EndNs, android::view::DISPLAY_STATE_OFF);
1538     processor->OnLogEvent(event.get());
1539 
1540     ConfigMetricsReportList reports;
1541     vector<uint8_t> buffer;
1542     processor->onDumpReport(cfgKey, configAddedTimeNs + bucketSizeNs * 2 + 1 * NS_PER_SEC, false,
1543                             true, ADB_DUMP, FAST, &buffer);  // 10:01
1544     EXPECT_TRUE(buffer.size() > 0);
1545     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1546     backfillDimensionPath(&reports);
1547     backfillStartEndTimestamp(&reports);
1548     ASSERT_EQ(1, reports.reports_size());
1549     ASSERT_EQ(1, reports.reports(0).metrics_size());
1550     EXPECT_EQ(metricId, reports.reports(0).metrics(0).metric_id());
1551     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
1552 
1553     StatsLogReport::DurationMetricDataWrapper durationMetrics;
1554     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(),
1555                                     &durationMetrics);
1556     ASSERT_EQ(1, durationMetrics.data_size());
1557 
1558     DurationMetricData data = durationMetrics.data(0);
1559     ASSERT_EQ(1, data.bucket_info_size());
1560     EXPECT_EQ(duration2EndNs - duration2StartNs, data.bucket_info(0).duration_nanos());
1561     EXPECT_EQ(baseTimeNs + bucketSizeNs, data.bucket_info(0).start_bucket_elapsed_nanos());
1562     EXPECT_EQ(baseTimeNs + bucketSizeNs * 2, data.bucket_info(0).end_bucket_elapsed_nanos());
1563 }
1564 
1565 #else
1566 GTEST_LOG_(INFO) << "This test does nothing.\n";
1567 #endif
1568 
1569 }  // namespace statsd
1570 }  // namespace os
1571 }  // namespace android
1572