• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2020 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 <aidl/android/os/StatsDimensionsValueParcel.h>
16 #include <android-base/properties.h>
17 #include <android-base/stringprintf.h>
18 #include <android/binder_interface_utils.h>
19 #include <gtest/gtest.h>
20 
21 #include <thread>
22 
23 #include "src/StatsLogProcessor.h"
24 #include "src/StatsService.h"
25 #include "src/storage/StorageManager.h"
26 #include "src/subscriber/SubscriberReporter.h"
27 #include "tests/statsd_test_util.h"
28 
29 namespace android {
30 namespace os {
31 namespace statsd {
32 
33 #ifdef __ANDROID__
34 
35 using aidl::android::os::StatsDimensionsValueParcel;
36 using android::base::SetProperty;
37 using android::base::StringPrintf;
38 using ::ndk::SharedRefBase;
39 using namespace std;
40 
41 // Tests that only run with the partial config update feature turned on.
42 namespace {
ValidateSubsystemSleepDimension(const DimensionsValue & value,string name)43 void ValidateSubsystemSleepDimension(const DimensionsValue& value, string name) {
44     EXPECT_EQ(value.field(), util::SUBSYSTEM_SLEEP_STATE);
45     ASSERT_EQ(value.value_tuple().dimensions_value_size(), 1);
46     EXPECT_EQ(value.value_tuple().dimensions_value(0).field(), 1 /* subsystem name field */);
47     EXPECT_EQ(value.value_tuple().dimensions_value(0).value_str(), name);
48 }
49 
50 }  // Anonymous namespace.
51 
52 // Setup for test fixture.
53 class ConfigUpdateE2eTest : public ::testing::Test {};
54 
TEST_F(ConfigUpdateE2eTest,TestEventMetric)55 TEST_F(ConfigUpdateE2eTest, TestEventMetric) {
56     StatsdConfig config;
57     config.add_allowed_log_source("AID_ROOT");
58 
59     AtomMatcher syncStartMatcher = CreateSyncStartAtomMatcher();
60     *config.add_atom_matcher() = syncStartMatcher;
61     AtomMatcher wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
62     *config.add_atom_matcher() = wakelockAcquireMatcher;
63     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
64     *config.add_atom_matcher() = screenOnMatcher;
65     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
66     *config.add_atom_matcher() = screenOffMatcher;
67     AtomMatcher batteryPluggedUsbMatcher = CreateBatteryStateUsbMatcher();
68     *config.add_atom_matcher() = batteryPluggedUsbMatcher;
69     AtomMatcher unpluggedMatcher = CreateBatteryStateNoneMatcher();
70     *config.add_atom_matcher() = unpluggedMatcher;
71 
72     AtomMatcher* combinationMatcher = config.add_atom_matcher();
73     combinationMatcher->set_id(StringToId("SyncOrWakelockMatcher"));
74     combinationMatcher->mutable_combination()->set_operation(LogicalOperation::OR);
75     addMatcherToMatcherCombination(syncStartMatcher, combinationMatcher);
76     addMatcherToMatcherCombination(wakelockAcquireMatcher, combinationMatcher);
77 
78     Predicate screenOnPredicate = CreateScreenIsOnPredicate();
79     *config.add_predicate() = screenOnPredicate;
80     Predicate unpluggedPredicate = CreateDeviceUnpluggedPredicate();
81     *config.add_predicate() = unpluggedPredicate;
82 
83     Predicate* combinationPredicate = config.add_predicate();
84     combinationPredicate->set_id(StringToId("ScreenOnOrUnpluggedPred)"));
85     combinationPredicate->mutable_combination()->set_operation(LogicalOperation::OR);
86     addPredicateToPredicateCombination(screenOnPredicate, combinationPredicate);
87     addPredicateToPredicateCombination(unpluggedPredicate, combinationPredicate);
88 
89     EventMetric eventPersist =
90             createEventMetric("SyncOrWlWhileScreenOnOrUnplugged", combinationMatcher->id(),
91                               combinationPredicate->id());
92     EventMetric eventChange = createEventMetric(
93             "WakelockWhileScreenOn", wakelockAcquireMatcher.id(), screenOnPredicate.id());
94     EventMetric eventRemove = createEventMetric("Syncs", syncStartMatcher.id(), nullopt);
95 
96     *config.add_event_metric() = eventRemove;
97     *config.add_event_metric() = eventPersist;
98     *config.add_event_metric() = eventChange;
99 
100     ConfigKey key(123, 987);
101     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
102     sp<StatsLogProcessor> processor =
103             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
104 
105     int app1Uid = 123;
106     vector<int> attributionUids1 = {app1Uid};
107     vector<string> attributionTags1 = {"App1"};
108 
109     // Initialize log events before update.
110     std::vector<std::unique_ptr<LogEvent>> events;
111     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 5 * NS_PER_SEC,
112                                                 attributionUids1, attributionTags1,
113                                                 "wl1"));  // Not kept.
114     events.push_back(CreateScreenStateChangedEvent(
115             bucketStartTimeNs + 10 * NS_PER_SEC,
116             android::view::DISPLAY_STATE_ON));  // Condition true for change.
117     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 15 * NS_PER_SEC, attributionUids1,
118                                           attributionTags1,
119                                           "sync1"));  // Kept for persist & remove.
120     events.push_back(CreateBatteryStateChangedEvent(
121             bucketStartTimeNs + 20 * NS_PER_SEC,
122             BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));  // Condition true for preserve.
123     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * NS_PER_SEC,
124                                                 attributionUids1, attributionTags1,
125                                                 "wl2"));  // Kept by persist and change.
126     events.push_back(CreateScreenStateChangedEvent(
127             bucketStartTimeNs + 30 * NS_PER_SEC,
128             android::view::DISPLAY_STATE_OFF));  // Condition false for change.
129     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 35 * NS_PER_SEC, attributionUids1,
130                                           attributionTags1,
131                                           "sync2"));  // Kept for persist & remove.
132     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 40 * NS_PER_SEC,
133                                                 attributionUids1, attributionTags1,
134                                                 "wl3"));  // Kept by persist.
135 
136     // Send log events to StatsLogProcessor.
137     for (auto& event : events) {
138         processor->OnLogEvent(event.get());
139     }
140 
141     // Do update. Add matchers/conditions in different order to force indices to change.
142     StatsdConfig newConfig;
143     newConfig.add_allowed_log_source("AID_ROOT");
144 
145     *newConfig.add_atom_matcher() = screenOnMatcher;
146     *newConfig.add_atom_matcher() = batteryPluggedUsbMatcher;
147     *newConfig.add_atom_matcher() = syncStartMatcher;
148     *newConfig.add_atom_matcher() = *combinationMatcher;
149     *newConfig.add_atom_matcher() = wakelockAcquireMatcher;
150     *newConfig.add_atom_matcher() = screenOffMatcher;
151     *newConfig.add_atom_matcher() = unpluggedMatcher;
152     *newConfig.add_predicate() = *combinationPredicate;
153     *newConfig.add_predicate() = unpluggedPredicate;
154     *newConfig.add_predicate() = screenOnPredicate;
155 
156     // Add metrics. Note that the condition of eventChange will go from false to true.
157     eventChange.set_condition(unpluggedPredicate.id());
158     *newConfig.add_event_metric() = eventChange;
159     EventMetric eventNew = createEventMetric("ScreenOn", screenOnMatcher.id(), nullopt);
160     *newConfig.add_event_metric() = eventNew;
161     *newConfig.add_event_metric() = eventPersist;
162 
163     int64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;
164     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
165 
166     // Send events after the update.
167     events.clear();
168     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 65 * NS_PER_SEC,
169                                                 attributionUids1, attributionTags1,
170                                                 "wl4"));  // Kept by preserve & change.
171     events.push_back(CreateBatteryStateChangedEvent(
172             bucketStartTimeNs + 70 * NS_PER_SEC,
173             BatteryPluggedStateEnum::BATTERY_PLUGGED_USB));  // All conditions are false.
174     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 75 * NS_PER_SEC,
175                                                 attributionUids1, attributionTags1,
176                                                 "wl5"));  // Not kept.
177     events.push_back(CreateScreenStateChangedEvent(
178             bucketStartTimeNs + 80 * NS_PER_SEC,
179             android::view::DISPLAY_STATE_ON));  // Condition true for preserve, event kept by new.
180     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 85 * NS_PER_SEC,
181                                                 attributionUids1, attributionTags1,
182                                                 "wl6"));  // Kept by preserve.
183     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 90 * NS_PER_SEC, attributionUids1,
184                                           attributionTags1, "sync3"));  // Kept by preserve.
185 
186     // Send log events to StatsLogProcessor.
187     for (auto& event : events) {
188         processor->OnLogEvent(event.get());
189     }
190     uint64_t dumpTimeNs = bucketStartTimeNs + 100 * NS_PER_SEC;
191     ConfigMetricsReportList reports;
192     vector<uint8_t> buffer;
193     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
194     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
195     backfillDimensionPath(&reports);
196     backfillStringInReport(&reports);
197     backfillStartEndTimestamp(&reports);
198     backfillAggregatedAtoms(&reports);
199     ASSERT_EQ(reports.reports_size(), 2);
200 
201     // Report from before update.
202     ConfigMetricsReport report = reports.reports(0);
203     ASSERT_EQ(report.metrics_size(), 3);
204     // Event remove. Captured sync events. There were 2 syncs before the update.
205     StatsLogReport eventRemoveBefore = report.metrics(0);
206     EXPECT_EQ(eventRemoveBefore.metric_id(), eventRemove.id());
207     EXPECT_TRUE(eventRemoveBefore.has_event_metrics());
208     ASSERT_EQ(eventRemoveBefore.event_metrics().data_size(), 2);
209     auto data = eventRemoveBefore.event_metrics().data(0);
210     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 15 * NS_PER_SEC);
211     EXPECT_EQ(data.atom().sync_state_changed().sync_name(), "sync1");
212     data = eventRemoveBefore.event_metrics().data(1);
213     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 35 * NS_PER_SEC);
214     EXPECT_EQ(data.atom().sync_state_changed().sync_name(), "sync2");
215 
216     // Captured wakelocks & syncs while screen on or unplugged. There were 2 wakelocks and 2 syncs.
217     StatsLogReport eventPersistBefore = report.metrics(1);
218     EXPECT_EQ(eventPersistBefore.metric_id(), eventPersist.id());
219     EXPECT_TRUE(eventPersistBefore.has_event_metrics());
220     ASSERT_EQ(eventPersistBefore.event_metrics().data_size(), 3);
221     data = eventPersistBefore.event_metrics().data(0);
222     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 25 * NS_PER_SEC);
223     EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl2");
224     data = eventPersistBefore.event_metrics().data(1);
225     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 35 * NS_PER_SEC);
226     EXPECT_EQ(data.atom().sync_state_changed().sync_name(), "sync2");
227     data = eventPersistBefore.event_metrics().data(2);
228     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 40 * NS_PER_SEC);
229     EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl3");
230 
231     // Captured wakelock events while screen on. There was 1 before the update.
232     StatsLogReport eventChangeBefore = report.metrics(2);
233     EXPECT_EQ(eventChangeBefore.metric_id(), eventChange.id());
234     EXPECT_TRUE(eventChangeBefore.has_event_metrics());
235     ASSERT_EQ(eventChangeBefore.event_metrics().data_size(), 1);
236     data = eventChangeBefore.event_metrics().data(0);
237     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 25 * NS_PER_SEC);
238     EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl2");
239 
240     // Report from after update.
241     report = reports.reports(1);
242     ASSERT_EQ(report.metrics_size(), 3);
243     // Captured wakelocks while unplugged. There was 1 after the update.
244     StatsLogReport eventChangeAfter = report.metrics(0);
245     EXPECT_EQ(eventChangeAfter.metric_id(), eventChange.id());
246     EXPECT_TRUE(eventChangeAfter.has_event_metrics());
247     ASSERT_EQ(eventChangeAfter.event_metrics().data_size(), 1);
248     data = eventChangeAfter.event_metrics().data(0);
249     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 65 * NS_PER_SEC);
250     EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl4");
251 
252     // Captured screen on events. There was 1 after the update.
253     StatsLogReport eventNewAfter = report.metrics(1);
254     EXPECT_EQ(eventNewAfter.metric_id(), eventNew.id());
255     EXPECT_TRUE(eventNewAfter.has_event_metrics());
256     ASSERT_EQ(eventNewAfter.event_metrics().data_size(), 1);
257     data = eventNewAfter.event_metrics().data(0);
258     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 80 * NS_PER_SEC);
259     EXPECT_EQ(data.atom().screen_state_changed().state(), android::view::DISPLAY_STATE_ON);
260 
261     // There were 2 wakelocks and 1 sync after the update while the condition was true.
262     StatsLogReport eventPersistAfter = report.metrics(2);
263     EXPECT_EQ(eventPersistAfter.metric_id(), eventPersist.id());
264     EXPECT_TRUE(eventPersistAfter.has_event_metrics());
265     ASSERT_EQ(eventPersistAfter.event_metrics().data_size(), 3);
266     data = eventPersistAfter.event_metrics().data(0);
267     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 65 * NS_PER_SEC);
268     EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl4");
269     data = eventPersistAfter.event_metrics().data(1);
270     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 85 * NS_PER_SEC);
271     EXPECT_EQ(data.atom().wakelock_state_changed().tag(), "wl6");
272     data = eventPersistAfter.event_metrics().data(2);
273     EXPECT_EQ(data.elapsed_timestamp_nanos(), bucketStartTimeNs + 90 * NS_PER_SEC);
274     EXPECT_EQ(data.atom().sync_state_changed().sync_name(), "sync3");
275 }
276 
TEST_F(ConfigUpdateE2eTest,TestCountMetric)277 TEST_F(ConfigUpdateE2eTest, TestCountMetric) {
278     StatsdConfig config;
279     config.add_allowed_log_source("AID_ROOT");
280 
281     AtomMatcher syncStartMatcher = CreateSyncStartAtomMatcher();
282     *config.add_atom_matcher() = syncStartMatcher;
283     AtomMatcher wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
284     *config.add_atom_matcher() = wakelockAcquireMatcher;
285     AtomMatcher wakelockReleaseMatcher = CreateReleaseWakelockAtomMatcher();
286     *config.add_atom_matcher() = wakelockReleaseMatcher;
287     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
288     *config.add_atom_matcher() = screenOnMatcher;
289     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
290     *config.add_atom_matcher() = screenOffMatcher;
291 
292     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
293     // The predicate is dimensioning by first attribution node by uid.
294     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
295             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
296     *config.add_predicate() = holdingWakelockPredicate;
297 
298     Predicate screenOnPredicate = CreateScreenIsOnPredicate();
299     *config.add_predicate() = screenOnPredicate;
300 
301     Predicate* combination = config.add_predicate();
302     combination->set_id(StringToId("ScreenOnAndHoldingWL)"));
303     combination->mutable_combination()->set_operation(LogicalOperation::AND);
304     addPredicateToPredicateCombination(screenOnPredicate, combination);
305     addPredicateToPredicateCombination(holdingWakelockPredicate, combination);
306 
307     State uidProcessState = CreateUidProcessState();
308     *config.add_state() = uidProcessState;
309 
310     CountMetric countPersist =
311             createCountMetric("CountSyncPerUidWhileScreenOnHoldingWLSliceProcessState",
312                               syncStartMatcher.id(), combination->id(), {uidProcessState.id()});
313     *countPersist.mutable_dimensions_in_what() =
314             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
315     // Links between sync state atom and condition of uid is holding wakelock.
316     MetricConditionLink* links = countPersist.add_links();
317     links->set_condition(holdingWakelockPredicate.id());
318     *links->mutable_fields_in_what() =
319             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
320     *links->mutable_fields_in_condition() =
321             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
322     MetricStateLink* stateLink = countPersist.add_state_link();
323     stateLink->set_state_atom_id(util::UID_PROCESS_STATE_CHANGED);
324     *stateLink->mutable_fields_in_what() =
325             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
326     *stateLink->mutable_fields_in_state() =
327             CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /*uid*/});
328 
329     CountMetric countChange = createCountMetric("Count*WhileScreenOn", syncStartMatcher.id(),
330                                                 screenOnPredicate.id(), {});
331     CountMetric countRemove = createCountMetric("CountSync", syncStartMatcher.id(), nullopt, {});
332     *config.add_count_metric() = countRemove;
333     *config.add_count_metric() = countPersist;
334     *config.add_count_metric() = countChange;
335 
336     ConfigKey key(123, 987);
337     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
338     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
339     sp<StatsLogProcessor> processor =
340             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
341 
342     int app1Uid = 123, app2Uid = 456;
343     vector<int> attributionUids1 = {app1Uid};
344     vector<string> attributionTags1 = {"App1"};
345     vector<int> attributionUids2 = {app2Uid};
346     vector<string> attributionTags2 = {"App2"};
347 
348     // Initialize log events before update. Counts are for countPersist since others are simpler.
349     std::vector<std::unique_ptr<LogEvent>> events;
350     events.push_back(CreateUidProcessStateChangedEvent(
351             bucketStartTimeNs + 2 * NS_PER_SEC, app1Uid,
352             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));
353     events.push_back(CreateUidProcessStateChangedEvent(
354             bucketStartTimeNs + 3 * NS_PER_SEC, app2Uid,
355             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
356     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 5 * NS_PER_SEC, attributionUids1,
357                                           attributionTags1, "sync_name"));  // Not counted.
358     events.push_back(
359             CreateScreenStateChangedEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
360                                           android::view::DisplayStateEnum::DISPLAY_STATE_ON));
361     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 15 * NS_PER_SEC,
362                                                 attributionUids1, attributionTags1, "wl1"));
363     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 20 * NS_PER_SEC, attributionUids1,
364                                           attributionTags1, "sync_name"));  // Counted. uid1 = 1.
365     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 21 * NS_PER_SEC, attributionUids2,
366                                           attributionTags2, "sync_name"));  // Not counted.
367     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 25 * NS_PER_SEC,
368                                                 attributionUids2, attributionTags2, "wl2"));
369     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 30 * NS_PER_SEC, attributionUids1,
370                                           attributionTags1, "sync_name"));  // Counted. uid1 = 2.
371     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 31 * NS_PER_SEC, attributionUids2,
372                                           attributionTags2, "sync_name"));  // Counted. uid2 = 1
373     events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 35 * NS_PER_SEC,
374                                                 attributionUids1, attributionTags1, "wl1"));
375     // Send log events to StatsLogProcessor.
376     for (auto& event : events) {
377         processor->OnLogEvent(event.get());
378     }
379 
380     // Do update. Add matchers/conditions in different order to force indices to change.
381     StatsdConfig newConfig;
382     newConfig.add_allowed_log_source("AID_ROOT");
383 
384     *newConfig.add_atom_matcher() = screenOnMatcher;
385     *newConfig.add_atom_matcher() = screenOffMatcher;
386     *newConfig.add_atom_matcher() = syncStartMatcher;
387     *newConfig.add_atom_matcher() = wakelockAcquireMatcher;
388     *newConfig.add_atom_matcher() = wakelockReleaseMatcher;
389     *newConfig.add_predicate() = *combination;
390     *newConfig.add_predicate() = holdingWakelockPredicate;
391     *newConfig.add_predicate() = screenOnPredicate;
392     *newConfig.add_state() = uidProcessState;
393 
394     countChange.set_what(screenOnMatcher.id());
395     *newConfig.add_count_metric() = countChange;
396     CountMetric countNew = createCountMetric("CountWlWhileScreenOn", wakelockAcquireMatcher.id(),
397                                              screenOnPredicate.id(), {});
398     *newConfig.add_count_metric() = countNew;
399     *newConfig.add_count_metric() = countPersist;
400 
401     int64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;
402     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
403 
404     // Send events after the update. Counts reset to 0 since this is a new bucket.
405     events.clear();
406     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 65 * NS_PER_SEC, attributionUids1,
407                                           attributionTags1, "sync_name"));  // Not counted.
408     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 66 * NS_PER_SEC, attributionUids2,
409                                           attributionTags2, "sync_name"));  // Counted. uid2 = 1.
410     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 70 * NS_PER_SEC,
411                                                 attributionUids1, attributionTags1, "wl1"));
412     events.push_back(
413             CreateScreenStateChangedEvent(bucketStartTimeNs + 75 * NS_PER_SEC,
414                                           android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
415     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 80 * NS_PER_SEC, attributionUids2,
416                                           attributionTags2, "sync_name"));  // Not counted.
417     events.push_back(
418             CreateScreenStateChangedEvent(bucketStartTimeNs + 85 * NS_PER_SEC,
419                                           android::view::DisplayStateEnum::DISPLAY_STATE_ON));
420     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 90 * NS_PER_SEC, attributionUids1,
421                                           attributionTags1, "sync_name"));  // Counted. uid1 = 1.
422     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 11 * NS_PER_SEC, attributionUids2,
423                                           attributionTags2, "sync_name"));  // Counted. uid2 = 2.
424     // Flushes bucket.
425     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + bucketSizeNs + NS_PER_SEC,
426                                                 attributionUids1, attributionTags1, "wl2"));
427     // Send log events to StatsLogProcessor.
428     for (auto& event : events) {
429         processor->OnLogEvent(event.get());
430     }
431     uint64_t dumpTimeNs = bucketStartTimeNs + bucketSizeNs + 10 * NS_PER_SEC;
432     ConfigMetricsReportList reports;
433     vector<uint8_t> buffer;
434     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
435     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
436     backfillDimensionPath(&reports);
437     backfillStringInReport(&reports);
438     backfillStartEndTimestamp(&reports);
439     ASSERT_EQ(reports.reports_size(), 2);
440 
441     // Report from before update.
442     ConfigMetricsReport report = reports.reports(0);
443     ASSERT_EQ(report.metrics_size(), 3);
444     // Count syncs. There were 5 syncs before the update.
445     StatsLogReport countRemoveBefore = report.metrics(0);
446     EXPECT_EQ(countRemoveBefore.metric_id(), countRemove.id());
447     EXPECT_TRUE(countRemoveBefore.has_count_metrics());
448     ASSERT_EQ(countRemoveBefore.count_metrics().data_size(), 1);
449     auto data = countRemoveBefore.count_metrics().data(0);
450     ASSERT_EQ(data.bucket_info_size(), 1);
451     ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 5);
452 
453     // Uid 1 had 2 syncs, uid 2 had 1 sync.
454     StatsLogReport countPersistBefore = report.metrics(1);
455     EXPECT_EQ(countPersistBefore.metric_id(), countPersist.id());
456     EXPECT_TRUE(countPersistBefore.has_count_metrics());
457     StatsLogReport::CountMetricDataWrapper countMetrics;
458     sortMetricDataByDimensionsValue(countPersistBefore.count_metrics(), &countMetrics);
459     ASSERT_EQ(countMetrics.data_size(), 2);
460     data = countMetrics.data(0);
461     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app1Uid);
462     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
463                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);
464     ASSERT_EQ(data.bucket_info_size(), 1);
465     ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 2);
466 
467     data = countMetrics.data(1);
468     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app2Uid);
469     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
470                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
471     ASSERT_EQ(data.bucket_info_size(), 1);
472     ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 1);
473 
474     // Counts syncs while screen on. There were 4 before the update.
475     StatsLogReport countChangeBefore = report.metrics(2);
476     EXPECT_EQ(countChangeBefore.metric_id(), countChange.id());
477     EXPECT_TRUE(countChangeBefore.has_count_metrics());
478     ASSERT_EQ(countChangeBefore.count_metrics().data_size(), 1);
479     data = countChangeBefore.count_metrics().data(0);
480     ASSERT_EQ(data.bucket_info_size(), 1);
481     ValidateCountBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 4);
482 
483     // Report from after update.
484     report = reports.reports(1);
485     ASSERT_EQ(report.metrics_size(), 3);
486     // Count screen on while screen is on. There was 1 after the update.
487     StatsLogReport countChangeAfter = report.metrics(0);
488     EXPECT_EQ(countChangeAfter.metric_id(), countChange.id());
489     EXPECT_TRUE(countChangeAfter.has_count_metrics());
490     ASSERT_EQ(countChangeAfter.count_metrics().data_size(), 1);
491     data = countChangeAfter.count_metrics().data(0);
492     ASSERT_EQ(data.bucket_info_size(), 1);
493     ValidateCountBucket(data.bucket_info(0), updateTimeNs, bucketStartTimeNs + bucketSizeNs, 1);
494 
495     // Count wl acquires while screen on. There were 2, one in each bucket.
496     StatsLogReport countNewAfter = report.metrics(1);
497     EXPECT_EQ(countNewAfter.metric_id(), countNew.id());
498     EXPECT_TRUE(countNewAfter.has_count_metrics());
499     ASSERT_EQ(countNewAfter.count_metrics().data_size(), 1);
500     data = countNewAfter.count_metrics().data(0);
501     ASSERT_EQ(data.bucket_info_size(), 2);
502     ValidateCountBucket(data.bucket_info(0), updateTimeNs, bucketStartTimeNs + bucketSizeNs, 1);
503     ValidateCountBucket(data.bucket_info(1), bucketStartTimeNs + bucketSizeNs, dumpTimeNs, 1);
504 
505     // Uid 1 had 1 sync, uid 2 had 2 syncs.
506     StatsLogReport countPersistAfter = report.metrics(2);
507     EXPECT_EQ(countPersistAfter.metric_id(), countPersist.id());
508     EXPECT_TRUE(countPersistAfter.has_count_metrics());
509     countMetrics.Clear();
510     sortMetricDataByDimensionsValue(countPersistAfter.count_metrics(), &countMetrics);
511     ASSERT_EQ(countMetrics.data_size(), 2);
512     data = countMetrics.data(0);
513     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app1Uid);
514     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
515                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);
516     ASSERT_EQ(data.bucket_info_size(), 1);
517     ValidateCountBucket(data.bucket_info(0), updateTimeNs, bucketStartTimeNs + bucketSizeNs, 1);
518 
519     data = countMetrics.data(1);
520     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app2Uid);
521     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
522                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
523     ASSERT_EQ(data.bucket_info_size(), 1);
524     ValidateCountBucket(data.bucket_info(0), updateTimeNs, bucketStartTimeNs + bucketSizeNs, 2);
525 }
526 
TEST_F(ConfigUpdateE2eTest,TestDurationMetric)527 TEST_F(ConfigUpdateE2eTest, TestDurationMetric) {
528     StatsdConfig config;
529     config.add_allowed_log_source("AID_ROOT");
530 
531     AtomMatcher syncStartMatcher = CreateSyncStartAtomMatcher();
532     *config.add_atom_matcher() = syncStartMatcher;
533     AtomMatcher syncStopMatcher = CreateSyncEndAtomMatcher();
534     *config.add_atom_matcher() = syncStopMatcher;
535     AtomMatcher wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
536     *config.add_atom_matcher() = wakelockAcquireMatcher;
537     AtomMatcher wakelockReleaseMatcher = CreateReleaseWakelockAtomMatcher();
538     *config.add_atom_matcher() = wakelockReleaseMatcher;
539     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
540     *config.add_atom_matcher() = screenOnMatcher;
541     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
542     *config.add_atom_matcher() = screenOffMatcher;
543 
544     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
545     // The predicate is dimensioning by first attribution node by uid.
546     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
547             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
548     *config.add_predicate() = holdingWakelockPredicate;
549 
550     Predicate screenOnPredicate = CreateScreenIsOnPredicate();
551     *config.add_predicate() = screenOnPredicate;
552 
553     Predicate syncPredicate = CreateIsSyncingPredicate();
554     // The predicate is dimensioning by first attribution node by uid.
555     *syncPredicate.mutable_simple_predicate()->mutable_dimensions() =
556             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
557     *config.add_predicate() = syncPredicate;
558 
559     State uidProcessState = CreateUidProcessState();
560     *config.add_state() = uidProcessState;
561 
562     DurationMetric durationSumPersist =
563             createDurationMetric("DurSyncPerUidWhileHoldingWLSliceProcessState", syncPredicate.id(),
564                                  holdingWakelockPredicate.id(), {uidProcessState.id()});
565     *durationSumPersist.mutable_dimensions_in_what() =
566             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
567     // Links between sync state atom and condition of uid is holding wakelock.
568     MetricConditionLink* links = durationSumPersist.add_links();
569     links->set_condition(holdingWakelockPredicate.id());
570     *links->mutable_fields_in_what() =
571             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
572     *links->mutable_fields_in_condition() =
573             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
574     MetricStateLink* stateLink = durationSumPersist.add_state_link();
575     stateLink->set_state_atom_id(util::UID_PROCESS_STATE_CHANGED);
576     *stateLink->mutable_fields_in_what() =
577             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
578     *stateLink->mutable_fields_in_state() =
579             CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /*uid*/});
580 
581     DurationMetric durationMaxPersist =
582             createDurationMetric("DurMaxSyncPerUidWhileHoldingWL", syncPredicate.id(),
583                                  holdingWakelockPredicate.id(), {});
584     durationMaxPersist.set_aggregation_type(DurationMetric::MAX_SPARSE);
585     *durationMaxPersist.mutable_dimensions_in_what() =
586             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
587     // Links between sync state atom and condition of uid is holding wakelock.
588     links = durationMaxPersist.add_links();
589     links->set_condition(holdingWakelockPredicate.id());
590     *links->mutable_fields_in_what() =
591             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
592     *links->mutable_fields_in_condition() =
593             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
594 
595     DurationMetric durationChange = createDurationMetric("Dur*WhileScreenOn", syncPredicate.id(),
596                                                          screenOnPredicate.id(), {});
597     DurationMetric durationRemove =
598             createDurationMetric("DurScreenOn", screenOnPredicate.id(), nullopt, {});
599     *config.add_duration_metric() = durationMaxPersist;
600     *config.add_duration_metric() = durationRemove;
601     *config.add_duration_metric() = durationSumPersist;
602     *config.add_duration_metric() = durationChange;
603 
604     ConfigKey key(123, 987);
605     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
606     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
607     sp<StatsLogProcessor> processor =
608             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
609 
610     int app1Uid = 123, app2Uid = 456, app3Uid = 789;
611     vector<int> attributionUids1 = {app1Uid};
612     vector<string> attributionTags1 = {"App1"};
613     vector<int> attributionUids2 = {app2Uid};
614     vector<string> attributionTags2 = {"App2"};
615     vector<int> attributionUids3 = {app3Uid};
616     vector<string> attributionTags3 = {"App3"};
617 
618     // Initialize log events before update. Comments provided for durations of persisted metrics.
619     std::vector<std::unique_ptr<LogEvent>> events;
620     events.push_back(CreateUidProcessStateChangedEvent(
621             bucketStartTimeNs + 2 * NS_PER_SEC, app1Uid,
622             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));
623     events.push_back(CreateUidProcessStateChangedEvent(
624             bucketStartTimeNs + 3 * NS_PER_SEC, app2Uid,
625             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND));
626     events.push_back(CreateScreenStateChangedEvent(
627             bucketStartTimeNs + 5 * NS_PER_SEC, android::view::DisplayStateEnum::DISPLAY_STATE_ON));
628     events.push_back(CreateUidProcessStateChangedEvent(
629             bucketStartTimeNs + 6 * NS_PER_SEC, app3Uid,
630             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND));
631     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 10 * NS_PER_SEC, attributionUids1,
632                                           attributionTags1, "sync_name"));  // uid1 paused.
633     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 15 * NS_PER_SEC,
634                                                 attributionUids2, attributionTags2,
635                                                 "wl2"));  // uid2 cond true.
636     events.push_back(
637             CreateScreenStateChangedEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
638                                           android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
639     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 25 * NS_PER_SEC, attributionUids2,
640                                           attributionTags2, "sync_name"));  // Uid 2 start t=25.
641     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 27 * NS_PER_SEC,
642                                                 attributionUids1, attributionTags1,
643                                                 "wl1"));  // Uid 1 start t=27.
644     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 35 * NS_PER_SEC, attributionUids3,
645                                           attributionTags3, "sync_name"));  // Uid 3 paused.
646     events.push_back(
647             CreateScreenStateChangedEvent(bucketStartTimeNs + 40 * NS_PER_SEC,
648                                           android::view::DisplayStateEnum::DISPLAY_STATE_ON));
649     events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 45 * NS_PER_SEC, attributionUids2,
650                                         attributionTags2,
651                                         "sync_name"));  // Uid 2 stop. sum/max = 20.
652     // Send log events to StatsLogProcessor.
653     for (auto& event : events) {
654         processor->OnLogEvent(event.get());
655     }
656 
657     // Do update. Add matchers/conditions in different order to force indices to change.
658     StatsdConfig newConfig;
659     newConfig.add_allowed_log_source("AID_ROOT");
660 
661     *newConfig.add_atom_matcher() = wakelockReleaseMatcher;
662     *newConfig.add_atom_matcher() = syncStopMatcher;
663     *newConfig.add_atom_matcher() = screenOnMatcher;
664     *newConfig.add_atom_matcher() = screenOffMatcher;
665     *newConfig.add_atom_matcher() = syncStartMatcher;
666     *newConfig.add_atom_matcher() = wakelockAcquireMatcher;
667     *newConfig.add_predicate() = syncPredicate;
668     *newConfig.add_predicate() = screenOnPredicate;
669     *newConfig.add_predicate() = holdingWakelockPredicate;
670     *newConfig.add_state() = uidProcessState;
671 
672     durationChange.set_what(holdingWakelockPredicate.id());
673     *newConfig.add_duration_metric() = durationChange;
674     DurationMetric durationNew =
675             createDurationMetric("DurationSync", syncPredicate.id(), nullopt, {});
676     *newConfig.add_duration_metric() = durationNew;
677     *newConfig.add_duration_metric() = durationMaxPersist;
678     *newConfig.add_duration_metric() = durationSumPersist;
679 
680     // At update, only uid 1 is syncing & holding a wakelock, duration=33. Max is paused for uid3.
681     // Before the update, only uid2 will report a duration for max, since others are started/paused.
682     int64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;
683     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
684 
685     // Send events after the update.
686     events.clear();
687     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 65 * NS_PER_SEC,
688                                                 attributionUids3, attributionTags3,
689                                                 "wl3"));  // Uid3 start t=65.
690     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 70 * NS_PER_SEC, attributionUids2,
691                                           attributionTags2, "sync_name"));  // Uid2 start t=70.
692     events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 75 * NS_PER_SEC,
693                                                 attributionUids1, attributionTags1,
694                                                 "wl1"));  // Uid1 Pause. Dur = 15.
695     events.push_back(
696             CreateScreenStateChangedEvent(bucketStartTimeNs + 81 * NS_PER_SEC,
697                                           android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
698     events.push_back(CreateUidProcessStateChangedEvent(
699             bucketStartTimeNs + 85 * NS_PER_SEC, app3Uid,
700             android::app::ProcessStateEnum::
701                     PROCESS_STATE_IMPORTANT_FOREGROUND));  // Uid3 Sum in BG: 20. FG starts. Max is
702                                                            // unchanged.
703     events.push_back(CreateSyncEndEvent(bucketStartTimeNs + 90 * NS_PER_SEC, attributionUids3,
704                                         attributionTags3,
705                                         "sync_name"));  // Uid3 stop. Sum in FG: 5. MAX: 25.
706 
707     // Flushes bucket. Sum: uid1=15, uid2=bucketSize - 70, uid3 = 20 in FG, 5 in BG. Max: uid3=25,
708     // others don't report.
709     events.push_back(CreateSyncEndEvent(bucketStartTimeNs + bucketSizeNs + NS_PER_SEC,
710                                         attributionUids1, attributionTags1,
711                                         "sync_name"));  // Uid1 stop. Max=15+33=48, Sum is 0.
712 
713     // Send log events to StatsLogProcessor.
714     for (auto& event : events) {
715         processor->OnLogEvent(event.get());
716     }
717     uint64_t bucketEndTimeNs = bucketStartTimeNs + bucketSizeNs;
718     uint64_t dumpTimeNs = bucketStartTimeNs + bucketSizeNs + 10 * NS_PER_SEC;
719     ConfigMetricsReportList reports;
720     vector<uint8_t> buffer;
721     // In the partial bucket, Sum for uid2 = 10, Max for Uid1 = 48. Rest are unreported.
722     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
723     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
724     backfillDimensionPath(&reports);
725     backfillStringInReport(&reports);
726     backfillStartEndTimestamp(&reports);
727     ASSERT_EQ(reports.reports_size(), 2);
728 
729     // Report from before update.
730     ConfigMetricsReport report = reports.reports(0);
731     ASSERT_EQ(report.metrics_size(), 4);
732     // Max duration of syncs per uid while uid holding WL. Only uid2 should have data.
733     StatsLogReport durationMaxPersistBefore = report.metrics(0);
734     EXPECT_EQ(durationMaxPersistBefore.metric_id(), durationMaxPersist.id());
735     EXPECT_TRUE(durationMaxPersistBefore.has_duration_metrics());
736     StatsLogReport::DurationMetricDataWrapper durationMetrics;
737     sortMetricDataByDimensionsValue(durationMaxPersistBefore.duration_metrics(), &durationMetrics);
738     ASSERT_EQ(durationMetrics.data_size(), 1);
739     auto data = durationMetrics.data(0);
740     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app2Uid);
741     ASSERT_EQ(data.bucket_info_size(), 1);
742     ValidateDurationBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 20 * NS_PER_SEC);
743 
744     // Screen on time. ON: 5, OFF: 20, ON: 40. Update: 60. Result: 35
745     StatsLogReport durationRemoveBefore = report.metrics(1);
746     EXPECT_EQ(durationRemoveBefore.metric_id(), durationRemove.id());
747     EXPECT_TRUE(durationRemoveBefore.has_duration_metrics());
748     durationMetrics.Clear();
749     sortMetricDataByDimensionsValue(durationRemoveBefore.duration_metrics(), &durationMetrics);
750     ASSERT_EQ(durationMetrics.data_size(), 1);
751     data = durationMetrics.data(0);
752     ASSERT_EQ(data.bucket_info_size(), 1);
753     ValidateDurationBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 35 * NS_PER_SEC);
754 
755     // Duration of syncs per uid while uid holding WL, slice screen. Uid1=33, uid2=20.
756     StatsLogReport durationSumPersistBefore = report.metrics(2);
757     EXPECT_EQ(durationSumPersistBefore.metric_id(), durationSumPersist.id());
758     EXPECT_TRUE(durationSumPersistBefore.has_duration_metrics());
759     durationMetrics.Clear();
760     sortMetricDataByDimensionsValue(durationSumPersistBefore.duration_metrics(), &durationMetrics);
761     ASSERT_EQ(durationMetrics.data_size(), 2);
762     data = durationMetrics.data(0);
763     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app1Uid);
764     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
765                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);
766     ASSERT_EQ(data.bucket_info_size(), 1);
767     ValidateDurationBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 33 * NS_PER_SEC);
768 
769     data = durationMetrics.data(1);
770     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app2Uid);
771     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
772                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
773     ASSERT_EQ(data.bucket_info_size(), 1);
774     ValidateDurationBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 20 * NS_PER_SEC);
775 
776     // Duration of syncs while screen on. Start: 10, pause: 20, start: 40 Update: 60. Total: 30.
777     StatsLogReport durationChangeBefore = report.metrics(3);
778     EXPECT_EQ(durationChangeBefore.metric_id(), durationChange.id());
779     EXPECT_TRUE(durationChangeBefore.has_duration_metrics());
780     durationMetrics.Clear();
781     sortMetricDataByDimensionsValue(durationChangeBefore.duration_metrics(), &durationMetrics);
782     ASSERT_EQ(durationMetrics.data_size(), 1);
783     data = durationMetrics.data(0);
784     ASSERT_EQ(data.bucket_info_size(), 1);
785     ValidateDurationBucket(data.bucket_info(0), bucketStartTimeNs, updateTimeNs, 30 * NS_PER_SEC);
786 
787     // Report from after update.
788     report = reports.reports(1);
789     ASSERT_EQ(report.metrics_size(), 4);
790     // Duration of WL while screen on. Update: 60, pause: 81. Total: 21.
791     StatsLogReport durationChangeAfter = report.metrics(0);
792     EXPECT_EQ(durationChangeAfter.metric_id(), durationChange.id());
793     EXPECT_TRUE(durationChangeAfter.has_duration_metrics());
794     durationMetrics.Clear();
795     sortMetricDataByDimensionsValue(durationChangeAfter.duration_metrics(), &durationMetrics);
796     ASSERT_EQ(durationMetrics.data_size(), 1);
797     data = durationMetrics.data(0);
798     ASSERT_EQ(data.bucket_info_size(), 1);
799     ValidateDurationBucket(data.bucket_info(0), updateTimeNs, bucketEndTimeNs, 21 * NS_PER_SEC);
800 
801     // Duration of syncs. Always true since at least 1 uid is always syncing.
802     StatsLogReport durationNewAfter = report.metrics(1);
803     EXPECT_EQ(durationNewAfter.metric_id(), durationNew.id());
804     EXPECT_TRUE(durationNewAfter.has_duration_metrics());
805     durationMetrics.Clear();
806     sortMetricDataByDimensionsValue(durationNewAfter.duration_metrics(), &durationMetrics);
807     ASSERT_EQ(durationMetrics.data_size(), 1);
808     data = durationMetrics.data(0);
809     ASSERT_EQ(data.bucket_info_size(), 2);
810     ValidateDurationBucket(data.bucket_info(0), updateTimeNs, bucketEndTimeNs,
811                            bucketEndTimeNs - updateTimeNs);
812     ValidateDurationBucket(data.bucket_info(1), bucketEndTimeNs, dumpTimeNs,
813                            dumpTimeNs - bucketEndTimeNs);
814 
815     // Max duration of syncs per uid while uid holding WL.
816     StatsLogReport durationMaxPersistAfter = report.metrics(2);
817     EXPECT_EQ(durationMaxPersistAfter.metric_id(), durationMaxPersist.id());
818     EXPECT_TRUE(durationMaxPersistAfter.has_duration_metrics());
819     durationMetrics.Clear();
820     sortMetricDataByDimensionsValue(durationMaxPersistAfter.duration_metrics(), &durationMetrics);
821     ASSERT_EQ(durationMetrics.data_size(), 2);
822 
823     // Uid 1. Duration = 48 in the later bucket.
824     data = durationMetrics.data(0);
825     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app1Uid);
826     ASSERT_EQ(data.bucket_info_size(), 1);
827     ValidateDurationBucket(data.bucket_info(0), bucketEndTimeNs, dumpTimeNs, 48 * NS_PER_SEC);
828 
829     // Uid 3. Duration = 25.
830     data = durationMetrics.data(1);
831     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app3Uid);
832     ASSERT_EQ(data.bucket_info_size(), 1);
833     ValidateDurationBucket(data.bucket_info(0), updateTimeNs, bucketEndTimeNs, 25 * NS_PER_SEC);
834 
835     // Duration of syncs per uid while uid holding WL, slice screen.
836     StatsLogReport durationSumPersistAfter = report.metrics(3);
837     EXPECT_EQ(durationSumPersistAfter.metric_id(), durationSumPersist.id());
838     EXPECT_TRUE(durationSumPersistAfter.has_duration_metrics());
839     durationMetrics.Clear();
840     sortMetricDataByDimensionsValue(durationSumPersistAfter.duration_metrics(), &durationMetrics);
841     ASSERT_EQ(durationMetrics.data_size(), 4);
842 
843     // Uid 1 in BG. Duration = 15.
844     data = durationMetrics.data(0);
845     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app1Uid);
846     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
847                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);
848     ASSERT_EQ(data.bucket_info_size(), 1);
849     ValidateDurationBucket(data.bucket_info(0), updateTimeNs, bucketEndTimeNs, 15 * NS_PER_SEC);
850 
851     // Uid 2 in FG. Duration = bucketSize - 70 in first bucket, 10 in second bucket.
852     data = durationMetrics.data(1);
853     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app2Uid);
854     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
855                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
856     ASSERT_EQ(data.bucket_info_size(), 2);
857     ValidateDurationBucket(data.bucket_info(0), updateTimeNs, bucketEndTimeNs,
858                            bucketSizeNs - 70 * NS_PER_SEC);
859     ValidateDurationBucket(data.bucket_info(1), bucketEndTimeNs, dumpTimeNs, 10 * NS_PER_SEC);
860 
861     // Uid 3 in FG. Duration = 5.
862     data = durationMetrics.data(2);
863     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app3Uid);
864     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
865                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
866     ASSERT_EQ(data.bucket_info_size(), 1);
867     ValidateDurationBucket(data.bucket_info(0), updateTimeNs, bucketEndTimeNs, 5 * NS_PER_SEC);
868 
869     // Uid 3 in BG. Duration = 20.
870     data = durationMetrics.data(3);
871     ValidateAttributionUidDimension(data.dimensions_in_what(), util::SYNC_STATE_CHANGED, app3Uid);
872     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
873                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);
874     ASSERT_EQ(data.bucket_info_size(), 1);
875     ValidateDurationBucket(data.bucket_info(0), updateTimeNs, bucketEndTimeNs, 20 * NS_PER_SEC);
876 }
877 
TEST_F(ConfigUpdateE2eTest,TestGaugeMetric)878 TEST_F(ConfigUpdateE2eTest, TestGaugeMetric) {
879     StatsdConfig config;
880     config.add_allowed_log_source("AID_ROOT");
881     config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
882 
883     AtomMatcher appStartMatcher = CreateSimpleAtomMatcher("AppStart", util::APP_START_OCCURRED);
884     *config.add_atom_matcher() = appStartMatcher;
885     AtomMatcher backgroundMatcher = CreateMoveToBackgroundAtomMatcher();
886     *config.add_atom_matcher() = backgroundMatcher;
887     AtomMatcher foregroundMatcher = CreateMoveToForegroundAtomMatcher();
888     *config.add_atom_matcher() = foregroundMatcher;
889     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
890     *config.add_atom_matcher() = screenOnMatcher;
891     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
892     *config.add_atom_matcher() = screenOffMatcher;
893     AtomMatcher subsystemSleepMatcher =
894             CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
895     *config.add_atom_matcher() = subsystemSleepMatcher;
896 
897     Predicate isInBackgroundPredicate = CreateIsInBackgroundPredicate();
898     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
899             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /*uid field*/});
900     *config.add_predicate() = isInBackgroundPredicate;
901 
902     Predicate screenOnPredicate = CreateScreenIsOnPredicate();
903     *config.add_predicate() = screenOnPredicate;
904 
905     GaugeMetric gaugePullPersist =
906             createGaugeMetric("SubsystemSleepWhileScreenOn", subsystemSleepMatcher.id(),
907                               GaugeMetric::RANDOM_ONE_SAMPLE, screenOnPredicate.id(), {});
908     *gaugePullPersist.mutable_dimensions_in_what() =
909             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
910 
911     GaugeMetric gaugePushPersist =
912             createGaugeMetric("AppStartWhileInBg", appStartMatcher.id(),
913                               GaugeMetric::FIRST_N_SAMPLES, isInBackgroundPredicate.id(), nullopt);
914     *gaugePushPersist.mutable_dimensions_in_what() =
915             CreateDimensions(util::APP_START_OCCURRED, {1 /*uid field*/});
916     // Links between sync state atom and condition of uid is holding wakelock.
917     MetricConditionLink* links = gaugePushPersist.add_links();
918     links->set_condition(isInBackgroundPredicate.id());
919     *links->mutable_fields_in_what() =
920             CreateDimensions(util::APP_START_OCCURRED, {1 /*uid field*/});
921     *links->mutable_fields_in_condition() =
922             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /*uid field*/});
923 
924     GaugeMetric gaugeChange = createGaugeMetric("GaugeScrOn", screenOnMatcher.id(),
925                                                 GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
926     GaugeMetric gaugeRemove =
927             createGaugeMetric("GaugeSubsysTriggerScr", subsystemSleepMatcher.id(),
928                               GaugeMetric::FIRST_N_SAMPLES, nullopt, screenOnMatcher.id());
929     *gaugeRemove.mutable_dimensions_in_what() =
930             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
931     *config.add_gauge_metric() = gaugeRemove;
932     *config.add_gauge_metric() = gaugePullPersist;
933     *config.add_gauge_metric() = gaugeChange;
934     *config.add_gauge_metric() = gaugePushPersist;
935 
936     ConfigKey key(123, 987);
937     uint64_t bucketStartTimeNs = getElapsedRealtimeNs();  // 0:10
938     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
939     sp<StatsLogProcessor> processor = CreateStatsLogProcessor(
940             bucketStartTimeNs, bucketStartTimeNs, config, key,
941             SharedRefBase::make<FakeSubsystemSleepCallback>(), util::SUBSYSTEM_SLEEP_STATE);
942 
943     int app1Uid = 123, app2Uid = 456;
944 
945     // Initialize log events before update.
946     std::vector<std::unique_ptr<LogEvent>> events;
947     events.push_back(CreateMoveToBackgroundEvent(bucketStartTimeNs + 5 * NS_PER_SEC, app1Uid));
948     events.push_back(CreateAppStartOccurredEvent(bucketStartTimeNs + 10 * NS_PER_SEC, app1Uid,
949                                                  "app1", AppStartOccurred::WARM, "", "", true,
950                                                  /*start_msec*/ 101));  // Kept by gaugePushPersist.
951     events.push_back(
952             CreateAppStartOccurredEvent(bucketStartTimeNs + 15 * NS_PER_SEC, app2Uid, "app2",
953                                         AppStartOccurred::WARM, "", "", true,
954                                         /*start_msec*/ 201));  // Not kept by gaugePushPersist.
955     events.push_back(CreateScreenStateChangedEvent(
956             bucketStartTimeNs + 20 * NS_PER_SEC,
957             android::view::DISPLAY_STATE_ON));  // Pulls gaugePullPersist and gaugeRemove.
958     events.push_back(CreateMoveToBackgroundEvent(bucketStartTimeNs + 25 * NS_PER_SEC, app2Uid));
959     events.push_back(
960             CreateScreenStateChangedEvent(bucketStartTimeNs + 30 * NS_PER_SEC,
961                                           android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
962     events.push_back(CreateAppStartOccurredEvent(bucketStartTimeNs + 35 * NS_PER_SEC, app1Uid,
963                                                  "app1", AppStartOccurred::WARM, "", "", true,
964                                                  /*start_msec*/ 102));  // Kept by gaugePushPersist.
965     events.push_back(CreateAppStartOccurredEvent(bucketStartTimeNs + 40 * NS_PER_SEC, app2Uid,
966                                                  "app2", AppStartOccurred::WARM, "", "", true,
967                                                  /*start_msec*/ 202));  // Kept by gaugePushPersist.
968     events.push_back(CreateScreenStateChangedEvent(
969             bucketStartTimeNs + 45 * NS_PER_SEC,
970             android::view::DisplayStateEnum::DISPLAY_STATE_ON));  // Pulls gaugeRemove only.
971     events.push_back(CreateMoveToForegroundEvent(bucketStartTimeNs + 50 * NS_PER_SEC, app1Uid));
972 
973     // Send log events to StatsLogProcessor.
974     for (auto& event : events) {
975         processor->mPullerManager->ForceClearPullerCache();
976         processor->OnLogEvent(event.get());
977     }
978     processor->mPullerManager->ForceClearPullerCache();
979 
980     // Do the update. Add matchers/conditions in different order to force indices to change.
981     StatsdConfig newConfig;
982     newConfig.add_allowed_log_source("AID_ROOT");
983     newConfig.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
984 
985     *newConfig.add_atom_matcher() = screenOffMatcher;
986     *newConfig.add_atom_matcher() = foregroundMatcher;
987     *newConfig.add_atom_matcher() = appStartMatcher;
988     *newConfig.add_atom_matcher() = subsystemSleepMatcher;
989     *newConfig.add_atom_matcher() = backgroundMatcher;
990     *newConfig.add_atom_matcher() = screenOnMatcher;
991 
992     *newConfig.add_predicate() = isInBackgroundPredicate;
993     *newConfig.add_predicate() = screenOnPredicate;
994 
995     gaugeChange.set_sampling_type(GaugeMetric::FIRST_N_SAMPLES);
996     *newConfig.add_gauge_metric() = gaugeChange;
997     GaugeMetric gaugeNew = createGaugeMetric("GaugeSubsys", subsystemSleepMatcher.id(),
998                                              GaugeMetric::RANDOM_ONE_SAMPLE, {}, {});
999     *gaugeNew.mutable_dimensions_in_what() =
1000             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
1001     *newConfig.add_gauge_metric() = gaugeNew;
1002     *newConfig.add_gauge_metric() = gaugePushPersist;
1003     *newConfig.add_gauge_metric() = gaugePullPersist;
1004 
1005     int64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;
1006     // Update pulls gaugePullPersist and gaugeNew.
1007     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
1008 
1009     // Verify puller manager is properly set.
1010     sp<StatsPullerManager> pullerManager = processor->mPullerManager;
1011     EXPECT_EQ(pullerManager->mNextPullTimeNs, bucketStartTimeNs + bucketSizeNs);
1012     ASSERT_EQ(pullerManager->mReceivers.size(), 1);
1013     ASSERT_EQ(pullerManager->mReceivers.begin()->second.size(), 2);
1014 
1015     // Send events after the update. Counts reset to 0 since this is a new bucket.
1016     events.clear();
1017     events.push_back(
1018             CreateAppStartOccurredEvent(bucketStartTimeNs + 65 * NS_PER_SEC, app1Uid, "app1",
1019                                         AppStartOccurred::WARM, "", "", true,
1020                                         /*start_msec*/ 103));  // Not kept by gaugePushPersist.
1021     events.push_back(CreateAppStartOccurredEvent(bucketStartTimeNs + 70 * NS_PER_SEC, app2Uid,
1022                                                  "app2", AppStartOccurred::WARM, "", "", true,
1023                                                  /*start_msec*/ 203));  // Kept by gaugePushPersist.
1024     events.push_back(
1025             CreateScreenStateChangedEvent(bucketStartTimeNs + 75 * NS_PER_SEC,
1026                                           android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
1027     events.push_back(
1028             CreateScreenStateChangedEvent(bucketStartTimeNs + 80 * NS_PER_SEC,
1029                                           android::view::DisplayStateEnum::DISPLAY_STATE_ON));
1030     events.push_back(CreateMoveToBackgroundEvent(bucketStartTimeNs + 85 * NS_PER_SEC, app1Uid));
1031     events.push_back(
1032             CreateScreenStateChangedEvent(bucketStartTimeNs + 90 * NS_PER_SEC,
1033                                           android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
1034     events.push_back(CreateAppStartOccurredEvent(bucketStartTimeNs + 95 * NS_PER_SEC, app1Uid,
1035                                                  "app1", AppStartOccurred::WARM, "", "", true,
1036                                                  /*start_msec*/ 104));  // Kept by gaugePushPersist.
1037     events.push_back(CreateAppStartOccurredEvent(bucketStartTimeNs + 100 * NS_PER_SEC, app2Uid,
1038                                                  "app2", AppStartOccurred::WARM, "", "", true,
1039                                                  /*start_msec*/ 204));  // Kept by gaugePushPersist.
1040     events.push_back(
1041             CreateScreenStateChangedEvent(bucketStartTimeNs + 105 * NS_PER_SEC,
1042                                           android::view::DisplayStateEnum::DISPLAY_STATE_ON));
1043     events.push_back(
1044             CreateScreenStateChangedEvent(bucketStartTimeNs + 110 * NS_PER_SEC,
1045                                           android::view::DisplayStateEnum::DISPLAY_STATE_OFF));
1046     // Send log events to StatsLogProcessor.
1047     for (auto& event : events) {
1048         processor->mPullerManager->ForceClearPullerCache();
1049         processor->OnLogEvent(event.get());
1050     }
1051     processor->mPullerManager->ForceClearPullerCache();
1052     // Pulling alarm arrive, triggering a bucket split. Only gaugeNew keeps the data since the
1053     // condition is false for gaugeNew.
1054     processor->informPullAlarmFired(bucketStartTimeNs + bucketSizeNs);
1055 
1056     uint64_t dumpTimeNs = bucketStartTimeNs + bucketSizeNs + 10 * NS_PER_SEC;
1057     ConfigMetricsReportList reports;
1058     vector<uint8_t> buffer;
1059     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
1060     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1061     backfillDimensionPath(&reports);
1062     backfillStringInReport(&reports);
1063     backfillStartEndTimestamp(&reports);
1064     backfillAggregatedAtoms(&reports);
1065     ASSERT_EQ(reports.reports_size(), 2);
1066 
1067     int64_t roundedBucketStartNs = MillisToNano(NanoToMillis(bucketStartTimeNs));
1068     int64_t roundedUpdateTimeNs = MillisToNano(NanoToMillis(updateTimeNs));
1069     int64_t roundedBucketEndNs = MillisToNano(NanoToMillis(bucketStartTimeNs + bucketSizeNs));
1070     int64_t roundedDumpTimeNs = MillisToNano(NanoToMillis(dumpTimeNs));
1071 
1072     // Report from before update.
1073     ConfigMetricsReport report = reports.reports(0);
1074     ASSERT_EQ(report.metrics_size(), 4);
1075     // Gauge subsystem sleep state trigger screen on. 2 pulls occurred.
1076     StatsLogReport gaugeRemoveBefore = report.metrics(0);
1077     EXPECT_EQ(gaugeRemoveBefore.metric_id(), gaugeRemove.id());
1078     EXPECT_TRUE(gaugeRemoveBefore.has_gauge_metrics());
1079     StatsLogReport::GaugeMetricDataWrapper gaugeMetrics;
1080     sortMetricDataByDimensionsValue(gaugeRemoveBefore.gauge_metrics(), &gaugeMetrics);
1081     ASSERT_EQ(gaugeMetrics.data_size(), 2);
1082     auto data = gaugeMetrics.data(0);
1083     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1084     ASSERT_EQ(data.bucket_info_size(), 1);
1085     ValidateGaugeBucketTimes(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs,
1086                              {(int64_t)(bucketStartTimeNs + 20 * NS_PER_SEC),
1087                               (int64_t)(bucketStartTimeNs + 45 * NS_PER_SEC)});
1088     ASSERT_EQ(data.bucket_info(0).atom_size(), 2);
1089     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 101);
1090     EXPECT_EQ(data.bucket_info(0).atom(1).subsystem_sleep_state().time_millis(), 401);
1091 
1092     data = gaugeMetrics.data(1);
1093     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1094     ASSERT_EQ(data.bucket_info_size(), 1);
1095     ValidateGaugeBucketTimes(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs,
1096                              {(int64_t)(bucketStartTimeNs + 20 * NS_PER_SEC),
1097                               (int64_t)(bucketStartTimeNs + 45 * NS_PER_SEC)});
1098     ASSERT_EQ(data.bucket_info(0).atom_size(), 2);
1099     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 102);
1100     EXPECT_EQ(data.bucket_info(0).atom(1).subsystem_sleep_state().time_millis(), 402);
1101 
1102     // Gauge subsystem sleep state when screen is on. One pull when the screen turned on
1103     StatsLogReport gaugePullPersistBefore = report.metrics(1);
1104     EXPECT_EQ(gaugePullPersistBefore.metric_id(), gaugePullPersist.id());
1105     EXPECT_TRUE(gaugePullPersistBefore.has_gauge_metrics());
1106     gaugeMetrics.Clear();
1107     sortMetricDataByDimensionsValue(gaugePullPersistBefore.gauge_metrics(), &gaugeMetrics);
1108     ASSERT_EQ(gaugeMetrics.data_size(), 2);
1109     data = gaugeMetrics.data(0);
1110     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1111     ASSERT_EQ(data.bucket_info_size(), 1);
1112     ValidateGaugeBucketTimes(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs,
1113                              {(int64_t)(bucketStartTimeNs + 20 * NS_PER_SEC)});
1114     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1115     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 101);
1116 
1117     data = gaugeMetrics.data(1);
1118     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1119     ASSERT_EQ(data.bucket_info_size(), 1);
1120     ValidateGaugeBucketTimes(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs,
1121                              {(int64_t)(bucketStartTimeNs + 20 * NS_PER_SEC)});
1122     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1123     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 102);
1124 
1125     // Gauge screen on events, one per bucket.
1126     StatsLogReport gaugeChangeBefore = report.metrics(2);
1127     EXPECT_EQ(gaugeChangeBefore.metric_id(), gaugeChange.id());
1128     EXPECT_TRUE(gaugeChangeBefore.has_gauge_metrics());
1129     gaugeMetrics.Clear();
1130     sortMetricDataByDimensionsValue(gaugeChangeBefore.gauge_metrics(), &gaugeMetrics);
1131     ASSERT_EQ(gaugeMetrics.data_size(), 1);
1132     data = gaugeMetrics.data(0);
1133     ASSERT_EQ(data.bucket_info_size(), 1);
1134     ValidateGaugeBucketTimes(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs,
1135                              {(int64_t)(bucketStartTimeNs + 20 * NS_PER_SEC)});
1136     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1137     EXPECT_EQ(data.bucket_info(0).atom(0).screen_state_changed().state(),
1138               android::view::DISPLAY_STATE_ON);
1139 
1140     // Gauge app start while app is in the background. App 1 started twice, app 2 started once.
1141     StatsLogReport gaugePushPersistBefore = report.metrics(3);
1142     EXPECT_EQ(gaugePushPersistBefore.metric_id(), gaugePushPersist.id());
1143     EXPECT_TRUE(gaugePushPersistBefore.has_gauge_metrics());
1144     gaugeMetrics.Clear();
1145     sortMetricDataByDimensionsValue(gaugePushPersistBefore.gauge_metrics(), &gaugeMetrics);
1146     ASSERT_EQ(gaugeMetrics.data_size(), 2);
1147     data = gaugeMetrics.data(0);
1148     ValidateUidDimension(data.dimensions_in_what(), util::APP_START_OCCURRED, app1Uid);
1149     ASSERT_EQ(data.bucket_info_size(), 1);
1150     ValidateGaugeBucketTimes(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs,
1151                              {(int64_t)(bucketStartTimeNs + 10 * NS_PER_SEC),
1152                               (int64_t)(bucketStartTimeNs + 35 * NS_PER_SEC)});
1153     ASSERT_EQ(data.bucket_info(0).atom_size(), 2);
1154     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().pkg_name(), "app1");
1155     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis(), 101);
1156     EXPECT_EQ(data.bucket_info(0).atom(1).app_start_occurred().pkg_name(), "app1");
1157     EXPECT_EQ(data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis(), 102);
1158 
1159     data = gaugeMetrics.data(1);
1160     ValidateUidDimension(data.dimensions_in_what(), util::APP_START_OCCURRED, app2Uid);
1161     ASSERT_EQ(data.bucket_info_size(), 1);
1162     ValidateGaugeBucketTimes(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs,
1163                              {(int64_t)(bucketStartTimeNs + 40 * NS_PER_SEC)});
1164     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1165     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().pkg_name(), "app2");
1166     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis(), 202);
1167 
1168     // Report from after update.
1169     report = reports.reports(1);
1170     ASSERT_EQ(report.metrics_size(), 4);
1171     // Gauge screen on events FIRST_N_SAMPLES. There were 2.
1172     StatsLogReport gaugeChangeAfter = report.metrics(0);
1173     EXPECT_EQ(gaugeChangeAfter.metric_id(), gaugeChange.id());
1174     EXPECT_TRUE(gaugeChangeAfter.has_gauge_metrics());
1175     gaugeMetrics.Clear();
1176     sortMetricDataByDimensionsValue(gaugeChangeAfter.gauge_metrics(), &gaugeMetrics);
1177     ASSERT_EQ(gaugeMetrics.data_size(), 1);
1178     data = gaugeMetrics.data(0);
1179     ASSERT_EQ(data.bucket_info_size(), 1);
1180     ValidateGaugeBucketTimes(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs,
1181                              {(int64_t)(bucketStartTimeNs + 80 * NS_PER_SEC),
1182                               (int64_t)(bucketStartTimeNs + 105 * NS_PER_SEC)});
1183     ASSERT_EQ(data.bucket_info(0).atom_size(), 2);
1184     EXPECT_EQ(data.bucket_info(0).atom(0).screen_state_changed().state(),
1185               android::view::DISPLAY_STATE_ON);
1186     EXPECT_EQ(data.bucket_info(0).atom(1).screen_state_changed().state(),
1187               android::view::DISPLAY_STATE_ON);
1188 
1189     // Gauge subsystem sleep state, random one sample, no condition.
1190     // Pulled at update time and after the normal bucket end.
1191     StatsLogReport gaugeNewAfter = report.metrics(1);
1192     EXPECT_EQ(gaugeNewAfter.metric_id(), gaugeNew.id());
1193     EXPECT_TRUE(gaugeNewAfter.has_gauge_metrics());
1194     gaugeMetrics.Clear();
1195     sortMetricDataByDimensionsValue(gaugeNewAfter.gauge_metrics(), &gaugeMetrics);
1196     ASSERT_EQ(gaugeMetrics.data_size(), 2);
1197     data = gaugeMetrics.data(0);
1198     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1199     ASSERT_EQ(data.bucket_info_size(), 2);
1200     ValidateGaugeBucketTimes(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs,
1201                              {updateTimeNs});
1202     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1203     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 901);
1204     ValidateGaugeBucketTimes(data.bucket_info(1), roundedBucketEndNs, roundedDumpTimeNs,
1205                              {(int64_t)(bucketStartTimeNs + bucketSizeNs)});
1206     ASSERT_EQ(data.bucket_info(1).atom_size(), 1);
1207     EXPECT_EQ(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 1601);
1208 
1209     data = gaugeMetrics.data(1);
1210     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1211     ASSERT_EQ(data.bucket_info_size(), 2);
1212     ValidateGaugeBucketTimes(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs,
1213                              {updateTimeNs});
1214     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1215     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 902);
1216     ValidateGaugeBucketTimes(data.bucket_info(1), roundedBucketEndNs, roundedDumpTimeNs,
1217                              {(int64_t)(bucketStartTimeNs + bucketSizeNs)});
1218     ASSERT_EQ(data.bucket_info(1).atom_size(), 1);
1219     EXPECT_EQ(data.bucket_info(1).atom(0).subsystem_sleep_state().time_millis(), 1602);
1220 
1221     // Gauge app start while app is in the background. App 1 started once, app 2 started twice.
1222     StatsLogReport gaugePushPersistAfter = report.metrics(2);
1223     EXPECT_EQ(gaugePushPersistAfter.metric_id(), gaugePushPersist.id());
1224     EXPECT_TRUE(gaugePushPersistAfter.has_gauge_metrics());
1225     gaugeMetrics.Clear();
1226     sortMetricDataByDimensionsValue(gaugePushPersistAfter.gauge_metrics(), &gaugeMetrics);
1227     ASSERT_EQ(gaugeMetrics.data_size(), 2);
1228     data = gaugeMetrics.data(0);
1229     ValidateUidDimension(data.dimensions_in_what(), util::APP_START_OCCURRED, app1Uid);
1230     ASSERT_EQ(data.bucket_info_size(), 1);
1231     ValidateGaugeBucketTimes(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs,
1232                              {(int64_t)(bucketStartTimeNs + 95 * NS_PER_SEC)});
1233     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1234     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().pkg_name(), "app1");
1235     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis(), 104);
1236 
1237     data = gaugeMetrics.data(1);
1238     ValidateUidDimension(data.dimensions_in_what(), util::APP_START_OCCURRED, app2Uid);
1239     ASSERT_EQ(data.bucket_info_size(), 1);
1240     ValidateGaugeBucketTimes(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs,
1241                              {(int64_t)(bucketStartTimeNs + 70 * NS_PER_SEC),
1242                               (int64_t)(bucketStartTimeNs + 100 * NS_PER_SEC)});
1243     ASSERT_EQ(data.bucket_info(0).atom_size(), 2);
1244     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().pkg_name(), "app2");
1245     EXPECT_EQ(data.bucket_info(0).atom(0).app_start_occurred().activity_start_millis(), 203);
1246     EXPECT_EQ(data.bucket_info(0).atom(1).app_start_occurred().pkg_name(), "app2");
1247     EXPECT_EQ(data.bucket_info(0).atom(1).app_start_occurred().activity_start_millis(), 204);
1248 
1249     // Gauge subsystem sleep state when screen is on. One pull at update since screen is on then.
1250     StatsLogReport gaugePullPersistAfter = report.metrics(3);
1251     EXPECT_EQ(gaugePullPersistAfter.metric_id(), gaugePullPersist.id());
1252     EXPECT_TRUE(gaugePullPersistAfter.has_gauge_metrics());
1253     gaugeMetrics.Clear();
1254     sortMetricDataByDimensionsValue(gaugePullPersistAfter.gauge_metrics(), &gaugeMetrics);
1255     ASSERT_EQ(gaugeMetrics.data_size(), 2);
1256     data = gaugeMetrics.data(0);
1257     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1258     ASSERT_EQ(data.bucket_info_size(), 1);
1259     ValidateGaugeBucketTimes(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs,
1260                              {updateTimeNs});
1261     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1262     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 901);
1263 
1264     data = gaugeMetrics.data(1);
1265     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1266     ASSERT_EQ(data.bucket_info_size(), 1);
1267     ValidateGaugeBucketTimes(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs,
1268                              {updateTimeNs});
1269     ASSERT_EQ(data.bucket_info(0).atom_size(), 1);
1270     EXPECT_EQ(data.bucket_info(0).atom(0).subsystem_sleep_state().time_millis(), 902);
1271 }
1272 
TEST_F(ConfigUpdateE2eTest,TestValueMetric)1273 TEST_F(ConfigUpdateE2eTest, TestValueMetric) {
1274     StatsdConfig config;
1275     config.add_allowed_log_source("AID_ROOT");
1276     config.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
1277 
1278     AtomMatcher brightnessMatcher = CreateScreenBrightnessChangedAtomMatcher();
1279     *config.add_atom_matcher() = brightnessMatcher;
1280     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
1281     *config.add_atom_matcher() = screenOnMatcher;
1282     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
1283     *config.add_atom_matcher() = screenOffMatcher;
1284     AtomMatcher batteryPluggedUsbMatcher = CreateBatteryStateUsbMatcher();
1285     *config.add_atom_matcher() = batteryPluggedUsbMatcher;
1286     AtomMatcher unpluggedMatcher = CreateBatteryStateNoneMatcher();
1287     *config.add_atom_matcher() = unpluggedMatcher;
1288     AtomMatcher subsystemSleepMatcher =
1289             CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
1290     *config.add_atom_matcher() = subsystemSleepMatcher;
1291 
1292     Predicate screenOnPredicate = CreateScreenIsOnPredicate();
1293     *config.add_predicate() = screenOnPredicate;
1294     Predicate unpluggedPredicate = CreateDeviceUnpluggedPredicate();
1295     *config.add_predicate() = unpluggedPredicate;
1296 
1297     State screenState = CreateScreenState();
1298     *config.add_state() = screenState;
1299 
1300     ValueMetric valuePullPersist =
1301             createValueMetric("SubsystemSleepWhileUnpluggedSliceScreen", subsystemSleepMatcher, 4,
1302                               unpluggedPredicate.id(), {screenState.id()});
1303     *valuePullPersist.mutable_dimensions_in_what() =
1304             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
1305 
1306     ValueMetric valuePushPersist = createValueMetric(
1307             "MinScreenBrightnessWhileScreenOn", brightnessMatcher, 1, screenOnPredicate.id(), {});
1308     valuePushPersist.set_aggregation_type(ValueMetric::MIN);
1309 
1310     ValueMetric valueChange =
1311             createValueMetric("SubsystemSleep", subsystemSleepMatcher, 4, nullopt, {});
1312     *valueChange.mutable_dimensions_in_what() =
1313             CreateDimensions(util::SUBSYSTEM_SLEEP_STATE, {1 /* subsystem name */});
1314 
1315     ValueMetric valueRemove =
1316             createValueMetric("AvgScreenBrightness", brightnessMatcher, 1, nullopt, {});
1317     valueRemove.set_aggregation_type(ValueMetric::AVG);
1318 
1319     *config.add_value_metric() = valuePullPersist;
1320     *config.add_value_metric() = valueRemove;
1321     *config.add_value_metric() = valuePushPersist;
1322     *config.add_value_metric() = valueChange;
1323 
1324     ConfigKey key(123, 987);
1325     uint64_t bucketStartTimeNs = getElapsedRealtimeNs();
1326     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
1327     // Config creation triggers pull #1.
1328     sp<StatsLogProcessor> processor = CreateStatsLogProcessor(
1329             bucketStartTimeNs, bucketStartTimeNs, config, key,
1330             SharedRefBase::make<FakeSubsystemSleepCallback>(), util::SUBSYSTEM_SLEEP_STATE);
1331 
1332     // Initialize log events before update.
1333     // ValuePushPersist and ValuePullPersist will skip the bucket due to condition unknown.
1334     std::vector<std::unique_ptr<LogEvent>> events;
1335     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 5 * NS_PER_SEC, 5));
1336     events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
1337                                                    android::view::DISPLAY_STATE_ON));
1338     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 15 * NS_PER_SEC, 15));
1339     events.push_back(CreateBatteryStateChangedEvent(
1340             bucketStartTimeNs + 20 * NS_PER_SEC,
1341             BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));  // Pull #2.
1342     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 25 * NS_PER_SEC, 40));
1343 
1344     // Send log events to StatsLogProcessor.
1345     for (auto& event : events) {
1346         processor->mPullerManager->ForceClearPullerCache();
1347         processor->OnLogEvent(event.get());
1348     }
1349     processor->mPullerManager->ForceClearPullerCache();
1350 
1351     // Do the update. Add matchers/conditions in different order to force indices to change.
1352     StatsdConfig newConfig;
1353     newConfig.add_allowed_log_source("AID_ROOT");
1354     newConfig.add_default_pull_packages("AID_ROOT");  // Fake puller is registered with root.
1355 
1356     *newConfig.add_atom_matcher() = screenOffMatcher;
1357     *newConfig.add_atom_matcher() = unpluggedMatcher;
1358     *newConfig.add_atom_matcher() = batteryPluggedUsbMatcher;
1359     *newConfig.add_atom_matcher() = subsystemSleepMatcher;
1360     *newConfig.add_atom_matcher() = brightnessMatcher;
1361     *newConfig.add_atom_matcher() = screenOnMatcher;
1362 
1363     *newConfig.add_predicate() = unpluggedPredicate;
1364     *newConfig.add_predicate() = screenOnPredicate;
1365 
1366     *config.add_state() = screenState;
1367 
1368     valueChange.set_condition(screenOnPredicate.id());
1369     *newConfig.add_value_metric() = valueChange;
1370     ValueMetric valueNew = createValueMetric("MaxScrBrightness", brightnessMatcher, 1, nullopt, {});
1371     valueNew.set_aggregation_type(ValueMetric::MAX);
1372     *newConfig.add_value_metric() = valueNew;
1373     *newConfig.add_value_metric() = valuePushPersist;
1374     *newConfig.add_value_metric() = valuePullPersist;
1375 
1376     int64_t updateTimeNs = bucketStartTimeNs + 30 * NS_PER_SEC;
1377     // Update pulls valuePullPersist and valueNew. Pull #3.
1378     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
1379 
1380     // Verify puller manager is properly set.
1381     sp<StatsPullerManager> pullerManager = processor->mPullerManager;
1382     EXPECT_EQ(pullerManager->mNextPullTimeNs, bucketStartTimeNs + bucketSizeNs);
1383     ASSERT_EQ(pullerManager->mReceivers.size(), 1);
1384     ASSERT_EQ(pullerManager->mReceivers.begin()->second.size(), 2);
1385 
1386     // Send events after the update. Values reset since this is a new bucket.
1387     events.clear();
1388     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 35 * NS_PER_SEC, 30));
1389     events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 40 * NS_PER_SEC,
1390                                                    android::view::DISPLAY_STATE_OFF));  // Pull #4.
1391     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 45 * NS_PER_SEC, 20));
1392     events.push_back(CreateBatteryStateChangedEvent(
1393             bucketStartTimeNs + 50 * NS_PER_SEC,
1394             BatteryPluggedStateEnum::BATTERY_PLUGGED_USB));  // Pull #5.
1395     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 55 * NS_PER_SEC, 25));
1396     events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 60 * NS_PER_SEC,
1397                                                    android::view::DISPLAY_STATE_ON));  // Pull #6.
1398     events.push_back(CreateBatteryStateChangedEvent(
1399             bucketStartTimeNs + 65 * NS_PER_SEC,
1400             BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));  // Pull #7.
1401     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 70 * NS_PER_SEC, 40));
1402 
1403     // Send log events to StatsLogProcessor.
1404     for (auto& event : events) {
1405         processor->mPullerManager->ForceClearPullerCache();
1406         processor->OnLogEvent(event.get());
1407     }
1408     processor->mPullerManager->ForceClearPullerCache();
1409 
1410     // Pulling alarm arrive, triggering a bucket split.
1411     // Both valuePullPersist and valueChange use the value since both conditions are true. Pull #8.
1412     processor->informPullAlarmFired(bucketStartTimeNs + bucketSizeNs);
1413     processor->OnLogEvent(CreateScreenBrightnessChangedEvent(
1414                                   bucketStartTimeNs + bucketSizeNs + 5 * NS_PER_SEC, 50)
1415                                   .get());
1416 
1417     uint64_t dumpTimeNs = bucketStartTimeNs + bucketSizeNs + 10 * NS_PER_SEC;
1418     ConfigMetricsReportList reports;
1419     vector<uint8_t> buffer;
1420     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
1421     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1422     backfillDimensionPath(&reports);
1423     backfillStringInReport(&reports);
1424     backfillStartEndTimestamp(&reports);
1425     ASSERT_EQ(reports.reports_size(), 2);
1426 
1427     int64_t roundedBucketStartNs = MillisToNano(NanoToMillis(bucketStartTimeNs));
1428     int64_t roundedUpdateTimeNs = MillisToNano(NanoToMillis(updateTimeNs));
1429     int64_t roundedBucketEndNs = MillisToNano(NanoToMillis(bucketStartTimeNs + bucketSizeNs));
1430     int64_t roundedDumpTimeNs = MillisToNano(NanoToMillis(dumpTimeNs));
1431 
1432     // Report from before update.
1433     ConfigMetricsReport report = reports.reports(0);
1434     ASSERT_EQ(report.metrics_size(), 4);
1435     // Pull subsystem sleep while unplugged slice screen. Bucket skipped due to condition unknown.
1436     StatsLogReport valuePullPersistBefore = report.metrics(0);
1437     EXPECT_EQ(valuePullPersistBefore.metric_id(), valuePullPersist.id());
1438     EXPECT_TRUE(valuePullPersistBefore.has_value_metrics());
1439     ASSERT_EQ(valuePullPersistBefore.value_metrics().data_size(), 0);
1440     ASSERT_EQ(valuePullPersistBefore.value_metrics().skipped_size(), 1);
1441     StatsLogReport::SkippedBuckets skipBucket = valuePullPersistBefore.value_metrics().skipped(0);
1442     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), roundedBucketStartNs);
1443     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), roundedUpdateTimeNs);
1444     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1445     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::CONDITION_UNKNOWN);
1446 
1447     // Average screen brightness. Values were 5, 15, 40. Avg: 20.
1448     StatsLogReport valueRemoveBefore = report.metrics(1);
1449     EXPECT_EQ(valueRemoveBefore.metric_id(), valueRemove.id());
1450     EXPECT_TRUE(valueRemoveBefore.has_value_metrics());
1451     StatsLogReport::ValueMetricDataWrapper valueMetrics;
1452     sortMetricDataByDimensionsValue(valueRemoveBefore.value_metrics(), &valueMetrics);
1453     ASSERT_EQ(valueMetrics.data_size(), 1);
1454     ValueMetricData data = valueMetrics.data(0);
1455     EXPECT_FALSE(data.has_dimensions_in_what());
1456     EXPECT_EQ(data.slice_by_state_size(), 0);
1457     ASSERT_EQ(data.bucket_info_size(), 1);
1458     ValidateValueBucket(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs, {20}, 0, 0);
1459 
1460     // Min screen brightness while screen on. Bucket skipped due to condition unknown.
1461     StatsLogReport valuePushPersistBefore = report.metrics(2);
1462     EXPECT_EQ(valuePushPersistBefore.metric_id(), valuePushPersist.id());
1463     EXPECT_TRUE(valuePushPersistBefore.has_value_metrics());
1464     ASSERT_EQ(valuePushPersistBefore.value_metrics().data_size(), 0);
1465     ASSERT_EQ(valuePushPersistBefore.value_metrics().skipped_size(), 1);
1466     skipBucket = valuePushPersistBefore.value_metrics().skipped(0);
1467     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), roundedBucketStartNs);
1468     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), roundedUpdateTimeNs);
1469     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1470     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::CONDITION_UNKNOWN);
1471 
1472     // Pull Subsystem sleep state. Value is Pull #3 (900) - Pull#1 (100).
1473     StatsLogReport valueChangeBefore = report.metrics(3);
1474     EXPECT_EQ(valueChangeBefore.metric_id(), valueChange.id());
1475     EXPECT_TRUE(valueChangeBefore.has_value_metrics());
1476     valueMetrics.Clear();
1477     sortMetricDataByDimensionsValue(valueChangeBefore.value_metrics(), &valueMetrics);
1478     ASSERT_EQ(valueMetrics.data_size(), 2);
1479     data = valueMetrics.data(0);
1480     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1481     ASSERT_EQ(data.bucket_info_size(), 1);
1482     ValidateValueBucket(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs, {800}, 0,
1483                         0);
1484     data = valueMetrics.data(1);
1485     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1486     ASSERT_EQ(data.bucket_info_size(), 1);
1487     ValidateValueBucket(data.bucket_info(0), roundedBucketStartNs, roundedUpdateTimeNs, {800}, 0,
1488                         0);
1489 
1490     // Report from after update.
1491     report = reports.reports(1);
1492     ASSERT_EQ(report.metrics_size(), 4);
1493     // Pull subsystem sleep while screen on.
1494     // Pull#4 (1600) - pull#3 (900) + pull#8 (6400) - pull#6 (3600)
1495     StatsLogReport valueChangeAfter = report.metrics(0);
1496     EXPECT_EQ(valueChangeAfter.metric_id(), valueChange.id());
1497     EXPECT_TRUE(valueChangeAfter.has_value_metrics());
1498     valueMetrics.Clear();
1499     sortMetricDataByDimensionsValue(valueChangeAfter.value_metrics(), &valueMetrics);
1500     int64_t conditionTrueNs = bucketSizeNs - 60 * NS_PER_SEC + 10 * NS_PER_SEC;
1501     ASSERT_EQ(valueMetrics.data_size(), 2);
1502     data = valueMetrics.data(0);
1503     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1504     ASSERT_EQ(data.bucket_info_size(), 1);
1505     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {3500},
1506                         conditionTrueNs, 0);
1507     ASSERT_EQ(valueMetrics.data_size(), 2);
1508     data = valueMetrics.data(1);
1509     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1510     ASSERT_EQ(data.bucket_info_size(), 1);
1511     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {3500},
1512                         conditionTrueNs, 0);
1513 
1514     ASSERT_EQ(valueChangeAfter.value_metrics().skipped_size(), 1);
1515     skipBucket = valueChangeAfter.value_metrics().skipped(0);
1516     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), roundedBucketEndNs);
1517     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), roundedDumpTimeNs);
1518     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1519     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::DUMP_REPORT_REQUESTED);
1520 
1521     // Max screen brightness, no condition. Val is 40 in first bucket, 50 in second.
1522     StatsLogReport valueNewAfter = report.metrics(1);
1523     EXPECT_EQ(valueNewAfter.metric_id(), valueNew.id());
1524     EXPECT_TRUE(valueNewAfter.has_value_metrics());
1525     valueMetrics.Clear();
1526     sortMetricDataByDimensionsValue(valueNewAfter.value_metrics(), &valueMetrics);
1527     ASSERT_EQ(valueMetrics.data_size(), 1);
1528     data = valueMetrics.data(0);
1529     ASSERT_EQ(data.bucket_info_size(), 2);
1530     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {40}, 0, 0);
1531     ValidateValueBucket(data.bucket_info(1), roundedBucketEndNs, roundedDumpTimeNs, {50}, 0, 0);
1532 
1533     // Min screen brightness when screen on. Val is 30 in first bucket, 50 in second.
1534     StatsLogReport valuePushPersistAfter = report.metrics(2);
1535     EXPECT_EQ(valuePushPersistAfter.metric_id(), valuePushPersist.id());
1536     EXPECT_TRUE(valuePushPersistAfter.has_value_metrics());
1537     valueMetrics.Clear();
1538     sortMetricDataByDimensionsValue(valuePushPersistAfter.value_metrics(), &valueMetrics);
1539     ASSERT_EQ(valueMetrics.data_size(), 1);
1540     data = valueMetrics.data(0);
1541     ASSERT_EQ(data.bucket_info_size(), 2);
1542     conditionTrueNs = bucketSizeNs - 60 * NS_PER_SEC + 10 * NS_PER_SEC;
1543     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {30},
1544                         conditionTrueNs, 0);
1545     ValidateValueBucket(data.bucket_info(1), roundedBucketEndNs, roundedDumpTimeNs, {50},
1546                         10 * NS_PER_SEC, 0);
1547 
1548     // TODO(b/179725160): fix assertions.
1549     // Subsystem sleep state while unplugged slice screen.
1550     StatsLogReport valuePullPersistAfter = report.metrics(3);
1551     EXPECT_EQ(valuePullPersistAfter.metric_id(), valuePullPersist.id());
1552     EXPECT_TRUE(valuePullPersistAfter.has_value_metrics());
1553     valueMetrics.Clear();
1554     sortMetricDataByDimensionsValue(valuePullPersistAfter.value_metrics(), &valueMetrics);
1555     ASSERT_EQ(valueMetrics.data_size(), 4);
1556     // Name 1, screen OFF. Pull#5 (2500) - pull#4 (1600).
1557     data = valueMetrics.data(0);
1558     conditionTrueNs = 10 * NS_PER_SEC;
1559     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1560     ValidateStateValue(data.slice_by_state(), util::SCREEN_STATE_CHANGED,
1561                        android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
1562     ASSERT_EQ(data.bucket_info_size(), 1);
1563     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {900}, -1, 0);
1564     // Name 1, screen ON. Pull#4 (1600) - pull#3 (900) + pull#8 (6400) - pull#7 (4900).
1565     data = valueMetrics.data(1);
1566     conditionTrueNs = 10 * NS_PER_SEC + bucketSizeNs - 65 * NS_PER_SEC;
1567     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_1");
1568     ValidateStateValue(data.slice_by_state(), util::SCREEN_STATE_CHANGED,
1569                        android::view::DisplayStateEnum::DISPLAY_STATE_ON);
1570     ASSERT_EQ(data.bucket_info_size(), 1);
1571     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {2200}, -1,
1572                         0);
1573     // Name 2, screen OFF. Pull#5 (2500) - pull#4 (1600).
1574     data = valueMetrics.data(2);
1575     conditionTrueNs = 10 * NS_PER_SEC;
1576     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1577     ValidateStateValue(data.slice_by_state(), util::SCREEN_STATE_CHANGED,
1578                        android::view::DisplayStateEnum::DISPLAY_STATE_OFF);
1579     ASSERT_EQ(data.bucket_info_size(), 1);
1580     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {900}, -1, 0);
1581     // Name 2, screen ON. Pull#4 (1600) - pull#3 (900) + pull#8 (6400) - pull#7 (4900).
1582     data = valueMetrics.data(3);
1583     conditionTrueNs = 10 * NS_PER_SEC + bucketSizeNs - 65 * NS_PER_SEC;
1584     ValidateSubsystemSleepDimension(data.dimensions_in_what(), "subsystem_name_2");
1585     ValidateStateValue(data.slice_by_state(), util::SCREEN_STATE_CHANGED,
1586                        android::view::DisplayStateEnum::DISPLAY_STATE_ON);
1587     ASSERT_EQ(data.bucket_info_size(), 1);
1588     ValidateValueBucket(data.bucket_info(0), roundedUpdateTimeNs, roundedBucketEndNs, {2200}, -1,
1589                         0);
1590 
1591     ASSERT_EQ(valuePullPersistAfter.value_metrics().skipped_size(), 1);
1592     skipBucket = valuePullPersistAfter.value_metrics().skipped(0);
1593     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), roundedBucketEndNs);
1594     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), roundedDumpTimeNs);
1595     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1596     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::DUMP_REPORT_REQUESTED);
1597 }
1598 
TEST_F(ConfigUpdateE2eTest,TestKllMetric)1599 TEST_F(ConfigUpdateE2eTest, TestKllMetric) {
1600     StatsdConfig config;
1601     config.add_allowed_log_source("AID_ROOT");
1602 
1603     AtomMatcher brightnessMatcher = CreateScreenBrightnessChangedAtomMatcher();
1604     *config.add_atom_matcher() = brightnessMatcher;
1605     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
1606     *config.add_atom_matcher() = screenOnMatcher;
1607     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
1608     *config.add_atom_matcher() = screenOffMatcher;
1609     AtomMatcher batteryPluggedUsbMatcher = CreateBatteryStateUsbMatcher();
1610     *config.add_atom_matcher() = batteryPluggedUsbMatcher;
1611     AtomMatcher unpluggedMatcher = CreateBatteryStateNoneMatcher();
1612     *config.add_atom_matcher() = unpluggedMatcher;
1613 
1614     Predicate screenOnPredicate = CreateScreenIsOnPredicate();
1615     *config.add_predicate() = screenOnPredicate;
1616     Predicate unpluggedPredicate = CreateDeviceUnpluggedPredicate();
1617     *config.add_predicate() = unpluggedPredicate;
1618 
1619     KllMetric kllPersist = createKllMetric("ScreenBrightnessWhileScreenOn", brightnessMatcher, 1,
1620                                            screenOnPredicate.id());
1621 
1622     KllMetric kllChange = createKllMetric("ScreenBrightness", brightnessMatcher, 1, nullopt);
1623 
1624     KllMetric kllRemove = createKllMetric("ScreenBrightnessWhileUnplugged", brightnessMatcher, 1,
1625                                           unpluggedPredicate.id());
1626 
1627     *config.add_kll_metric() = kllRemove;
1628     *config.add_kll_metric() = kllPersist;
1629     *config.add_kll_metric() = kllChange;
1630 
1631     ConfigKey key(123, 987);
1632     const uint64_t bucketStartTimeNs = 10000000000;  // 0:10
1633     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
1634     sp<StatsLogProcessor> processor =
1635             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
1636 
1637     // Initialize log events before update.
1638     // kllPersist and kllRemove will skip the bucket due to condition unknown.
1639     std::vector<std::unique_ptr<LogEvent>> events;
1640     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 5 * NS_PER_SEC, 5));
1641     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 15 * NS_PER_SEC, 15));
1642     events.push_back(CreateBatteryStateChangedEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
1643                                                     BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));
1644     events.push_back(CreateScreenBrightnessChangedEvent(bucketStartTimeNs + 25 * NS_PER_SEC, 40));
1645     events.push_back(CreateScreenStateChangedEvent(bucketStartTimeNs + 27 * NS_PER_SEC,
1646                                                    android::view::DISPLAY_STATE_ON));
1647 
1648     // Send log events to StatsLogProcessor.
1649     for (auto& event : events) {
1650         processor->OnLogEvent(event.get());
1651     }
1652 
1653     // Do the update. Add matchers/conditions in different order to force indices to change.
1654     StatsdConfig newConfig;
1655     newConfig.add_allowed_log_source("AID_ROOT");
1656 
1657     *newConfig.add_atom_matcher() = screenOffMatcher;
1658     *newConfig.add_atom_matcher() = unpluggedMatcher;
1659     *newConfig.add_atom_matcher() = batteryPluggedUsbMatcher;
1660     *newConfig.add_atom_matcher() = brightnessMatcher;
1661     *newConfig.add_atom_matcher() = screenOnMatcher;
1662     AtomMatcher batterySaverStartMatcher = CreateBatterySaverModeStartAtomMatcher();
1663     *newConfig.add_atom_matcher() = batterySaverStartMatcher;
1664     AtomMatcher batterySaverStopMatcher = CreateBatterySaverModeStopAtomMatcher();
1665     *newConfig.add_atom_matcher() = batterySaverStopMatcher;
1666 
1667     *newConfig.add_predicate() = screenOnPredicate;
1668     Predicate batterySaverPredicate = CreateBatterySaverModePredicate();
1669     *newConfig.add_predicate() = batterySaverPredicate;
1670     Predicate screenOffPredicate = CreateScreenIsOffPredicate();
1671     *newConfig.add_predicate() = screenOffPredicate;
1672 
1673     kllChange.set_condition(batterySaverPredicate.id());
1674     *newConfig.add_kll_metric() = kllChange;
1675     KllMetric kllNew = createKllMetric("ScreenBrightnessWhileScreenOff", brightnessMatcher, 1,
1676                                        screenOffPredicate.id());
1677     *newConfig.add_kll_metric() = kllNew;
1678     *newConfig.add_kll_metric() = kllPersist;
1679 
1680     int64_t updateTimeNs = bucketStartTimeNs + 30 * NS_PER_SEC;
1681     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
1682 
1683     // Send events after the update. This is a new bucket.
1684     events.clear();
1685     events.push_back(CreateScreenBrightnessChangedEvent(updateTimeNs + 5 * NS_PER_SEC, 30));
1686     events.push_back(CreateScreenStateChangedEvent(updateTimeNs + 10 * NS_PER_SEC,
1687                                                    android::view::DISPLAY_STATE_OFF));
1688     events.push_back(CreateScreenBrightnessChangedEvent(updateTimeNs + 15 * NS_PER_SEC, 20));
1689     events.push_back(CreateBatteryStateChangedEvent(updateTimeNs + 20 * NS_PER_SEC,
1690                                                     BatteryPluggedStateEnum::BATTERY_PLUGGED_USB));
1691     events.push_back(CreateScreenBrightnessChangedEvent(updateTimeNs + 25 * NS_PER_SEC, 25));
1692     events.push_back(CreateScreenStateChangedEvent(updateTimeNs + 30 * NS_PER_SEC,
1693                                                    android::view::DISPLAY_STATE_ON));
1694     events.push_back(CreateBatteryStateChangedEvent(updateTimeNs + 35 * NS_PER_SEC,
1695                                                     BatteryPluggedStateEnum::BATTERY_PLUGGED_NONE));
1696     events.push_back(CreateScreenBrightnessChangedEvent(updateTimeNs + 40 * NS_PER_SEC, 40));
1697 
1698     // End current bucket and start new bucket.
1699     events.push_back(CreateScreenBrightnessChangedEvent(
1700             bucketStartTimeNs + bucketSizeNs + 5 * NS_PER_SEC, 50));
1701 
1702     // Send log events to StatsLogProcessor.
1703     for (auto& event : events) {
1704         processor->OnLogEvent(event.get());
1705     }
1706 
1707     uint64_t dumpTimeNs = bucketStartTimeNs + bucketSizeNs + 10 * NS_PER_SEC;
1708     ConfigMetricsReportList reports;
1709     vector<uint8_t> buffer;
1710     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
1711     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1712     backfillDimensionPath(&reports);
1713     backfillStringInReport(&reports);
1714     backfillStartEndTimestamp(&reports);
1715     ASSERT_EQ(reports.reports_size(), 2);
1716 
1717     // Report from before update.
1718     ConfigMetricsReport report = reports.reports(0);
1719     ASSERT_EQ(report.metrics_size(), 3);
1720 
1721     // kllRemove: Screen brightness while unplugged. Bucket skipped due to condition unknown.
1722     StatsLogReport kllRemoveBefore = report.metrics(0);
1723     EXPECT_EQ(kllRemoveBefore.metric_id(), kllRemove.id());
1724     EXPECT_TRUE(kllRemoveBefore.has_kll_metrics());
1725     ASSERT_EQ(kllRemoveBefore.kll_metrics().data_size(), 0);
1726     ASSERT_EQ(kllRemoveBefore.kll_metrics().skipped_size(), 1);
1727     StatsLogReport::SkippedBuckets skipBucket = kllRemoveBefore.kll_metrics().skipped(0);
1728     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), bucketStartTimeNs);
1729     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), updateTimeNs);
1730     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1731     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::CONDITION_UNKNOWN);
1732 
1733     // kllPersist: Screen brightness while screen on.
1734     StatsLogReport kllPersistBefore = report.metrics(1);
1735     EXPECT_EQ(kllPersistBefore.metric_id(), kllPersist.id());
1736     EXPECT_TRUE(kllPersistBefore.has_kll_metrics());
1737     EXPECT_EQ(kllPersistBefore.kll_metrics().data_size(), 0);
1738     ASSERT_EQ(kllPersistBefore.kll_metrics().skipped_size(), 1);
1739     skipBucket = kllPersistBefore.kll_metrics().skipped(0);
1740     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), bucketStartTimeNs);
1741     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), updateTimeNs);
1742     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1743     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::CONDITION_UNKNOWN);
1744 
1745     // kllChange: Screen brightness.
1746     StatsLogReport kllChangeBefore = report.metrics(2);
1747     EXPECT_EQ(kllChangeBefore.metric_id(), kllChange.id());
1748     EXPECT_TRUE(kllChangeBefore.has_kll_metrics());
1749     ASSERT_EQ(kllChangeBefore.kll_metrics().data_size(), 1);
1750     KllMetricData data = kllChangeBefore.kll_metrics().data(0);
1751     ASSERT_EQ(data.bucket_info_size(), 1);
1752     TRACE_CALL(ValidateKllBucket, data.bucket_info(0), bucketStartTimeNs, updateTimeNs,
1753                /*sketchSizes=*/{3}, /*conditionTrueNs=*/0);
1754     EXPECT_EQ(kllChangeBefore.kll_metrics().skipped_size(), 0);
1755 
1756     // Report from after update.
1757     report = reports.reports(1);
1758     ASSERT_EQ(report.metrics_size(), 3);
1759 
1760     // kllChange: Screen brightness while on battery saver.
1761     StatsLogReport kllChangeAfter = report.metrics(0);
1762     EXPECT_EQ(kllChangeAfter.metric_id(), kllChange.id());
1763     EXPECT_TRUE(kllChangeAfter.has_kll_metrics());
1764     EXPECT_EQ(kllChangeAfter.kll_metrics().data_size(), 0);
1765     ASSERT_EQ(kllChangeAfter.kll_metrics().skipped_size(), 2);
1766     skipBucket = kllChangeAfter.kll_metrics().skipped(0);
1767     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), updateTimeNs);
1768     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
1769     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1770     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::CONDITION_UNKNOWN);
1771     skipBucket = kllChangeAfter.kll_metrics().skipped(1);
1772     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
1773     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), dumpTimeNs);
1774     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1775     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::CONDITION_UNKNOWN);
1776 
1777     // kllNew: Screen brightness while screen off.
1778     StatsLogReport kllNewAfter = report.metrics(1);
1779     EXPECT_EQ(kllNewAfter.metric_id(), kllNew.id());
1780     EXPECT_TRUE(kllNewAfter.has_kll_metrics());
1781     EXPECT_EQ(kllNewAfter.kll_metrics().data_size(), 0);
1782     ASSERT_EQ(kllNewAfter.kll_metrics().skipped_size(), 2);
1783     skipBucket = kllNewAfter.kll_metrics().skipped(0);
1784     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), updateTimeNs);
1785     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
1786     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1787     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::CONDITION_UNKNOWN);
1788     skipBucket = kllNewAfter.kll_metrics().skipped(1);
1789     EXPECT_EQ(skipBucket.start_bucket_elapsed_nanos(), bucketStartTimeNs + bucketSizeNs);
1790     EXPECT_EQ(skipBucket.end_bucket_elapsed_nanos(), dumpTimeNs);
1791     ASSERT_EQ(skipBucket.drop_event_size(), 1);
1792     EXPECT_EQ(skipBucket.drop_event(0).drop_reason(), BucketDropReason::NO_DATA);
1793 
1794     // kllPersist: Screen brightness while screen on.
1795     StatsLogReport kllPersistAfter = report.metrics(2);
1796     EXPECT_EQ(kllPersistAfter.metric_id(), kllPersist.id());
1797     EXPECT_TRUE(kllPersistAfter.has_kll_metrics());
1798     ASSERT_EQ(kllPersistAfter.kll_metrics().data_size(), 1);
1799     data = kllPersistAfter.kll_metrics().data(0);
1800     ASSERT_EQ(data.bucket_info_size(), 2);
1801     int64_t conditionTrueNs =
1802             bucketStartTimeNs + 40 * NS_PER_SEC - updateTimeNs + bucketSizeNs - 60 * NS_PER_SEC;
1803     TRACE_CALL(ValidateKllBucket, data.bucket_info(0), updateTimeNs,
1804                bucketStartTimeNs + bucketSizeNs,
1805                /*sketchSizes=*/{2}, conditionTrueNs);
1806     conditionTrueNs = dumpTimeNs - bucketStartTimeNs - bucketSizeNs;
1807     TRACE_CALL(ValidateKllBucket, data.bucket_info(1), bucketStartTimeNs + bucketSizeNs, dumpTimeNs,
1808                /*sketchSizes=*/{1}, conditionTrueNs);
1809     EXPECT_EQ(kllPersistAfter.kll_metrics().skipped_size(), 0);
1810 }
1811 
TEST_F(ConfigUpdateE2eTest,TestMetricActivation)1812 TEST_F(ConfigUpdateE2eTest, TestMetricActivation) {
1813     ALOGE("Start ConfigUpdateE2eTest#TestMetricActivation");
1814     StatsdConfig config;
1815     config.add_allowed_log_source("AID_ROOT");
1816 
1817     string immediateTag = "immediate", bootTag = "boot", childTag = "child";
1818 
1819     AtomMatcher syncStartMatcher = CreateSyncStartAtomMatcher();
1820     *config.add_atom_matcher() = syncStartMatcher;
1821 
1822     AtomMatcher immediateMatcher =
1823             CreateSimpleAtomMatcher("immediateMatcher", util::WAKELOCK_STATE_CHANGED);
1824     FieldValueMatcher* fvm =
1825             immediateMatcher.mutable_simple_atom_matcher()->add_field_value_matcher();
1826     fvm->set_field(3);  // Tag.
1827     fvm->set_eq_string(immediateTag);
1828     *config.add_atom_matcher() = immediateMatcher;
1829 
1830     AtomMatcher bootMatcher = CreateSimpleAtomMatcher("bootMatcher", util::WAKELOCK_STATE_CHANGED);
1831     fvm = bootMatcher.mutable_simple_atom_matcher()->add_field_value_matcher();
1832     fvm->set_field(3);  // Tag.
1833     fvm->set_eq_string(bootTag);
1834     *config.add_atom_matcher() = bootMatcher;
1835 
1836     AtomMatcher childMatcher =
1837             CreateSimpleAtomMatcher("childMatcher", util::WAKELOCK_STATE_CHANGED);
1838     fvm = childMatcher.mutable_simple_atom_matcher()->add_field_value_matcher();
1839     fvm->set_field(3);  // Tag.
1840     fvm->set_eq_string(childTag);
1841     *config.add_atom_matcher() = childMatcher;
1842 
1843     AtomMatcher acquireMatcher = CreateAcquireWakelockAtomMatcher();
1844     *config.add_atom_matcher() = acquireMatcher;
1845 
1846     AtomMatcher combinationMatcher;
1847     combinationMatcher.set_id(StringToId("combination"));
1848     AtomMatcher_Combination* combination = combinationMatcher.mutable_combination();
1849     combination->set_operation(LogicalOperation::OR);
1850     combination->add_matcher(acquireMatcher.id());
1851     combination->add_matcher(childMatcher.id());
1852     *config.add_atom_matcher() = combinationMatcher;
1853 
1854     CountMetric immediateMetric =
1855             createCountMetric("ImmediateMetric", syncStartMatcher.id(), nullopt, {});
1856     CountMetric bootMetric = createCountMetric("BootMetric", syncStartMatcher.id(), nullopt, {});
1857     CountMetric combinationMetric =
1858             createCountMetric("CombinationMetric", syncStartMatcher.id(), nullopt, {});
1859     *config.add_count_metric() = immediateMetric;
1860     *config.add_count_metric() = bootMetric;
1861     *config.add_count_metric() = combinationMetric;
1862 
1863     MetricActivation immediateMetricActivation;
1864     immediateMetricActivation.set_metric_id(immediateMetric.id());
1865     auto eventActivation = immediateMetricActivation.add_event_activation();
1866     eventActivation->set_activation_type(ActivationType::ACTIVATE_IMMEDIATELY);
1867     eventActivation->set_atom_matcher_id(immediateMatcher.id());
1868     eventActivation->set_ttl_seconds(60);  // One minute.
1869     *config.add_metric_activation() = immediateMetricActivation;
1870 
1871     MetricActivation bootMetricActivation;
1872     bootMetricActivation.set_metric_id(bootMetric.id());
1873     eventActivation = bootMetricActivation.add_event_activation();
1874     eventActivation->set_activation_type(ActivationType::ACTIVATE_ON_BOOT);
1875     eventActivation->set_atom_matcher_id(bootMatcher.id());
1876     eventActivation->set_ttl_seconds(60);  // One minute.
1877     *config.add_metric_activation() = bootMetricActivation;
1878 
1879     MetricActivation combinationMetricActivation;
1880     combinationMetricActivation.set_metric_id(combinationMetric.id());
1881     eventActivation = combinationMetricActivation.add_event_activation();
1882     eventActivation->set_activation_type(ActivationType::ACTIVATE_IMMEDIATELY);
1883     eventActivation->set_atom_matcher_id(combinationMatcher.id());
1884     eventActivation->set_ttl_seconds(60);  // One minute.
1885     *config.add_metric_activation() = combinationMetricActivation;
1886 
1887     ConfigKey key(123, 987);
1888     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
1889     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
1890     sp<StatsLogProcessor> processor =
1891             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
1892     int uid1 = 55555;
1893 
1894     // Initialize log events before update.
1895     // Counts provided in order of immediate, boot, and combination metric.
1896     std::vector<std::unique_ptr<LogEvent>> events;
1897 
1898     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 5 * NS_PER_SEC, {uid1}, {""},
1899                                           ""));  // Count: 0, 0, 0.
1900     events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC, {uid1}, {""},
1901                                                 immediateTag));  // Activate immediate metric.
1902     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 15 * NS_PER_SEC, {uid1}, {""},
1903                                           ""));  // Count: 1, 0, 0.
1904     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 20 * NS_PER_SEC, {uid1}, {""},
1905                                                 "foo"));  // Activate combination metric.
1906     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 25 * NS_PER_SEC, {uid1}, {""},
1907                                           ""));  // Count: 2, 0, 1.
1908     events.push_back(CreateReleaseWakelockEvent(bucketStartTimeNs + 30 * NS_PER_SEC, {uid1}, {""},
1909                                                 bootTag));  // Boot metric pending activation.
1910     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 35 * NS_PER_SEC, {uid1}, {""},
1911                                           ""));  // Count: 3, 0, 2.
1912     // Send log events to StatsLogProcessor.
1913     for (auto& event : events) {
1914         processor->OnLogEvent(event.get());
1915     }
1916 
1917     // Do update. Add matchers/conditions in different order to force indices to change.
1918     StatsdConfig newConfig;
1919     newConfig.add_allowed_log_source("AID_ROOT");
1920     newConfig.set_hash_strings_in_metric_report(false);  // Modify metadata for fun.
1921 
1922     // Change combination matcher, will mean combination metric isn't active after update.
1923     combinationMatcher.mutable_combination()->set_operation(LogicalOperation::AND);
1924     *newConfig.add_atom_matcher() = acquireMatcher;
1925     *newConfig.add_atom_matcher() = bootMatcher;
1926     *newConfig.add_atom_matcher() = combinationMatcher;
1927     *newConfig.add_atom_matcher() = childMatcher;
1928     *newConfig.add_atom_matcher() = syncStartMatcher;
1929     *newConfig.add_atom_matcher() = immediateMatcher;
1930 
1931     *newConfig.add_count_metric() = bootMetric;
1932     *newConfig.add_count_metric() = combinationMetric;
1933     *newConfig.add_count_metric() = immediateMetric;
1934 
1935     *newConfig.add_metric_activation() = bootMetricActivation;
1936     *newConfig.add_metric_activation() = combinationMetricActivation;
1937     *newConfig.add_metric_activation() = immediateMetricActivation;
1938 
1939     int64_t updateTimeNs = bucketStartTimeNs + 40 * NS_PER_SEC;
1940     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
1941 
1942     // The reboot will write to disk again, so sleep for 1 second to avoid this.
1943     // TODO(b/178887128): clean this up.
1944     std::this_thread::sleep_for(1000ms);
1945     // Send event after the update. Counts reset to 0 since this is a new bucket.
1946     processor->OnLogEvent(
1947             CreateSyncStartEvent(bucketStartTimeNs + 45 * NS_PER_SEC, {uid1}, {""}, "")
1948                     .get());  // Count: 1, 0, 0.
1949 
1950     // Fake a reboot. Code is from StatsService::informDeviceShutdown.
1951     int64_t shutDownTimeNs = bucketStartTimeNs + 50 * NS_PER_SEC;
1952     processor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST, shutDownTimeNs, getWallClockNs());
1953     processor->SaveActiveConfigsToDisk(shutDownTimeNs);
1954     processor->SaveMetadataToDisk(getWallClockNs(), shutDownTimeNs);
1955 
1956     // On boot, use StartUp. However, skip config manager for simplicity.
1957     int64_t bootTimeNs = bucketStartTimeNs + 55 * NS_PER_SEC;
1958     processor = CreateStatsLogProcessor(bootTimeNs, bootTimeNs, newConfig, key);
1959     processor->LoadActiveConfigsFromDisk();
1960     processor->LoadMetadataFromDisk(getWallClockNs(), bootTimeNs);
1961 
1962     // Send events after boot. Counts reset to 0 since this is a new bucket. Boot metric now active.
1963     events.clear();
1964     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 60 * NS_PER_SEC, {uid1}, {""},
1965                                           ""));  // Count: 1, 1, 0.
1966     int64_t deactivationTimeNs = bucketStartTimeNs + 76 * NS_PER_SEC;
1967     events.push_back(CreateScreenStateChangedEvent(
1968             deactivationTimeNs,
1969             android::view::DisplayStateEnum::DISPLAY_STATE_OFF));  // TTLs immediate metric.
1970     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 80 * NS_PER_SEC, {uid1}, {""},
1971                                           ""));  // Count: 1, 2, 0.
1972     events.push_back(CreateAcquireWakelockEvent(bucketStartTimeNs + 85 * NS_PER_SEC, {uid1}, {""},
1973                                                 childTag));  // Activate combination metric.
1974     events.push_back(CreateSyncStartEvent(bucketStartTimeNs + 90 * NS_PER_SEC, {uid1}, {""},
1975                                           ""));  // Count: 1, 3, 1.
1976 
1977     // Send log events to StatsLogProcessor.
1978     for (auto& event : events) {
1979         processor->OnLogEvent(event.get());
1980     }
1981     uint64_t dumpTimeNs = bucketStartTimeNs + 90 * NS_PER_SEC;
1982     ConfigMetricsReportList reports;
1983     vector<uint8_t> buffer;
1984     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
1985     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
1986     sortReportsByElapsedTime(&reports);
1987     backfillDimensionPath(&reports);
1988     backfillStringInReport(&reports);
1989     backfillStartEndTimestamp(&reports);
1990     ASSERT_EQ(reports.reports_size(), 3);
1991 
1992     // Report from before update.
1993     ConfigMetricsReport report = reports.reports(0);
1994     EXPECT_EQ(report.last_report_elapsed_nanos(), bucketStartTimeNs);
1995     EXPECT_EQ(report.current_report_elapsed_nanos(), updateTimeNs);
1996     ASSERT_EQ(report.metrics_size(), 3);
1997     // Immediate metric. Count = 3.
1998     StatsLogReport metricReport = report.metrics(0);
1999     EXPECT_EQ(metricReport.metric_id(), immediateMetric.id());
2000     EXPECT_TRUE(metricReport.is_active());
2001     EXPECT_TRUE(metricReport.has_count_metrics());
2002 
2003     // Boot metric. Count = 0.
2004     metricReport = report.metrics(1);
2005     EXPECT_EQ(metricReport.metric_id(), bootMetric.id());
2006     EXPECT_FALSE(metricReport.is_active());
2007     EXPECT_FALSE(metricReport.has_count_metrics());
2008 
2009     // Combination metric. Count = 2.
2010     metricReport = report.metrics(2);
2011     EXPECT_EQ(metricReport.metric_id(), combinationMetric.id());
2012     EXPECT_TRUE(metricReport.is_active());
2013     EXPECT_TRUE(metricReport.has_count_metrics());
2014 
2015     // Report from after update, before boot.
2016     report = reports.reports(1);
2017     EXPECT_EQ(report.last_report_elapsed_nanos(), updateTimeNs);
2018     EXPECT_EQ(report.current_report_elapsed_nanos(), shutDownTimeNs);
2019     ASSERT_EQ(report.metrics_size(), 3);
2020     // Boot metric. Count = 0.
2021     metricReport = report.metrics(0);
2022     EXPECT_EQ(metricReport.metric_id(), bootMetric.id());
2023     EXPECT_FALSE(metricReport.is_active());
2024     EXPECT_FALSE(metricReport.has_count_metrics());
2025 
2026     // Combination metric. Count = 0.
2027     metricReport = report.metrics(1);
2028     EXPECT_EQ(metricReport.metric_id(), combinationMetric.id());
2029     EXPECT_FALSE(metricReport.is_active());
2030     EXPECT_FALSE(metricReport.has_count_metrics());
2031 
2032     // Immediate metric. Count = 1.
2033     metricReport = report.metrics(2);
2034     EXPECT_EQ(metricReport.metric_id(), immediateMetric.id());
2035     EXPECT_TRUE(metricReport.is_active());
2036     EXPECT_TRUE(metricReport.has_count_metrics());
2037 
2038     // Report from after reboot.
2039     report = reports.reports(2);
2040     EXPECT_EQ(report.last_report_elapsed_nanos(), bootTimeNs);
2041     EXPECT_EQ(report.current_report_elapsed_nanos(), dumpTimeNs);
2042     ASSERT_EQ(report.metrics_size(), 3);
2043     // Boot metric. Count = 3.
2044     metricReport = report.metrics(0);
2045     EXPECT_EQ(metricReport.metric_id(), bootMetric.id());
2046     EXPECT_TRUE(metricReport.is_active());
2047     EXPECT_TRUE(metricReport.has_count_metrics());
2048 
2049     // Combination metric. Count = 1.
2050     metricReport = report.metrics(1);
2051     EXPECT_EQ(metricReport.metric_id(), combinationMetric.id());
2052     EXPECT_TRUE(metricReport.is_active());
2053     EXPECT_TRUE(metricReport.has_count_metrics());
2054 
2055     // Immediate metric. Count = 1.
2056     metricReport = report.metrics(2);
2057     EXPECT_EQ(metricReport.metric_id(), immediateMetric.id());
2058     EXPECT_FALSE(metricReport.is_active());
2059     EXPECT_TRUE(metricReport.has_count_metrics());
2060     ALOGE("End ConfigUpdateE2eTest#TestMetricActivation");
2061 }
2062 
TEST_F(ConfigUpdateE2eTest,TestAnomalyCountMetric)2063 TEST_F(ConfigUpdateE2eTest, TestAnomalyCountMetric) {
2064     StatsdConfig config;
2065     config.add_allowed_log_source("AID_ROOT");
2066 
2067     AtomMatcher syncStartMatcher = CreateSyncStartAtomMatcher();
2068     *config.add_atom_matcher() = syncStartMatcher;
2069     AtomMatcher wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
2070     *config.add_atom_matcher() = wakelockAcquireMatcher;
2071 
2072     CountMetric countWakelock =
2073             createCountMetric("CountWakelock", wakelockAcquireMatcher.id(), nullopt, {});
2074     *countWakelock.mutable_dimensions_in_what() =
2075             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2076 
2077     CountMetric countSync = createCountMetric("CountSync", syncStartMatcher.id(), nullopt, {});
2078     *countSync.mutable_dimensions_in_what() =
2079             CreateAttributionUidDimensions(util::SYNC_STATE_CHANGED, {Position::FIRST});
2080 
2081     *config.add_count_metric() = countWakelock;
2082     *config.add_count_metric() = countSync;
2083 
2084     Alert alertPreserve =
2085             createAlert("AlertPreserve", countWakelock.id(), /*buckets=*/2, /*triggerSumGt=*/1);
2086     alertPreserve.set_refractory_period_secs(20);
2087     Alert alertReplace = createAlert("AlertReplace", countSync.id(), 1, 1);
2088     alertReplace.set_refractory_period_secs(1);
2089     Alert alertRemove = createAlert("AlertRemove", countWakelock.id(), 1, 0);
2090     alertRemove.set_refractory_period_secs(1);
2091     *config.add_alert() = alertReplace;
2092     *config.add_alert() = alertPreserve;
2093     *config.add_alert() = alertRemove;
2094 
2095     int preserveSubId = 1, replaceSubId = 2, removeSubId = 3;
2096     Subscription preserveSub = createSubscription("S1", Subscription::ALERT, alertPreserve.id());
2097     preserveSub.mutable_broadcast_subscriber_details()->set_subscriber_id(preserveSubId);
2098     Subscription replaceSub = createSubscription("S2", Subscription::ALERT, alertReplace.id());
2099     replaceSub.mutable_broadcast_subscriber_details()->set_subscriber_id(replaceSubId);
2100     Subscription removeSub = createSubscription("S3", Subscription::ALERT, alertRemove.id());
2101     removeSub.mutable_broadcast_subscriber_details()->set_subscriber_id(removeSubId);
2102     *config.add_subscription() = preserveSub;
2103     *config.add_subscription() = removeSub;
2104     *config.add_subscription() = replaceSub;
2105 
2106     int app1Uid = 123, app2Uid = 456;
2107     vector<int> attributionUids1 = {app1Uid};
2108     vector<string> attributionTags1 = {"App1"};
2109     vector<int> attributionUids2 = {app2Uid};
2110     vector<string> attributionTags2 = {"App2"};
2111     int64_t configUid = 123, configId = 987;
2112     ConfigKey key(configUid, configId);
2113 
2114     int alertPreserveCount = 0, alertRemoveCount = 0;
2115     StatsDimensionsValueParcel alertPreserveDims;
2116     StatsDimensionsValueParcel alertRemoveDims;
2117 
2118     // The binder calls here will happen synchronously because they are in-process.
2119     shared_ptr<MockPendingIntentRef> preserveBroadcast =
2120             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2121     EXPECT_CALL(*preserveBroadcast, sendSubscriberBroadcast(configUid, configId, preserveSub.id(),
2122                                                             alertPreserve.id(), _, _))
2123             .Times(2)
2124             .WillRepeatedly(
2125                     Invoke([&alertPreserveCount, &alertPreserveDims](
2126                                    int64_t, int64_t, int64_t, int64_t, const vector<string>&,
2127                                    const StatsDimensionsValueParcel& dimensionsValueParcel) {
2128                         alertPreserveCount++;
2129                         alertPreserveDims = dimensionsValueParcel;
2130                         return Status::ok();
2131                     }));
2132 
2133     shared_ptr<MockPendingIntentRef> replaceBroadcast =
2134             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2135     EXPECT_CALL(*replaceBroadcast, sendSubscriberBroadcast(configUid, configId, replaceSub.id(),
2136                                                            alertReplace.id(), _, _))
2137             .Times(0);
2138 
2139     shared_ptr<MockPendingIntentRef> removeBroadcast =
2140             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2141     EXPECT_CALL(*removeBroadcast, sendSubscriberBroadcast(configUid, configId, removeSub.id(),
2142                                                           alertRemove.id(), _, _))
2143             .Times(3)
2144             .WillRepeatedly(
2145                     Invoke([&alertRemoveCount, &alertRemoveDims](
2146                                    int64_t, int64_t, int64_t, int64_t, const vector<string>&,
2147                                    const StatsDimensionsValueParcel& dimensionsValueParcel) {
2148                         alertRemoveCount++;
2149                         alertRemoveDims = dimensionsValueParcel;
2150                         return Status::ok();
2151                     }));
2152 
2153     SubscriberReporter::getInstance().setBroadcastSubscriber(key, preserveSubId, preserveBroadcast);
2154     SubscriberReporter::getInstance().setBroadcastSubscriber(key, replaceSubId, replaceBroadcast);
2155     SubscriberReporter::getInstance().setBroadcastSubscriber(key, removeSubId, removeBroadcast);
2156 
2157     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
2158     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
2159     uint64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
2160     sp<StatsLogProcessor> processor =
2161             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
2162 
2163     StatsDimensionsValueParcel wlUid1 =
2164             CreateAttributionUidDimensionsValueParcel(util::WAKELOCK_STATE_CHANGED, app1Uid);
2165     StatsDimensionsValueParcel wlUid2 =
2166             CreateAttributionUidDimensionsValueParcel(util::WAKELOCK_STATE_CHANGED, app2Uid);
2167 
2168     processor->OnLogEvent(CreateAcquireWakelockEvent(bucketStartTimeNs + 15 * NS_PER_SEC,
2169                                                      attributionUids1, attributionTags1, "wl1")
2170                                   .get());
2171     EXPECT_EQ(alertPreserveCount, 0);
2172     EXPECT_EQ(alertRemoveCount, 1);
2173     EXPECT_EQ(alertRemoveDims, wlUid1);
2174 
2175     processor->OnLogEvent(CreateAcquireWakelockEvent(bucketStartTimeNs + 20 * NS_PER_SEC,
2176                                                      attributionUids2, attributionTags2, "wl2")
2177                                   .get());
2178     EXPECT_EQ(alertPreserveCount, 0);
2179     EXPECT_EQ(alertRemoveCount, 2);
2180     EXPECT_EQ(alertRemoveDims, wlUid2);
2181 
2182     processor->OnLogEvent(CreateSyncStartEvent(bucket2StartTimeNs + 5 * NS_PER_SEC,
2183                                                attributionUids1, attributionTags1, "sync1")
2184                                   .get());
2185     EXPECT_EQ(alertPreserveCount, 0);
2186     EXPECT_EQ(alertRemoveCount, 2);
2187 
2188     // AlertPreserve enters 30 sec refractory period for uid2.
2189     processor->OnLogEvent(CreateAcquireWakelockEvent(bucket2StartTimeNs + 10 * NS_PER_SEC,
2190                                                      attributionUids2, attributionTags2, "wl2")
2191                                   .get());
2192     EXPECT_EQ(alertPreserveCount, 1);
2193     EXPECT_EQ(alertPreserveDims, wlUid2);
2194     EXPECT_EQ(alertRemoveCount, 3);
2195     EXPECT_EQ(alertRemoveDims, wlUid2);
2196 
2197     // Do config update.
2198     StatsdConfig newConfig;
2199     newConfig.add_allowed_log_source("AID_ROOT");
2200     *newConfig.add_atom_matcher() = wakelockAcquireMatcher;
2201     *newConfig.add_atom_matcher() = syncStartMatcher;
2202 
2203     // Clear dims of sync metric, will result in alertReplace getting replaced.
2204     countSync.clear_dimensions_in_what();
2205     *newConfig.add_count_metric() = countSync;
2206     *newConfig.add_count_metric() = countWakelock;
2207 
2208     // New alert on existing metric. Should get current full bucket, but not history of 1st bucket.
2209     Alert alertNew = createAlert("AlertNew", countWakelock.id(), /*buckets=*/1, /*triggerSumGt=*/1);
2210     *newConfig.add_alert() = alertPreserve;
2211     *newConfig.add_alert() = alertNew;
2212     *newConfig.add_alert() = alertReplace;
2213 
2214     int newSubId = 4;
2215     Subscription newSub = createSubscription("S4", Subscription::ALERT, alertNew.id());
2216     newSub.mutable_broadcast_subscriber_details()->set_subscriber_id(newSubId);
2217     *newConfig.add_subscription() = newSub;
2218     *newConfig.add_subscription() = replaceSub;
2219     *newConfig.add_subscription() = preserveSub;
2220 
2221     int alertNewCount = 0;
2222     StatsDimensionsValueParcel alertNewDims;
2223     shared_ptr<MockPendingIntentRef> newBroadcast =
2224             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2225     EXPECT_CALL(*newBroadcast,
2226                 sendSubscriberBroadcast(configUid, configId, newSub.id(), alertNew.id(), _, _))
2227             .Times(1)
2228             .WillRepeatedly(
2229                     Invoke([&alertNewCount, &alertNewDims](
2230                                    int64_t, int64_t, int64_t, int64_t, const vector<string>&,
2231                                    const StatsDimensionsValueParcel& dimensionsValueParcel) {
2232                         alertNewCount++;
2233                         alertNewDims = dimensionsValueParcel;
2234                         return Status::ok();
2235                     }));
2236     SubscriberReporter::getInstance().setBroadcastSubscriber(key, newSubId, newBroadcast);
2237 
2238     int64_t updateTimeNs = bucket2StartTimeNs + 15 * NS_PER_SEC;
2239     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
2240 
2241     // Within refractory of AlertPreserve, but AlertNew should fire since the full bucket has 2.
2242     processor->OnLogEvent(CreateAcquireWakelockEvent(bucket2StartTimeNs + 20 * NS_PER_SEC,
2243                                                      attributionUids2, attributionTags2, "wl2")
2244                                   .get());
2245     EXPECT_EQ(alertPreserveCount, 1);
2246     EXPECT_EQ(alertNewCount, 1);
2247     EXPECT_EQ(alertNewDims, wlUid2);
2248 
2249     // Wakelock for uid1 fired in first bucket, alert preserve should keep the history and fire.
2250     processor->OnLogEvent(CreateAcquireWakelockEvent(bucket2StartTimeNs + 25 * NS_PER_SEC,
2251                                                      attributionUids1, attributionTags1, "wl1")
2252                                   .get());
2253     EXPECT_EQ(alertPreserveCount, 2);
2254     EXPECT_EQ(alertPreserveDims, wlUid1);
2255     EXPECT_EQ(alertNewCount, 1);
2256 
2257     processor->OnLogEvent(CreateSyncStartEvent(bucket2StartTimeNs + 30 * NS_PER_SEC,
2258                                                attributionUids1, attributionTags1, "sync1")
2259                                   .get());
2260     EXPECT_EQ(alertPreserveCount, 2);
2261     EXPECT_EQ(alertNewCount, 1);
2262     EXPECT_EQ(alertRemoveCount, 3);
2263 
2264     // Clear data so it doesn't stay on disk.
2265     vector<uint8_t> buffer;
2266     processor->onDumpReport(key, bucket2StartTimeNs + 100 * NS_PER_SEC, true, true, ADB_DUMP, FAST,
2267                             &buffer);
2268     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, preserveSubId);
2269     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, replaceSubId);
2270     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, removeSubId);
2271     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, newSubId);
2272 }
2273 
TEST_F(ConfigUpdateE2eTest,TestAnomalyDurationMetric)2274 TEST_F(ConfigUpdateE2eTest, TestAnomalyDurationMetric) {
2275     StatsdConfig config;
2276     config.add_allowed_log_source("AID_ROOT");
2277 
2278     AtomMatcher wakelockAcquireMatcher = CreateAcquireWakelockAtomMatcher();
2279     *config.add_atom_matcher() = wakelockAcquireMatcher;
2280     AtomMatcher wakelockReleaseMatcher = CreateReleaseWakelockAtomMatcher();
2281     *config.add_atom_matcher() = wakelockReleaseMatcher;
2282     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
2283     *config.add_atom_matcher() = screenOnMatcher;
2284     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
2285     *config.add_atom_matcher() = screenOffMatcher;
2286 
2287     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
2288     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
2289             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2290     *config.add_predicate() = holdingWakelockPredicate;
2291     Predicate screenOnPredicate = CreateScreenIsOnPredicate();
2292     *config.add_predicate() = screenOnPredicate;
2293 
2294     DurationMetric durationWakelock =
2295             createDurationMetric("DurWakelock", holdingWakelockPredicate.id(), nullopt, {});
2296     *durationWakelock.mutable_dimensions_in_what() =
2297             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2298     DurationMetric durationScreen =
2299             createDurationMetric("DurScreen", screenOnPredicate.id(), nullopt, {});
2300     *config.add_duration_metric() = durationScreen;
2301     *config.add_duration_metric() = durationWakelock;
2302 
2303     Alert alertPreserve = createAlert("AlertPreserve", durationWakelock.id(), /*buckets=*/2,
2304                                       /*triggerSumGt=*/30 * NS_PER_SEC);
2305     alertPreserve.set_refractory_period_secs(300);
2306     Alert alertReplace = createAlert("AlertReplace", durationScreen.id(), 2, 30 * NS_PER_SEC);
2307     alertReplace.set_refractory_period_secs(1);
2308     Alert alertRemove = createAlert("AlertRemove", durationWakelock.id(), 5, 10 * NS_PER_SEC);
2309     alertRemove.set_refractory_period_secs(1);
2310     *config.add_alert() = alertReplace;
2311     *config.add_alert() = alertPreserve;
2312     *config.add_alert() = alertRemove;
2313 
2314     int preserveSubId = 1, replaceSubId = 2, removeSubId = 3;
2315     Subscription preserveSub = createSubscription("S1", Subscription::ALERT, alertPreserve.id());
2316     preserveSub.mutable_broadcast_subscriber_details()->set_subscriber_id(preserveSubId);
2317     Subscription replaceSub = createSubscription("S2", Subscription::ALERT, alertReplace.id());
2318     replaceSub.mutable_broadcast_subscriber_details()->set_subscriber_id(replaceSubId);
2319     Subscription removeSub = createSubscription("S3", Subscription::ALERT, alertRemove.id());
2320     removeSub.mutable_broadcast_subscriber_details()->set_subscriber_id(removeSubId);
2321     *config.add_subscription() = preserveSub;
2322     *config.add_subscription() = removeSub;
2323     *config.add_subscription() = replaceSub;
2324 
2325     int app1Uid = 123, app2Uid = 456, app3Uid = 789, app4Uid = 111;
2326     vector<int> attributionUids1 = {app1Uid}, attributionUids2 = {app2Uid},
2327                 attributionUids3 = {app3Uid}, attributionUids4 = {app4Uid};
2328     vector<string> attributionTags1 = {"App1"}, attributionTags2 = {"App2"},
2329                    attributionTags3 = {"App3"}, attributionTags4 = {"App4"};
2330 
2331     int64_t configUid = 123, configId = 987;
2332     ConfigKey key(configUid, configId);
2333 
2334     int alertPreserveCount = 0, alertRemoveCount = 0;
2335     StatsDimensionsValueParcel alertPreserveDims;
2336     StatsDimensionsValueParcel alertRemoveDims;
2337 
2338     // The binder calls here will happen synchronously because they are in-process.
2339     shared_ptr<MockPendingIntentRef> preserveBroadcast =
2340             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2341     EXPECT_CALL(*preserveBroadcast, sendSubscriberBroadcast(configUid, configId, preserveSub.id(),
2342                                                             alertPreserve.id(), _, _))
2343             .Times(4)
2344             .WillRepeatedly(
2345                     Invoke([&alertPreserveCount, &alertPreserveDims](
2346                                    int64_t, int64_t, int64_t, int64_t, const vector<string>&,
2347                                    const StatsDimensionsValueParcel& dimensionsValueParcel) {
2348                         alertPreserveCount++;
2349                         alertPreserveDims = dimensionsValueParcel;
2350                         return Status::ok();
2351                     }));
2352 
2353     shared_ptr<MockPendingIntentRef> replaceBroadcast =
2354             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2355     EXPECT_CALL(*replaceBroadcast, sendSubscriberBroadcast(configUid, configId, replaceSub.id(),
2356                                                            alertReplace.id(), _, _))
2357             .Times(0);
2358 
2359     shared_ptr<MockPendingIntentRef> removeBroadcast =
2360             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2361     EXPECT_CALL(*removeBroadcast, sendSubscriberBroadcast(configUid, configId, removeSub.id(),
2362                                                           alertRemove.id(), _, _))
2363             .Times(6)
2364             .WillRepeatedly(
2365                     Invoke([&alertRemoveCount, &alertRemoveDims](
2366                                    int64_t, int64_t, int64_t, int64_t, const vector<string>&,
2367                                    const StatsDimensionsValueParcel& dimensionsValueParcel) {
2368                         alertRemoveCount++;
2369                         alertRemoveDims = dimensionsValueParcel;
2370                         return Status::ok();
2371                     }));
2372 
2373     SubscriberReporter::getInstance().setBroadcastSubscriber(key, preserveSubId, preserveBroadcast);
2374     SubscriberReporter::getInstance().setBroadcastSubscriber(key, replaceSubId, replaceBroadcast);
2375     SubscriberReporter::getInstance().setBroadcastSubscriber(key, removeSubId, removeBroadcast);
2376 
2377     shared_ptr<StatsService> service = SharedRefBase::make<StatsService>(nullptr, nullptr);
2378     sp<StatsLogProcessor> processor = service->mProcessor;
2379     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(TEN_MINUTES) * 1000000LL;
2380     int64_t bucketStartTimeNs = processor->mTimeBaseNs;
2381     int64_t roundedBucketStartTimeNs = bucketStartTimeNs / NS_PER_SEC * NS_PER_SEC;
2382     uint64_t bucket2StartTimeNs = bucketStartTimeNs + bucketSizeNs;
2383     processor->OnConfigUpdated(bucketStartTimeNs, key, config);
2384 
2385     StatsDimensionsValueParcel wlUid1 =
2386             CreateAttributionUidDimensionsValueParcel(util::WAKELOCK_STATE_CHANGED, app1Uid);
2387     StatsDimensionsValueParcel wlUid2 =
2388             CreateAttributionUidDimensionsValueParcel(util::WAKELOCK_STATE_CHANGED, app2Uid);
2389     StatsDimensionsValueParcel wlUid3 =
2390             CreateAttributionUidDimensionsValueParcel(util::WAKELOCK_STATE_CHANGED, app3Uid);
2391     StatsDimensionsValueParcel wlUid4 =
2392             CreateAttributionUidDimensionsValueParcel(util::WAKELOCK_STATE_CHANGED, app4Uid);
2393 
2394     int64_t eventTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
2395     processor->OnLogEvent(
2396             CreateAcquireWakelockEvent(eventTimeNs, attributionUids1, attributionTags1, "wl1")
2397                     .get(),
2398             eventTimeNs);
2399     EXPECT_EQ(alertPreserveCount, 0);
2400     EXPECT_EQ(alertRemoveCount, 0);
2401 
2402     eventTimeNs = bucketStartTimeNs + 20 * NS_PER_SEC;
2403     processor->OnLogEvent(CreateScreenStateChangedEvent(
2404                                   eventTimeNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON)
2405                                   .get(),
2406                           eventTimeNs);
2407     EXPECT_EQ(alertPreserveCount, 0);
2408     EXPECT_EQ(alertRemoveCount, 0);
2409 
2410     // Uid 1 accumulates 15 seconds in bucket #1.
2411     eventTimeNs = bucketStartTimeNs + 30 * NS_PER_SEC;
2412     processor->OnLogEvent(
2413             CreateReleaseWakelockEvent(eventTimeNs, attributionUids1, attributionTags1, "wl1")
2414                     .get(),
2415             eventTimeNs);
2416     EXPECT_EQ(alertPreserveCount, 0);
2417     EXPECT_EQ(alertRemoveCount, 1);
2418     EXPECT_EQ(alertRemoveDims, wlUid1);
2419 
2420     // 20 seconds accumulated in bucket #1.
2421     eventTimeNs = bucketStartTimeNs + 40 * NS_PER_SEC;
2422     processor->OnLogEvent(CreateScreenStateChangedEvent(
2423                                   eventTimeNs, android::view::DisplayStateEnum::DISPLAY_STATE_OFF)
2424                                   .get(),
2425                           eventTimeNs);
2426     EXPECT_EQ(alertPreserveCount, 0);
2427     EXPECT_EQ(alertRemoveCount, 1);
2428 
2429     eventTimeNs = bucket2StartTimeNs + 2 * NS_PER_SEC;
2430     processor->OnLogEvent(
2431             CreateAcquireWakelockEvent(eventTimeNs, attributionUids4, attributionTags4, "wl4")
2432                     .get(),
2433             eventTimeNs);
2434     EXPECT_EQ(alertPreserveCount, 0);
2435     EXPECT_EQ(alertRemoveCount, 1);
2436 
2437     eventTimeNs = bucket2StartTimeNs + 5 * NS_PER_SEC;
2438     processor->OnLogEvent(
2439             CreateAcquireWakelockEvent(eventTimeNs, attributionUids2, attributionTags2, "wl2")
2440                     .get(),
2441             eventTimeNs);
2442     EXPECT_EQ(alertPreserveCount, 0);
2443     EXPECT_EQ(alertRemoveCount, 1);
2444 
2445     // Alarm for alert remove for uid 4.
2446     eventTimeNs = bucket2StartTimeNs + 13 * NS_PER_SEC;
2447     processor->OnLogEvent(CreateBatteryStateChangedEvent(
2448                                   eventTimeNs, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB)
2449                                   .get(),
2450                           eventTimeNs);
2451     EXPECT_EQ(alertPreserveCount, 0);
2452     EXPECT_EQ(alertRemoveCount, 2);
2453     EXPECT_EQ(alertRemoveDims, wlUid4);
2454 
2455     // Uid3 will be pending at the update.
2456     // Also acts as the alarm for alert remove for uid 2.
2457     eventTimeNs = bucket2StartTimeNs + 30 * NS_PER_SEC;
2458     processor->OnLogEvent(
2459             CreateAcquireWakelockEvent(eventTimeNs, attributionUids3, attributionTags3, "wl3")
2460                     .get(),
2461             eventTimeNs);
2462     EXPECT_EQ(alertPreserveCount, 0);
2463     EXPECT_EQ(alertRemoveCount, 3);
2464     EXPECT_EQ(alertRemoveDims, wlUid2);
2465 
2466     // Alarm for alert preserve for uid 4, enters 5 min refractory period.
2467     eventTimeNs = bucket2StartTimeNs + 33 * NS_PER_SEC;
2468     processor->OnLogEvent(CreateBatteryStateChangedEvent(
2469                                   eventTimeNs, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB)
2470                                   .get(),
2471                           eventTimeNs);
2472     EXPECT_EQ(alertPreserveCount, 1);
2473     EXPECT_EQ(alertPreserveDims, wlUid4);
2474     EXPECT_EQ(alertRemoveCount, 3);
2475 
2476     // Uid 2 accumulates 32 seconds in partial bucket before the update. Alert preserve fires.
2477     // Preserve enters 5 min refractory for uid 2.
2478     // Alert remove fires again for uid 2 since the refractory has expired.
2479     eventTimeNs = bucket2StartTimeNs + 37 * NS_PER_SEC;
2480     processor->OnLogEvent(
2481             CreateReleaseWakelockEvent(eventTimeNs, attributionUids2, attributionTags2, "wl2")
2482                     .get(),
2483             eventTimeNs);
2484     EXPECT_EQ(alertPreserveCount, 2);
2485     EXPECT_EQ(alertPreserveDims, wlUid2);
2486     EXPECT_EQ(alertRemoveCount, 4);
2487     EXPECT_EQ(alertRemoveDims, wlUid2);
2488 
2489     // Alarm for alert remove for uid 3.
2490     eventTimeNs = bucket2StartTimeNs + 41 * NS_PER_SEC;
2491     processor->OnLogEvent(CreateBatteryStateChangedEvent(
2492                                   eventTimeNs, BatteryPluggedStateEnum::BATTERY_PLUGGED_USB)
2493                                   .get(),
2494                           eventTimeNs);
2495     EXPECT_EQ(alertPreserveCount, 2);
2496     EXPECT_EQ(alertRemoveCount, 5);
2497     EXPECT_EQ(alertRemoveDims, wlUid3);
2498 
2499     // Release wl for uid 4, has accumulated 41 seconds in partial bucket before update.
2500     // Acts as alarm for uid3 of alert remove.
2501     eventTimeNs = bucket2StartTimeNs + 43 * NS_PER_SEC;
2502     processor->OnLogEvent(
2503             CreateReleaseWakelockEvent(eventTimeNs, attributionUids4, attributionTags4, "wl4")
2504                     .get(),
2505             eventTimeNs);
2506     EXPECT_EQ(alertPreserveCount, 2);
2507     EXPECT_EQ(alertRemoveCount, 6);
2508     EXPECT_EQ(alertRemoveDims, wlUid4);
2509 
2510     // Starts the timer for screen on.
2511     eventTimeNs = bucket2StartTimeNs + 46 * NS_PER_SEC;
2512     processor->OnLogEvent(CreateScreenStateChangedEvent(
2513                                   eventTimeNs, android::view::DisplayStateEnum::DISPLAY_STATE_ON)
2514                                   .get(),
2515                           eventTimeNs);
2516     EXPECT_EQ(alertPreserveCount, 2);
2517     EXPECT_EQ(alertRemoveCount, 6);
2518 
2519     // Do config update.
2520     StatsdConfig newConfig;
2521     newConfig.add_allowed_log_source("AID_ROOT");
2522     *newConfig.add_atom_matcher() = wakelockAcquireMatcher;
2523     *newConfig.add_atom_matcher() = screenOffMatcher;
2524     *newConfig.add_atom_matcher() = wakelockReleaseMatcher;
2525     *newConfig.add_atom_matcher() = screenOnMatcher;
2526     *newConfig.add_predicate() = screenOnPredicate;
2527     *newConfig.add_predicate() = holdingWakelockPredicate;
2528     *newConfig.add_duration_metric() = durationWakelock;
2529     *newConfig.add_duration_metric() = durationScreen;
2530 
2531     alertReplace.set_refractory_period_secs(2);  // Causes replacement.
2532     // New alert on existing metric. Should get current full bucket, but not history of 1st bucket.
2533     Alert alertNew = createAlert("AlertNew", durationWakelock.id(), /*buckets=*/2,
2534                                  /*triggerSumGt=*/40 * NS_PER_SEC);
2535     *newConfig.add_alert() = alertPreserve;
2536     *newConfig.add_alert() = alertNew;
2537     *newConfig.add_alert() = alertReplace;
2538 
2539     int newSubId = 4;
2540     Subscription newSub = createSubscription("S4", Subscription::ALERT, alertNew.id());
2541     newSub.mutable_broadcast_subscriber_details()->set_subscriber_id(newSubId);
2542     *newConfig.add_subscription() = newSub;
2543     *newConfig.add_subscription() = replaceSub;
2544     *newConfig.add_subscription() = preserveSub;
2545 
2546     int alertNewCount = 0;
2547     StatsDimensionsValueParcel alertNewDims;
2548     shared_ptr<MockPendingIntentRef> newBroadcast =
2549             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2550     EXPECT_CALL(*newBroadcast,
2551                 sendSubscriberBroadcast(configUid, configId, newSub.id(), alertNew.id(), _, _))
2552             .Times(3)
2553             .WillRepeatedly(
2554                     Invoke([&alertNewCount, &alertNewDims](
2555                                    int64_t, int64_t, int64_t, int64_t, const vector<string>&,
2556                                    const StatsDimensionsValueParcel& dimensionsValueParcel) {
2557                         alertNewCount++;
2558                         alertNewDims = dimensionsValueParcel;
2559                         return Status::ok();
2560                     }));
2561     SubscriberReporter::getInstance().setBroadcastSubscriber(key, newSubId, newBroadcast);
2562 
2563     int64_t updateTimeNs = bucket2StartTimeNs + 50 * NS_PER_SEC;
2564     processor->OnConfigUpdated(updateTimeNs, key, newConfig);
2565 
2566     // Alert preserve will set alarm after the refractory period, but alert new will set it for
2567     // 8 seconds after this event.
2568     // Alert new should fire for uid 4, since it has already accumulated 41s and should fire on the
2569     // first event after the update.
2570     eventTimeNs = bucket2StartTimeNs + 55 * NS_PER_SEC;
2571     processor->OnLogEvent(
2572             CreateAcquireWakelockEvent(eventTimeNs, attributionUids2, attributionTags2, "wl2")
2573                     .get(),
2574             eventTimeNs);
2575     EXPECT_EQ(alertPreserveCount, 2);
2576     EXPECT_EQ(alertNewCount, 1);
2577     EXPECT_EQ(alertNewDims, wlUid4);
2578 
2579     eventTimeNs = bucket2StartTimeNs + 60 * NS_PER_SEC;
2580     // Alert replace doesn't fire because it has lost history.
2581     processor->OnLogEvent(CreateScreenStateChangedEvent(
2582                                   eventTimeNs, android::view::DisplayStateEnum::DISPLAY_STATE_OFF)
2583                                   .get(),
2584                           eventTimeNs);
2585     EXPECT_EQ(alertPreserveCount, 2);
2586     EXPECT_EQ(alertNewCount, 1);
2587 
2588     // Alert preserve has 15 seconds from 1st bucket, so alert should fire at bucket2Start + 80.
2589     // Serves as alarm for alert new for uid2.
2590     // Also serves as alarm for alert preserve for uid 3, which began at bucket2Start + 30.
2591     eventTimeNs = bucket2StartTimeNs + 65 * NS_PER_SEC;
2592     processor->OnLogEvent(
2593             CreateAcquireWakelockEvent(eventTimeNs, attributionUids1, attributionTags1, "wl1")
2594                     .get(),
2595             eventTimeNs);
2596     EXPECT_EQ(alertPreserveCount, 3);
2597     EXPECT_EQ(alertPreserveDims, wlUid3);
2598     EXPECT_EQ(alertNewCount, 2);
2599     EXPECT_EQ(alertNewDims, wlUid2);
2600 
2601     // Release wakelock for uid1, causing alert preserve to fire for uid1.
2602     // Also serves as alarm for alert new for uid3.
2603     eventTimeNs = bucket2StartTimeNs + 81 * NS_PER_SEC;
2604     processor->OnLogEvent(
2605             CreateReleaseWakelockEvent(eventTimeNs, attributionUids1, attributionTags1, "wl1")
2606                     .get(),
2607             eventTimeNs);
2608     EXPECT_EQ(alertPreserveCount, 4);
2609     EXPECT_EQ(alertPreserveDims, wlUid1);
2610     EXPECT_EQ(alertNewCount, 3);
2611     EXPECT_EQ(alertNewDims, wlUid3);
2612 
2613     // Clear data so it doesn't stay on disk.
2614     vector<uint8_t> buffer;
2615     processor->onDumpReport(key, bucket2StartTimeNs + 100 * NS_PER_SEC, true, true, ADB_DUMP, FAST,
2616                             &buffer);
2617     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, preserveSubId);
2618     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, replaceSubId);
2619     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, removeSubId);
2620     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, newSubId);
2621 }
2622 
TEST_F(ConfigUpdateE2eTest,TestAlarms)2623 TEST_F(ConfigUpdateE2eTest, TestAlarms) {
2624     StatsdConfig config;
2625     config.add_allowed_log_source("AID_ROOT");
2626     Alarm alarmPreserve = createAlarm("AlarmPreserve", /*offset*/ 5 * MS_PER_SEC,
2627                                       /*period*/ TimeUnitToBucketSizeInMillis(ONE_MINUTE));
2628     Alarm alarmReplace = createAlarm("AlarmReplace", /*offset*/ 1,
2629                                      /*period*/ TimeUnitToBucketSizeInMillis(FIVE_MINUTES));
2630     Alarm alarmRemove = createAlarm("AlarmRemove", /*offset*/ 1,
2631                                     /*period*/ TimeUnitToBucketSizeInMillis(ONE_MINUTE));
2632     *config.add_alarm() = alarmReplace;
2633     *config.add_alarm() = alarmPreserve;
2634     *config.add_alarm() = alarmRemove;
2635 
2636     int preserveSubId = 1, replaceSubId = 2, removeSubId = 3;
2637     Subscription preserveSub = createSubscription("S1", Subscription::ALARM, alarmPreserve.id());
2638     preserveSub.mutable_broadcast_subscriber_details()->set_subscriber_id(preserveSubId);
2639     Subscription replaceSub = createSubscription("S2", Subscription::ALARM, alarmReplace.id());
2640     replaceSub.mutable_broadcast_subscriber_details()->set_subscriber_id(replaceSubId);
2641     Subscription removeSub = createSubscription("S3", Subscription::ALARM, alarmRemove.id());
2642     removeSub.mutable_broadcast_subscriber_details()->set_subscriber_id(removeSubId);
2643     *config.add_subscription() = preserveSub;
2644     *config.add_subscription() = removeSub;
2645     *config.add_subscription() = replaceSub;
2646 
2647     int64_t configUid = 123, configId = 987;
2648     ConfigKey key(configUid, configId);
2649 
2650     int alarmPreserveCount = 0, alarmReplaceCount = 0, alarmRemoveCount = 0;
2651 
2652     // The binder calls here will happen synchronously because they are in-process.
2653     shared_ptr<MockPendingIntentRef> preserveBroadcast =
2654             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2655     EXPECT_CALL(*preserveBroadcast, sendSubscriberBroadcast(configUid, configId, preserveSub.id(),
2656                                                             alarmPreserve.id(), _, _))
2657             .Times(4)
2658             .WillRepeatedly([&alarmPreserveCount](int64_t, int64_t, int64_t, int64_t,
2659                                                   const vector<string>&,
2660                                                   const StatsDimensionsValueParcel&) {
2661                 alarmPreserveCount++;
2662                 return Status::ok();
2663             });
2664 
2665     shared_ptr<MockPendingIntentRef> replaceBroadcast =
2666             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2667     EXPECT_CALL(*replaceBroadcast, sendSubscriberBroadcast(configUid, configId, replaceSub.id(),
2668                                                            alarmReplace.id(), _, _))
2669             .Times(2)
2670             .WillRepeatedly([&alarmReplaceCount](int64_t, int64_t, int64_t, int64_t,
2671                                                  const vector<string>&,
2672                                                  const StatsDimensionsValueParcel&) {
2673                 alarmReplaceCount++;
2674                 return Status::ok();
2675             });
2676 
2677     shared_ptr<MockPendingIntentRef> removeBroadcast =
2678             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2679     EXPECT_CALL(*removeBroadcast, sendSubscriberBroadcast(configUid, configId, removeSub.id(),
2680                                                           alarmRemove.id(), _, _))
2681             .Times(1)
2682             .WillRepeatedly([&alarmRemoveCount](int64_t, int64_t, int64_t, int64_t,
2683                                                 const vector<string>&,
2684                                                 const StatsDimensionsValueParcel&) {
2685                 alarmRemoveCount++;
2686                 return Status::ok();
2687             });
2688 
2689     SubscriberReporter::getInstance().setBroadcastSubscriber(key, preserveSubId, preserveBroadcast);
2690     SubscriberReporter::getInstance().setBroadcastSubscriber(key, replaceSubId, replaceBroadcast);
2691     SubscriberReporter::getInstance().setBroadcastSubscriber(key, removeSubId, removeBroadcast);
2692 
2693     int64_t startTimeSec = 10;
2694     sp<StatsLogProcessor> processor = CreateStatsLogProcessor(
2695             startTimeSec * NS_PER_SEC, startTimeSec * NS_PER_SEC, config, key);
2696 
2697     sp<AlarmMonitor> alarmMonitor = processor->getPeriodicAlarmMonitor();
2698     // First alarm is for alarm preserve's offset of 5 seconds.
2699     EXPECT_EQ(alarmMonitor->getRegisteredAlarmTimeSec(), startTimeSec + 5);
2700 
2701     // Alarm fired at 5. AlarmPreserve should fire.
2702     int32_t alarmFiredTimestampSec = startTimeSec + 5;
2703     auto alarmSet = alarmMonitor->popSoonerThan(static_cast<uint32_t>(alarmFiredTimestampSec));
2704     processor->onPeriodicAlarmFired(alarmFiredTimestampSec * NS_PER_SEC, alarmSet);
2705     EXPECT_EQ(alarmPreserveCount, 1);
2706     EXPECT_EQ(alarmReplaceCount, 0);
2707     EXPECT_EQ(alarmRemoveCount, 0);
2708     EXPECT_EQ(alarmMonitor->getRegisteredAlarmTimeSec(), startTimeSec + 60);
2709 
2710     // Alarm fired at 75. AlarmPreserve and AlarmRemove should fire.
2711     alarmFiredTimestampSec = startTimeSec + 75;
2712     alarmSet = alarmMonitor->popSoonerThan(static_cast<uint32_t>(alarmFiredTimestampSec));
2713     processor->onPeriodicAlarmFired(alarmFiredTimestampSec * NS_PER_SEC, alarmSet);
2714     EXPECT_EQ(alarmPreserveCount, 2);
2715     EXPECT_EQ(alarmReplaceCount, 0);
2716     EXPECT_EQ(alarmRemoveCount, 1);
2717     EXPECT_EQ(alarmMonitor->getRegisteredAlarmTimeSec(), startTimeSec + 120);
2718 
2719     // Do config update.
2720     StatsdConfig newConfig;
2721     newConfig.add_allowed_log_source("AID_ROOT");
2722 
2723     // Change alarm replace's definition.
2724     alarmReplace.set_period_millis(TimeUnitToBucketSizeInMillis(ONE_MINUTE));
2725     Alarm alarmNew = createAlarm("AlarmNew", /*offset*/ 1,
2726                                  /*period*/ TimeUnitToBucketSizeInMillis(FIVE_MINUTES));
2727     *newConfig.add_alarm() = alarmNew;
2728     *newConfig.add_alarm() = alarmPreserve;
2729     *newConfig.add_alarm() = alarmReplace;
2730 
2731     int newSubId = 4;
2732     Subscription newSub = createSubscription("S4", Subscription::ALARM, alarmNew.id());
2733     newSub.mutable_broadcast_subscriber_details()->set_subscriber_id(newSubId);
2734     *newConfig.add_subscription() = newSub;
2735     *newConfig.add_subscription() = replaceSub;
2736     *newConfig.add_subscription() = preserveSub;
2737 
2738     int alarmNewCount = 0;
2739     shared_ptr<MockPendingIntentRef> newBroadcast =
2740             SharedRefBase::make<StrictMock<MockPendingIntentRef>>();
2741     EXPECT_CALL(*newBroadcast,
2742                 sendSubscriberBroadcast(configUid, configId, newSub.id(), alarmNew.id(), _, _))
2743             .Times(1)
2744             .WillRepeatedly([&alarmNewCount](int64_t, int64_t, int64_t, int64_t,
2745                                              const vector<string>&,
2746                                              const StatsDimensionsValueParcel&) {
2747                 alarmNewCount++;
2748                 return Status::ok();
2749             });
2750     SubscriberReporter::getInstance().setBroadcastSubscriber(key, newSubId, newBroadcast);
2751 
2752     processor->OnConfigUpdated((startTimeSec + 90) * NS_PER_SEC, key, newConfig);
2753     // After the update, the alarm time should remain unchanged since alarm replace now fires every
2754     // minute with no offset.
2755     EXPECT_EQ(alarmMonitor->getRegisteredAlarmTimeSec(), startTimeSec + 120);
2756 
2757     // Alarm fired at 120. AlermReplace should fire.
2758     alarmFiredTimestampSec = startTimeSec + 120;
2759     alarmSet = alarmMonitor->popSoonerThan(static_cast<uint32_t>(alarmFiredTimestampSec));
2760     processor->onPeriodicAlarmFired(alarmFiredTimestampSec * NS_PER_SEC, alarmSet);
2761     EXPECT_EQ(alarmPreserveCount, 2);
2762     EXPECT_EQ(alarmReplaceCount, 1);
2763     EXPECT_EQ(alarmNewCount, 0);
2764     EXPECT_EQ(alarmMonitor->getRegisteredAlarmTimeSec(), startTimeSec + 125);
2765 
2766     // Alarm fired at 130. AlarmPreserve should fire.
2767     alarmFiredTimestampSec = startTimeSec + 130;
2768     alarmSet = alarmMonitor->popSoonerThan(static_cast<uint32_t>(alarmFiredTimestampSec));
2769     processor->onPeriodicAlarmFired(alarmFiredTimestampSec * NS_PER_SEC, alarmSet);
2770     EXPECT_EQ(alarmPreserveCount, 3);
2771     EXPECT_EQ(alarmReplaceCount, 1);
2772     EXPECT_EQ(alarmNewCount, 0);
2773     EXPECT_EQ(alarmMonitor->getRegisteredAlarmTimeSec(), startTimeSec + 180);
2774 
2775     // Alarm fired late at 310. All alerms should fire.
2776     alarmFiredTimestampSec = startTimeSec + 310;
2777     alarmSet = alarmMonitor->popSoonerThan(static_cast<uint32_t>(alarmFiredTimestampSec));
2778     processor->onPeriodicAlarmFired(alarmFiredTimestampSec * NS_PER_SEC, alarmSet);
2779     EXPECT_EQ(alarmPreserveCount, 4);
2780     EXPECT_EQ(alarmReplaceCount, 2);
2781     EXPECT_EQ(alarmNewCount, 1);
2782     EXPECT_EQ(alarmMonitor->getRegisteredAlarmTimeSec(), startTimeSec + 360);
2783 
2784     // Clear subscribers
2785     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, preserveSubId);
2786     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, replaceSubId);
2787     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, removeSubId);
2788     SubscriberReporter::getInstance().unsetBroadcastSubscriber(key, newSubId);
2789 }
2790 
TEST_F(ConfigUpdateE2eTest,TestNewDurationExistingWhat)2791 TEST_F(ConfigUpdateE2eTest, TestNewDurationExistingWhat) {
2792     StatsdConfig config;
2793     config.add_allowed_log_source("AID_ROOT");
2794     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
2795     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
2796 
2797     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
2798     *config.add_predicate() = holdingWakelockPredicate;
2799 
2800     ConfigKey key(123, 987);
2801     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
2802     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(FIVE_MINUTES) * 1000000LL;
2803     sp<StatsLogProcessor> processor =
2804             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
2805 
2806     int app1Uid = 123;
2807     vector<int> attributionUids1 = {app1Uid};
2808     vector<string> attributionTags1 = {"App1"};
2809     // Create a wakelock acquire, causing the condition to be true.
2810     unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
2811                                                             attributionUids1, attributionTags1,
2812                                                             "wl1");  // 0:10
2813     processor->OnLogEvent(event.get());
2814 
2815     // Add metric.
2816     DurationMetric* durationMetric = config.add_duration_metric();
2817     durationMetric->set_id(StringToId("WakelockDuration"));
2818     durationMetric->set_what(holdingWakelockPredicate.id());
2819     durationMetric->set_aggregation_type(DurationMetric::SUM);
2820     durationMetric->set_bucket(FIVE_MINUTES);
2821 
2822     uint64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;  // 1:00
2823     processor->OnConfigUpdated(updateTimeNs, key, config);
2824 
2825     event = CreateReleaseWakelockEvent(bucketStartTimeNs + 80 * NS_PER_SEC, attributionUids1,
2826                                        attributionTags1,
2827                                        "wl1");  // 1:20
2828     processor->OnLogEvent(event.get());
2829     uint64_t dumpTimeNs = bucketStartTimeNs + 90 * NS_PER_SEC;  // 1:30
2830     ConfigMetricsReportList reports;
2831     vector<uint8_t> buffer;
2832     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
2833     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
2834     backfillDimensionPath(&reports);
2835     backfillStringInReport(&reports);
2836     backfillStartEndTimestamp(&reports);
2837     ASSERT_EQ(reports.reports_size(), 1);
2838     ASSERT_EQ(reports.reports(0).metrics_size(), 1);
2839     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
2840 
2841     StatsLogReport::DurationMetricDataWrapper metricData;
2842     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metricData);
2843     ASSERT_EQ(metricData.data_size(), 1);
2844     DurationMetricData data = metricData.data(0);
2845     ASSERT_EQ(data.bucket_info_size(), 1);
2846 
2847     DurationBucketInfo bucketInfo = data.bucket_info(0);
2848     EXPECT_EQ(bucketInfo.start_bucket_elapsed_nanos(), updateTimeNs);
2849     EXPECT_EQ(bucketInfo.end_bucket_elapsed_nanos(), dumpTimeNs);
2850     EXPECT_EQ(bucketInfo.duration_nanos(), 20 * NS_PER_SEC);
2851 }
2852 
TEST_F(ConfigUpdateE2eTest,TestNewDurationExistingWhatSlicedCondition)2853 TEST_F(ConfigUpdateE2eTest, TestNewDurationExistingWhatSlicedCondition) {
2854     StatsdConfig config;
2855     config.add_allowed_log_source("AID_ROOT");
2856     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
2857     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
2858     *config.add_atom_matcher() = CreateMoveToBackgroundAtomMatcher();
2859     *config.add_atom_matcher() = CreateMoveToForegroundAtomMatcher();
2860 
2861     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
2862     // The predicate is dimensioning by first attribution node by uid.
2863     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
2864             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2865     *config.add_predicate() = holdingWakelockPredicate;
2866 
2867     Predicate isInBackgroundPredicate = CreateIsInBackgroundPredicate();
2868     *isInBackgroundPredicate.mutable_simple_predicate()->mutable_dimensions() =
2869             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /*uid*/});
2870     *config.add_predicate() = isInBackgroundPredicate;
2871 
2872     ConfigKey key(123, 987);
2873     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
2874     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(FIVE_MINUTES) * 1000000LL;
2875     sp<StatsLogProcessor> processor =
2876             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
2877 
2878     int app1Uid = 123, app2Uid = 456;
2879     vector<int> attributionUids1 = {app1Uid};
2880     vector<string> attributionTags1 = {"App1"};
2881     vector<int> attributionUids2 = {app2Uid};
2882     vector<string> attributionTags2 = {"App2"};
2883     unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(bucketStartTimeNs + 10 * NS_PER_SEC,
2884                                                             attributionUids1, attributionTags1,
2885                                                             "wl1");  // 0:10
2886     processor->OnLogEvent(event.get());
2887     event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 22 * NS_PER_SEC, app1Uid);  // 0:22
2888     processor->OnLogEvent(event.get());
2889     event = CreateAcquireWakelockEvent(bucketStartTimeNs + 35 * NS_PER_SEC, attributionUids2,
2890                                        attributionTags2,
2891                                        "wl1");  // 0:35
2892     processor->OnLogEvent(event.get());
2893 
2894     // Add metric.
2895     DurationMetric* durationMetric = config.add_duration_metric();
2896     durationMetric->set_id(StringToId("WakelockDuration"));
2897     durationMetric->set_what(holdingWakelockPredicate.id());
2898     durationMetric->set_condition(isInBackgroundPredicate.id());
2899     durationMetric->set_aggregation_type(DurationMetric::SUM);
2900     // The metric is dimensioning by first attribution node and only by uid.
2901     *durationMetric->mutable_dimensions_in_what() =
2902             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2903     durationMetric->set_bucket(FIVE_MINUTES);
2904     // Links between wakelock state atom and condition of app is in background.
2905     auto links = durationMetric->add_links();
2906     links->set_condition(isInBackgroundPredicate.id());
2907     *links->mutable_fields_in_what() =
2908             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2909     *links->mutable_fields_in_condition() =
2910             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1 /*uid*/});
2911 
2912     uint64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;  // 1:00
2913     processor->OnConfigUpdated(updateTimeNs, key, config);
2914 
2915     event = CreateMoveToBackgroundEvent(bucketStartTimeNs + 73 * NS_PER_SEC, app2Uid);  // 1:13
2916     processor->OnLogEvent(event.get());
2917     event = CreateReleaseWakelockEvent(bucketStartTimeNs + 84 * NS_PER_SEC, attributionUids1,
2918                                        attributionTags1, "wl1");  // 1:24
2919     processor->OnLogEvent(event.get());
2920 
2921     uint64_t dumpTimeNs = bucketStartTimeNs + 90 * NS_PER_SEC;  //  1:30
2922     ConfigMetricsReportList reports;
2923     vector<uint8_t> buffer;
2924     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
2925     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
2926     backfillDimensionPath(&reports);
2927     backfillStringInReport(&reports);
2928     backfillStartEndTimestamp(&reports);
2929     ASSERT_EQ(reports.reports_size(), 1);
2930     ASSERT_EQ(reports.reports(0).metrics_size(), 1);
2931     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
2932 
2933     StatsLogReport::DurationMetricDataWrapper metricData;
2934     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metricData);
2935     ASSERT_EQ(metricData.data_size(), 2);
2936 
2937     DurationMetricData data = metricData.data(0);
2938     ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
2939                                     app1Uid);
2940     ASSERT_EQ(data.bucket_info_size(), 1);
2941     DurationBucketInfo bucketInfo = data.bucket_info(0);
2942     EXPECT_EQ(bucketInfo.duration_nanos(), 24 * NS_PER_SEC);
2943 
2944     data = metricData.data(1);
2945     ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
2946                                     app2Uid);
2947     ASSERT_EQ(data.bucket_info_size(), 1);
2948     bucketInfo = data.bucket_info(0);
2949     EXPECT_EQ(bucketInfo.duration_nanos(), 17 * NS_PER_SEC);
2950 }
2951 
TEST_F(ConfigUpdateE2eTest,TestNewDurationExistingWhatSlicedState)2952 TEST_F(ConfigUpdateE2eTest, TestNewDurationExistingWhatSlicedState) {
2953     StatsdConfig config;
2954     config.add_allowed_log_source("AID_ROOT");
2955     *config.add_atom_matcher() = CreateAcquireWakelockAtomMatcher();
2956     *config.add_atom_matcher() = CreateReleaseWakelockAtomMatcher();
2957 
2958     Predicate holdingWakelockPredicate = CreateHoldingWakelockPredicate();
2959     // The predicate is dimensioning by first attribution node by uid.
2960     *holdingWakelockPredicate.mutable_simple_predicate()->mutable_dimensions() =
2961             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2962     *config.add_predicate() = holdingWakelockPredicate;
2963 
2964     auto uidProcessState = CreateUidProcessState();
2965     *config.add_state() = uidProcessState;
2966 
2967     // Count metric. We don't care about this one. Only use it so the StateTracker gets persisted.
2968     CountMetric* countMetric = config.add_count_metric();
2969     countMetric->set_id(StringToId("Tmp"));
2970     countMetric->set_what(config.atom_matcher(0).id());
2971     countMetric->add_slice_by_state(uidProcessState.id());
2972     // The metric is dimensioning by first attribution node and only by uid.
2973     *countMetric->mutable_dimensions_in_what() =
2974             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2975     countMetric->set_bucket(FIVE_MINUTES);
2976     auto stateLink = countMetric->add_state_link();
2977     stateLink->set_state_atom_id(util::UID_PROCESS_STATE_CHANGED);
2978     *stateLink->mutable_fields_in_what() =
2979             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2980     *stateLink->mutable_fields_in_state() =
2981             CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /*uid*/});
2982     config.add_no_report_metric(countMetric->id());
2983 
2984     ConfigKey key(123, 987);
2985     uint64_t bucketStartTimeNs = 10000000000;  // 0:10
2986     uint64_t bucketSizeNs = TimeUnitToBucketSizeInMillis(FIVE_MINUTES) * 1000000LL;
2987     sp<StatsLogProcessor> processor =
2988             CreateStatsLogProcessor(bucketStartTimeNs, bucketStartTimeNs, config, key);
2989 
2990     int app1Uid = 123, app2Uid = 456;
2991     vector<int> attributionUids1 = {app1Uid};
2992     vector<string> attributionTags1 = {"App1"};
2993     vector<int> attributionUids2 = {app2Uid};
2994     vector<string> attributionTags2 = {"App2"};
2995     unique_ptr<LogEvent> event = CreateUidProcessStateChangedEvent(
2996             bucketStartTimeNs + 10 * NS_PER_SEC, app1Uid,
2997             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);  // 0:10
2998     processor->OnLogEvent(event.get());
2999     event = CreateAcquireWakelockEvent(bucketStartTimeNs + 22 * NS_PER_SEC, attributionUids1,
3000                                        attributionTags1,
3001                                        "wl1");  // 0:22
3002     processor->OnLogEvent(event.get());
3003     event = CreateUidProcessStateChangedEvent(
3004             bucketStartTimeNs + 30 * NS_PER_SEC, app2Uid,
3005             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);  // 0:30
3006     processor->OnLogEvent(event.get());
3007 
3008     // Add metric.
3009     DurationMetric* durationMetric = config.add_duration_metric();
3010     durationMetric->set_id(StringToId("WakelockDuration"));
3011     durationMetric->set_what(holdingWakelockPredicate.id());
3012     durationMetric->add_slice_by_state(uidProcessState.id());
3013     durationMetric->set_aggregation_type(DurationMetric::SUM);
3014     // The metric is dimensioning by first attribution node and only by uid.
3015     *durationMetric->mutable_dimensions_in_what() =
3016             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
3017     durationMetric->set_bucket(FIVE_MINUTES);
3018     // Links between wakelock state atom and condition of app is in background.
3019     stateLink = durationMetric->add_state_link();
3020     stateLink->set_state_atom_id(util::UID_PROCESS_STATE_CHANGED);
3021     *stateLink->mutable_fields_in_what() =
3022             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
3023     *stateLink->mutable_fields_in_state() =
3024             CreateDimensions(util::UID_PROCESS_STATE_CHANGED, {1 /*uid*/});
3025 
3026     uint64_t updateTimeNs = bucketStartTimeNs + 60 * NS_PER_SEC;  // 1:00
3027     processor->OnConfigUpdated(updateTimeNs, key, config);
3028 
3029     event = CreateAcquireWakelockEvent(bucketStartTimeNs + 72 * NS_PER_SEC, attributionUids2,
3030                                        attributionTags2,
3031                                        "wl1");  // 1:13
3032     processor->OnLogEvent(event.get());
3033     event = CreateUidProcessStateChangedEvent(
3034             bucketStartTimeNs + 75 * NS_PER_SEC, app1Uid,
3035             android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);  // 1:15
3036     processor->OnLogEvent(event.get());
3037     event = CreateReleaseWakelockEvent(bucketStartTimeNs + 84 * NS_PER_SEC, attributionUids1,
3038                                        attributionTags1, "wl1");  // 1:24
3039     processor->OnLogEvent(event.get());
3040 
3041     uint64_t dumpTimeNs = bucketStartTimeNs + 90 * NS_PER_SEC;  //  1:30
3042     ConfigMetricsReportList reports;
3043     vector<uint8_t> buffer;
3044     processor->onDumpReport(key, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
3045     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
3046     backfillDimensionPath(&reports);
3047     backfillStringInReport(&reports);
3048     backfillStartEndTimestamp(&reports);
3049     ASSERT_EQ(reports.reports_size(), 1);
3050     ASSERT_EQ(reports.reports(0).metrics_size(), 1);
3051     EXPECT_TRUE(reports.reports(0).metrics(0).has_duration_metrics());
3052 
3053     StatsLogReport::DurationMetricDataWrapper metricData;
3054     sortMetricDataByDimensionsValue(reports.reports(0).metrics(0).duration_metrics(), &metricData);
3055     ASSERT_EQ(metricData.data_size(), 3);
3056 
3057     DurationMetricData data = metricData.data(0);
3058     ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
3059                                     app1Uid);
3060     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
3061                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
3062     ASSERT_EQ(data.bucket_info_size(), 1);
3063     DurationBucketInfo bucketInfo = data.bucket_info(0);
3064     EXPECT_EQ(bucketInfo.duration_nanos(), 15 * NS_PER_SEC);
3065 
3066     data = metricData.data(1);
3067     ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
3068                                     app1Uid);
3069     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
3070                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_BACKGROUND);
3071     ASSERT_EQ(data.bucket_info_size(), 1);
3072     bucketInfo = data.bucket_info(0);
3073     EXPECT_EQ(bucketInfo.duration_nanos(), 9 * NS_PER_SEC);
3074 
3075     data = metricData.data(2);
3076     ValidateAttributionUidDimension(data.dimensions_in_what(), util::WAKELOCK_STATE_CHANGED,
3077                                     app2Uid);
3078     ValidateStateValue(data.slice_by_state(), util::UID_PROCESS_STATE_CHANGED,
3079                        android::app::ProcessStateEnum::PROCESS_STATE_IMPORTANT_FOREGROUND);
3080     ASSERT_EQ(data.bucket_info_size(), 1);
3081     bucketInfo = data.bucket_info(0);
3082     EXPECT_EQ(bucketInfo.duration_nanos(), 18 * NS_PER_SEC);
3083 }
3084 
3085 #else
3086 GTEST_LOG_(INFO) << "This test does nothing.\n";
3087 #endif
3088 
3089 }  // namespace statsd
3090 }  // namespace os
3091 }  // namespace android
3092