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