• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2020 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/metrics/parsing_utils/config_update_utils.h"
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <private/android_filesystem_config.h>
20 #include <stdio.h>
21 
22 #include <set>
23 #include <unordered_map>
24 #include <vector>
25 
26 #include "src/statsd_config.pb.h"
27 #include "src/condition/CombinationConditionTracker.h"
28 #include "src/condition/SimpleConditionTracker.h"
29 #include "src/matchers/CombinationAtomMatchingTracker.h"
30 #include "src/metrics/DurationMetricProducer.h"
31 #include "src/metrics/GaugeMetricProducer.h"
32 #include "src/metrics/ValueMetricProducer.h"
33 #include "src/metrics/parsing_utils/metrics_manager_util.h"
34 #include "tests/statsd_test_util.h"
35 
36 using namespace testing;
37 using android::sp;
38 using android::os::statsd::Predicate;
39 using std::map;
40 using std::nullopt;
41 using std::optional;
42 using std::set;
43 using std::unordered_map;
44 using std::vector;
45 
46 #ifdef __ANDROID__
47 
48 namespace android {
49 namespace os {
50 namespace statsd {
51 
52 namespace {
53 
54 ConfigKey key(123, 456);
55 const int64_t timeBaseNs = 1000 * NS_PER_SEC;
56 
57 sp<UidMap> uidMap = new UidMap();
58 sp<StatsPullerManager> pullerManager = new StatsPullerManager();
59 sp<AlarmMonitor> anomalyAlarmMonitor;
60 sp<AlarmMonitor> periodicAlarmMonitor = new AlarmMonitor(
61         /*minDiffToUpdateRegisteredAlarmTimeSec=*/0,
__anon813d57930202(const shared_ptr<IStatsCompanionService>&, int64_t) 62         [](const shared_ptr<IStatsCompanionService>&, int64_t) {},
__anon813d57930302(const shared_ptr<IStatsCompanionService>&) 63         [](const shared_ptr<IStatsCompanionService>&) {});
64 set<int> allTagIds;
65 vector<sp<AtomMatchingTracker>> oldAtomMatchingTrackers;
66 unordered_map<int64_t, int> oldAtomMatchingTrackerMap;
67 vector<sp<ConditionTracker>> oldConditionTrackers;
68 unordered_map<int64_t, int> oldConditionTrackerMap;
69 vector<sp<MetricProducer>> oldMetricProducers;
70 unordered_map<int64_t, int> oldMetricProducerMap;
71 std::vector<sp<AnomalyTracker>> oldAnomalyTrackers;
72 unordered_map<int64_t, int> oldAlertTrackerMap;
73 std::vector<sp<AlarmTracker>> oldAlarmTrackers;
74 unordered_map<int, std::vector<int>> tmpConditionToMetricMap;
75 unordered_map<int, std::vector<int>> tmpTrackerToMetricMap;
76 unordered_map<int, std::vector<int>> tmpTrackerToConditionMap;
77 unordered_map<int, std::vector<int>> tmpActivationAtomTrackerToMetricMap;
78 unordered_map<int, std::vector<int>> tmpDeactivationAtomTrackerToMetricMap;
79 vector<int> metricsWithActivation;
80 map<int64_t, uint64_t> oldStateHashes;
81 std::set<int64_t> noReportMetricIds;
82 
83 class ConfigUpdateTest : public ::testing::Test {
84 public:
ConfigUpdateTest()85     ConfigUpdateTest() {
86     }
87 
SetUp()88     void SetUp() override {
89         allTagIds.clear();
90         oldAtomMatchingTrackers.clear();
91         oldAtomMatchingTrackerMap.clear();
92         oldConditionTrackers.clear();
93         oldConditionTrackerMap.clear();
94         oldMetricProducers.clear();
95         oldMetricProducerMap.clear();
96         oldAnomalyTrackers.clear();
97         oldAlarmTrackers.clear();
98         tmpConditionToMetricMap.clear();
99         tmpTrackerToMetricMap.clear();
100         tmpTrackerToConditionMap.clear();
101         tmpActivationAtomTrackerToMetricMap.clear();
102         tmpDeactivationAtomTrackerToMetricMap.clear();
103         oldAlertTrackerMap.clear();
104         metricsWithActivation.clear();
105         oldStateHashes.clear();
106         noReportMetricIds.clear();
107         StateManager::getInstance().clear();
108     }
109 };
110 
initConfig(const StatsdConfig & config)111 bool initConfig(const StatsdConfig& config) {
112     return initStatsdConfig(
113             key, config, uidMap, pullerManager, anomalyAlarmMonitor, periodicAlarmMonitor,
114             timeBaseNs, timeBaseNs, allTagIds, oldAtomMatchingTrackers, oldAtomMatchingTrackerMap,
115             oldConditionTrackers, oldConditionTrackerMap, oldMetricProducers, oldMetricProducerMap,
116             oldAnomalyTrackers, oldAlarmTrackers, tmpConditionToMetricMap, tmpTrackerToMetricMap,
117             tmpTrackerToConditionMap, tmpActivationAtomTrackerToMetricMap,
118             tmpDeactivationAtomTrackerToMetricMap, oldAlertTrackerMap, metricsWithActivation,
119             oldStateHashes, noReportMetricIds);
120 }
121 }  // anonymous namespace
122 
TEST_F(ConfigUpdateTest,TestSimpleMatcherPreserve)123 TEST_F(ConfigUpdateTest, TestSimpleMatcherPreserve) {
124     StatsdConfig config;
125     AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
126     int64_t matcherId = matcher.id();
127     *config.add_atom_matcher() = matcher;
128 
129     // Create an initial config.
130     EXPECT_TRUE(initConfig(config));
131 
132     vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
133     vector<bool> cycleTracker(1, false);
134     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
135     newAtomMatchingTrackerMap[matcherId] = 0;
136     EXPECT_TRUE(determineMatcherUpdateStatus(config, 0, oldAtomMatchingTrackerMap,
137                                              oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
138                                              matchersToUpdate, cycleTracker));
139     EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
140 }
141 
TEST_F(ConfigUpdateTest,TestSimpleMatcherReplace)142 TEST_F(ConfigUpdateTest, TestSimpleMatcherReplace) {
143     StatsdConfig config;
144     AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
145     *config.add_atom_matcher() = matcher;
146 
147     EXPECT_TRUE(initConfig(config));
148 
149     StatsdConfig newConfig;
150     // Same id, different atom, so should be replaced.
151     AtomMatcher newMatcher = CreateSimpleAtomMatcher("TEST", /*atom=*/11);
152     int64_t matcherId = newMatcher.id();
153     EXPECT_EQ(matcherId, matcher.id());
154     *newConfig.add_atom_matcher() = newMatcher;
155 
156     vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
157     vector<bool> cycleTracker(1, false);
158     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
159     newAtomMatchingTrackerMap[matcherId] = 0;
160     EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
161                                              oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
162                                              matchersToUpdate, cycleTracker));
163     EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
164 }
165 
TEST_F(ConfigUpdateTest,TestSimpleMatcherNew)166 TEST_F(ConfigUpdateTest, TestSimpleMatcherNew) {
167     StatsdConfig config;
168     AtomMatcher matcher = CreateSimpleAtomMatcher("TEST", /*atom=*/10);
169     *config.add_atom_matcher() = matcher;
170 
171     EXPECT_TRUE(initConfig(config));
172 
173     StatsdConfig newConfig;
174     // Different id, so should be a new matcher.
175     AtomMatcher newMatcher = CreateSimpleAtomMatcher("DIFFERENT_NAME", /*atom=*/10);
176     int64_t matcherId = newMatcher.id();
177     EXPECT_NE(matcherId, matcher.id());
178     *newConfig.add_atom_matcher() = newMatcher;
179 
180     vector<UpdateStatus> matchersToUpdate(1, UPDATE_UNKNOWN);
181     vector<bool> cycleTracker(1, false);
182     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
183     newAtomMatchingTrackerMap[matcherId] = 0;
184     EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 0, oldAtomMatchingTrackerMap,
185                                              oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
186                                              matchersToUpdate, cycleTracker));
187     EXPECT_EQ(matchersToUpdate[0], UPDATE_NEW);
188 }
189 
TEST_F(ConfigUpdateTest,TestCombinationMatcherPreserve)190 TEST_F(ConfigUpdateTest, TestCombinationMatcherPreserve) {
191     StatsdConfig config;
192     AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
193     int64_t matcher1Id = matcher1.id();
194     *config.add_atom_matcher() = matcher1;
195 
196     AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
197     *config.add_atom_matcher() = matcher2;
198     int64_t matcher2Id = matcher2.id();
199 
200     AtomMatcher matcher3;
201     matcher3.set_id(StringToId("TEST3"));
202     AtomMatcher_Combination* combination = matcher3.mutable_combination();
203     combination->set_operation(LogicalOperation::OR);
204     combination->add_matcher(matcher1Id);
205     combination->add_matcher(matcher2Id);
206     int64_t matcher3Id = matcher3.id();
207     *config.add_atom_matcher() = matcher3;
208 
209     EXPECT_TRUE(initConfig(config));
210 
211     StatsdConfig newConfig;
212     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
213     // Same matchers, different order, all should be preserved.
214     *newConfig.add_atom_matcher() = matcher2;
215     newAtomMatchingTrackerMap[matcher2Id] = 0;
216     *newConfig.add_atom_matcher() = matcher3;
217     newAtomMatchingTrackerMap[matcher3Id] = 1;
218     *newConfig.add_atom_matcher() = matcher1;
219     newAtomMatchingTrackerMap[matcher1Id] = 2;
220 
221     vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
222     vector<bool> cycleTracker(3, false);
223     // Only update the combination. It should recurse the two child matchers and preserve all 3.
224     EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
225                                              oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
226                                              matchersToUpdate, cycleTracker));
227     EXPECT_EQ(matchersToUpdate[0], UPDATE_PRESERVE);
228     EXPECT_EQ(matchersToUpdate[1], UPDATE_PRESERVE);
229     EXPECT_EQ(matchersToUpdate[2], UPDATE_PRESERVE);
230 }
231 
TEST_F(ConfigUpdateTest,TestCombinationMatcherReplace)232 TEST_F(ConfigUpdateTest, TestCombinationMatcherReplace) {
233     StatsdConfig config;
234     AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
235     int64_t matcher1Id = matcher1.id();
236     *config.add_atom_matcher() = matcher1;
237 
238     AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
239     *config.add_atom_matcher() = matcher2;
240     int64_t matcher2Id = matcher2.id();
241 
242     AtomMatcher matcher3;
243     matcher3.set_id(StringToId("TEST3"));
244     AtomMatcher_Combination* combination = matcher3.mutable_combination();
245     combination->set_operation(LogicalOperation::OR);
246     combination->add_matcher(matcher1Id);
247     combination->add_matcher(matcher2Id);
248     int64_t matcher3Id = matcher3.id();
249     *config.add_atom_matcher() = matcher3;
250 
251     EXPECT_TRUE(initConfig(config));
252 
253     // Change the logical operation of the combination matcher, causing a replacement.
254     matcher3.mutable_combination()->set_operation(LogicalOperation::AND);
255 
256     StatsdConfig newConfig;
257     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
258     *newConfig.add_atom_matcher() = matcher2;
259     newAtomMatchingTrackerMap[matcher2Id] = 0;
260     *newConfig.add_atom_matcher() = matcher3;
261     newAtomMatchingTrackerMap[matcher3Id] = 1;
262     *newConfig.add_atom_matcher() = matcher1;
263     newAtomMatchingTrackerMap[matcher1Id] = 2;
264 
265     vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
266     vector<bool> cycleTracker(3, false);
267     // Only update the combination. The simple matchers should not be evaluated.
268     EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
269                                              oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
270                                              matchersToUpdate, cycleTracker));
271     EXPECT_EQ(matchersToUpdate[0], UPDATE_UNKNOWN);
272     EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
273     EXPECT_EQ(matchersToUpdate[2], UPDATE_UNKNOWN);
274 }
275 
TEST_F(ConfigUpdateTest,TestCombinationMatcherDepsChange)276 TEST_F(ConfigUpdateTest, TestCombinationMatcherDepsChange) {
277     StatsdConfig config;
278     AtomMatcher matcher1 = CreateSimpleAtomMatcher("TEST1", /*atom=*/10);
279     int64_t matcher1Id = matcher1.id();
280     *config.add_atom_matcher() = matcher1;
281 
282     AtomMatcher matcher2 = CreateSimpleAtomMatcher("TEST2", /*atom=*/11);
283     *config.add_atom_matcher() = matcher2;
284     int64_t matcher2Id = matcher2.id();
285 
286     AtomMatcher matcher3;
287     matcher3.set_id(StringToId("TEST3"));
288     AtomMatcher_Combination* combination = matcher3.mutable_combination();
289     combination->set_operation(LogicalOperation::OR);
290     combination->add_matcher(matcher1Id);
291     combination->add_matcher(matcher2Id);
292     int64_t matcher3Id = matcher3.id();
293     *config.add_atom_matcher() = matcher3;
294 
295     EXPECT_TRUE(initConfig(config));
296 
297     // Change a dependency of matcher 3.
298     matcher2.mutable_simple_atom_matcher()->set_atom_id(12);
299 
300     StatsdConfig newConfig;
301     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
302     *newConfig.add_atom_matcher() = matcher2;
303     newAtomMatchingTrackerMap[matcher2Id] = 0;
304     *newConfig.add_atom_matcher() = matcher3;
305     newAtomMatchingTrackerMap[matcher3Id] = 1;
306     *newConfig.add_atom_matcher() = matcher1;
307     newAtomMatchingTrackerMap[matcher1Id] = 2;
308 
309     vector<UpdateStatus> matchersToUpdate(3, UPDATE_UNKNOWN);
310     vector<bool> cycleTracker(3, false);
311     // Only update the combination.
312     EXPECT_TRUE(determineMatcherUpdateStatus(newConfig, 1, oldAtomMatchingTrackerMap,
313                                              oldAtomMatchingTrackers, newAtomMatchingTrackerMap,
314                                              matchersToUpdate, cycleTracker));
315     // Matcher 2 and matcher3 must be reevaluated. Matcher 1 might, but does not need to be.
316     EXPECT_EQ(matchersToUpdate[0], UPDATE_REPLACE);
317     EXPECT_EQ(matchersToUpdate[1], UPDATE_REPLACE);
318 }
319 
TEST_F(ConfigUpdateTest,TestUpdateMatchers)320 TEST_F(ConfigUpdateTest, TestUpdateMatchers) {
321     StatsdConfig config;
322     // Will be preserved.
323     AtomMatcher simple1 = CreateSimpleAtomMatcher("SIMPLE1", /*atom=*/10);
324     int64_t simple1Id = simple1.id();
325     *config.add_atom_matcher() = simple1;
326 
327     // Will be replaced.
328     AtomMatcher simple2 = CreateSimpleAtomMatcher("SIMPLE2", /*atom=*/11);
329     *config.add_atom_matcher() = simple2;
330     int64_t simple2Id = simple2.id();
331 
332     // Will be removed.
333     AtomMatcher simple3 = CreateSimpleAtomMatcher("SIMPLE3", /*atom=*/12);
334     *config.add_atom_matcher() = simple3;
335     int64_t simple3Id = simple3.id();
336 
337     // Will be preserved.
338     AtomMatcher combination1;
339     combination1.set_id(StringToId("combination1"));
340     AtomMatcher_Combination* combination = combination1.mutable_combination();
341     combination->set_operation(LogicalOperation::NOT);
342     combination->add_matcher(simple1Id);
343     int64_t combination1Id = combination1.id();
344     *config.add_atom_matcher() = combination1;
345 
346     // Will be replaced since it depends on simple2.
347     AtomMatcher combination2;
348     combination2.set_id(StringToId("combination2"));
349     combination = combination2.mutable_combination();
350     combination->set_operation(LogicalOperation::AND);
351     combination->add_matcher(simple1Id);
352     combination->add_matcher(simple2Id);
353     int64_t combination2Id = combination2.id();
354     *config.add_atom_matcher() = combination2;
355 
356     EXPECT_TRUE(initConfig(config));
357 
358     // Change simple2, causing simple2 and combination2 to be replaced.
359     simple2.mutable_simple_atom_matcher()->set_atom_id(111);
360 
361     // 2 new matchers: simple4 and combination3:
362     AtomMatcher simple4 = CreateSimpleAtomMatcher("SIMPLE4", /*atom=*/13);
363     int64_t simple4Id = simple4.id();
364 
365     AtomMatcher combination3;
366     combination3.set_id(StringToId("combination3"));
367     combination = combination3.mutable_combination();
368     combination->set_operation(LogicalOperation::AND);
369     combination->add_matcher(simple4Id);
370     combination->add_matcher(simple2Id);
371     int64_t combination3Id = combination3.id();
372 
373     StatsdConfig newConfig;
374     *newConfig.add_atom_matcher() = combination3;
375     *newConfig.add_atom_matcher() = simple2;
376     *newConfig.add_atom_matcher() = combination2;
377     *newConfig.add_atom_matcher() = simple1;
378     *newConfig.add_atom_matcher() = simple4;
379     *newConfig.add_atom_matcher() = combination1;
380 
381     set<int> newTagIds;
382     unordered_map<int64_t, int> newAtomMatchingTrackerMap;
383     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers;
384     set<int64_t> replacedMatchers;
385     EXPECT_TRUE(updateAtomMatchingTrackers(
386             newConfig, uidMap, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers, newTagIds,
387             newAtomMatchingTrackerMap, newAtomMatchingTrackers, replacedMatchers));
388 
389     ASSERT_EQ(newTagIds.size(), 3);
390     EXPECT_EQ(newTagIds.count(10), 1);
391     EXPECT_EQ(newTagIds.count(111), 1);
392     EXPECT_EQ(newTagIds.count(13), 1);
393 
394     ASSERT_EQ(newAtomMatchingTrackerMap.size(), 6);
395     EXPECT_EQ(newAtomMatchingTrackerMap.at(combination3Id), 0);
396     EXPECT_EQ(newAtomMatchingTrackerMap.at(simple2Id), 1);
397     EXPECT_EQ(newAtomMatchingTrackerMap.at(combination2Id), 2);
398     EXPECT_EQ(newAtomMatchingTrackerMap.at(simple1Id), 3);
399     EXPECT_EQ(newAtomMatchingTrackerMap.at(simple4Id), 4);
400     EXPECT_EQ(newAtomMatchingTrackerMap.at(combination1Id), 5);
401 
402     ASSERT_EQ(newAtomMatchingTrackers.size(), 6);
403     // Make sure all atom matchers are initialized:
404     for (const sp<AtomMatchingTracker>& tracker : newAtomMatchingTrackers) {
405         EXPECT_TRUE(tracker->mInitialized);
406     }
407     // Make sure preserved atom matchers are the same.
408     EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple1Id)],
409               newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple1Id)]);
410     EXPECT_EQ(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination1Id)],
411               newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination1Id)]);
412     // Make sure replaced matchers are different.
413     EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(simple2Id)],
414               newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(simple2Id)]);
415     EXPECT_NE(oldAtomMatchingTrackers[oldAtomMatchingTrackerMap.at(combination2Id)],
416               newAtomMatchingTrackers[newAtomMatchingTrackerMap.at(combination2Id)]);
417 
418     // Validation, make sure the matchers have the proper ids/indices. Could do more checks here.
419     EXPECT_EQ(newAtomMatchingTrackers[0]->getId(), combination3Id);
420     EXPECT_EQ(newAtomMatchingTrackers[0]->mIndex, 0);
421     EXPECT_EQ(newAtomMatchingTrackers[1]->getId(), simple2Id);
422     EXPECT_EQ(newAtomMatchingTrackers[1]->mIndex, 1);
423     EXPECT_EQ(newAtomMatchingTrackers[2]->getId(), combination2Id);
424     EXPECT_EQ(newAtomMatchingTrackers[2]->mIndex, 2);
425     EXPECT_EQ(newAtomMatchingTrackers[3]->getId(), simple1Id);
426     EXPECT_EQ(newAtomMatchingTrackers[3]->mIndex, 3);
427     EXPECT_EQ(newAtomMatchingTrackers[4]->getId(), simple4Id);
428     EXPECT_EQ(newAtomMatchingTrackers[4]->mIndex, 4);
429     EXPECT_EQ(newAtomMatchingTrackers[5]->getId(), combination1Id);
430     EXPECT_EQ(newAtomMatchingTrackers[5]->mIndex, 5);
431 
432     // Verify child indices of Combination Matchers are correct.
433     CombinationAtomMatchingTracker* combinationTracker1 =
434             static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[5].get());
435     vector<int>* childMatchers = &combinationTracker1->mChildren;
436     EXPECT_EQ(childMatchers->size(), 1);
437     EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());
438 
439     CombinationAtomMatchingTracker* combinationTracker2 =
440             static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[2].get());
441     childMatchers = &combinationTracker2->mChildren;
442     EXPECT_EQ(childMatchers->size(), 2);
443     EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
444     EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 3), childMatchers->end());
445 
446     CombinationAtomMatchingTracker* combinationTracker3 =
447             static_cast<CombinationAtomMatchingTracker*>(newAtomMatchingTrackers[0].get());
448     childMatchers = &combinationTracker3->mChildren;
449     EXPECT_EQ(childMatchers->size(), 2);
450     EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 1), childMatchers->end());
451     EXPECT_NE(std::find(childMatchers->begin(), childMatchers->end(), 4), childMatchers->end());
452 
453     // Expect replacedMatchers to have simple2 and combination2
454     ASSERT_EQ(replacedMatchers.size(), 2);
455     EXPECT_NE(replacedMatchers.find(simple2Id), replacedMatchers.end());
456     EXPECT_NE(replacedMatchers.find(combination2Id), replacedMatchers.end());
457 }
458 
TEST_F(ConfigUpdateTest,TestSimpleConditionPreserve)459 TEST_F(ConfigUpdateTest, TestSimpleConditionPreserve) {
460     StatsdConfig config;
461     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
462     *config.add_atom_matcher() = startMatcher;
463     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
464     *config.add_atom_matcher() = stopMatcher;
465 
466     Predicate predicate = CreateScreenIsOnPredicate();
467     *config.add_predicate() = predicate;
468 
469     // Create an initial config.
470     EXPECT_TRUE(initConfig(config));
471 
472     set<int64_t> replacedMatchers;
473     vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
474     vector<bool> cycleTracker(1, false);
475     unordered_map<int64_t, int> newConditionTrackerMap;
476     newConditionTrackerMap[predicate.id()] = 0;
477     EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
478                                                oldConditionTrackers, newConditionTrackerMap,
479                                                replacedMatchers, conditionsToUpdate, cycleTracker));
480     EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
481 }
482 
TEST_F(ConfigUpdateTest,TestSimpleConditionReplace)483 TEST_F(ConfigUpdateTest, TestSimpleConditionReplace) {
484     StatsdConfig config;
485     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
486     *config.add_atom_matcher() = startMatcher;
487     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
488     *config.add_atom_matcher() = stopMatcher;
489 
490     Predicate predicate = CreateScreenIsOnPredicate();
491     *config.add_predicate() = predicate;
492 
493     EXPECT_TRUE(initConfig(config));
494 
495     // Modify the predicate.
496     config.mutable_predicate(0)->mutable_simple_predicate()->set_count_nesting(true);
497 
498     set<int64_t> replacedMatchers;
499     vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
500     vector<bool> cycleTracker(1, false);
501     unordered_map<int64_t, int> newConditionTrackerMap;
502     newConditionTrackerMap[predicate.id()] = 0;
503     EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
504                                                oldConditionTrackers, newConditionTrackerMap,
505                                                replacedMatchers, conditionsToUpdate, cycleTracker));
506     EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
507 }
508 
TEST_F(ConfigUpdateTest,TestSimpleConditionDepsChange)509 TEST_F(ConfigUpdateTest, TestSimpleConditionDepsChange) {
510     StatsdConfig config;
511     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
512     int64_t startMatcherId = startMatcher.id();
513     *config.add_atom_matcher() = startMatcher;
514     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
515     *config.add_atom_matcher() = stopMatcher;
516 
517     Predicate predicate = CreateScreenIsOnPredicate();
518     *config.add_predicate() = predicate;
519 
520     EXPECT_TRUE(initConfig(config));
521 
522     // Start matcher was replaced.
523     set<int64_t> replacedMatchers;
524     replacedMatchers.insert(startMatcherId);
525 
526     vector<UpdateStatus> conditionsToUpdate(1, UPDATE_UNKNOWN);
527     vector<bool> cycleTracker(1, false);
528     unordered_map<int64_t, int> newConditionTrackerMap;
529     newConditionTrackerMap[predicate.id()] = 0;
530     EXPECT_TRUE(determineConditionUpdateStatus(config, 0, oldConditionTrackerMap,
531                                                oldConditionTrackers, newConditionTrackerMap,
532                                                replacedMatchers, conditionsToUpdate, cycleTracker));
533     EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
534 }
535 
TEST_F(ConfigUpdateTest,TestCombinationConditionPreserve)536 TEST_F(ConfigUpdateTest, TestCombinationConditionPreserve) {
537     StatsdConfig config;
538     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
539     *config.add_atom_matcher() = screenOnMatcher;
540     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
541     *config.add_atom_matcher() = screenOffMatcher;
542 
543     Predicate simple1 = CreateScreenIsOnPredicate();
544     *config.add_predicate() = simple1;
545     Predicate simple2 = CreateScreenIsOffPredicate();
546     *config.add_predicate() = simple2;
547 
548     Predicate combination1;
549     combination1.set_id(StringToId("COMBINATION1"));
550     Predicate_Combination* combinationInternal = combination1.mutable_combination();
551     combinationInternal->set_operation(LogicalOperation::NAND);
552     combinationInternal->add_predicate(simple1.id());
553     combinationInternal->add_predicate(simple2.id());
554     *config.add_predicate() = combination1;
555 
556     EXPECT_TRUE(initConfig(config));
557 
558     // Same predicates, different order
559     StatsdConfig newConfig;
560     unordered_map<int64_t, int> newConditionTrackerMap;
561     *newConfig.add_predicate() = combination1;
562     newConditionTrackerMap[combination1.id()] = 0;
563     *newConfig.add_predicate() = simple2;
564     newConditionTrackerMap[simple2.id()] = 1;
565     *newConfig.add_predicate() = simple1;
566     newConditionTrackerMap[simple1.id()] = 2;
567 
568     set<int64_t> replacedMatchers;
569     vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
570     vector<bool> cycleTracker(3, false);
571     // Only update the combination. It should recurse the two child predicates and preserve all 3.
572     EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
573                                                oldConditionTrackers, newConditionTrackerMap,
574                                                replacedMatchers, conditionsToUpdate, cycleTracker));
575     EXPECT_EQ(conditionsToUpdate[0], UPDATE_PRESERVE);
576     EXPECT_EQ(conditionsToUpdate[1], UPDATE_PRESERVE);
577     EXPECT_EQ(conditionsToUpdate[2], UPDATE_PRESERVE);
578 }
579 
TEST_F(ConfigUpdateTest,TestCombinationConditionReplace)580 TEST_F(ConfigUpdateTest, TestCombinationConditionReplace) {
581     StatsdConfig config;
582     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
583     *config.add_atom_matcher() = screenOnMatcher;
584     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
585     *config.add_atom_matcher() = screenOffMatcher;
586 
587     Predicate simple1 = CreateScreenIsOnPredicate();
588     *config.add_predicate() = simple1;
589     Predicate simple2 = CreateScreenIsOffPredicate();
590     *config.add_predicate() = simple2;
591 
592     Predicate combination1;
593     combination1.set_id(StringToId("COMBINATION1"));
594     Predicate_Combination* combinationInternal = combination1.mutable_combination();
595     combinationInternal->set_operation(LogicalOperation::NAND);
596     combinationInternal->add_predicate(simple1.id());
597     combinationInternal->add_predicate(simple2.id());
598     *config.add_predicate() = combination1;
599 
600     EXPECT_TRUE(initConfig(config));
601 
602     // Changing the logical operation changes the predicate definition, so it should be replaced.
603     combination1.mutable_combination()->set_operation(LogicalOperation::OR);
604 
605     StatsdConfig newConfig;
606     unordered_map<int64_t, int> newConditionTrackerMap;
607     *newConfig.add_predicate() = combination1;
608     newConditionTrackerMap[combination1.id()] = 0;
609     *newConfig.add_predicate() = simple2;
610     newConditionTrackerMap[simple2.id()] = 1;
611     *newConfig.add_predicate() = simple1;
612     newConditionTrackerMap[simple1.id()] = 2;
613 
614     set<int64_t> replacedMatchers;
615     vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
616     vector<bool> cycleTracker(3, false);
617     // Only update the combination. The simple conditions should not be evaluated.
618     EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
619                                                oldConditionTrackers, newConditionTrackerMap,
620                                                replacedMatchers, conditionsToUpdate, cycleTracker));
621     EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
622     EXPECT_EQ(conditionsToUpdate[1], UPDATE_UNKNOWN);
623     EXPECT_EQ(conditionsToUpdate[2], UPDATE_UNKNOWN);
624 }
625 
TEST_F(ConfigUpdateTest,TestCombinationConditionDepsChange)626 TEST_F(ConfigUpdateTest, TestCombinationConditionDepsChange) {
627     StatsdConfig config;
628     AtomMatcher screenOnMatcher = CreateScreenTurnedOnAtomMatcher();
629     *config.add_atom_matcher() = screenOnMatcher;
630     AtomMatcher screenOffMatcher = CreateScreenTurnedOffAtomMatcher();
631     *config.add_atom_matcher() = screenOffMatcher;
632 
633     Predicate simple1 = CreateScreenIsOnPredicate();
634     *config.add_predicate() = simple1;
635     Predicate simple2 = CreateScreenIsOffPredicate();
636     *config.add_predicate() = simple2;
637 
638     Predicate combination1;
639     combination1.set_id(StringToId("COMBINATION1"));
640     Predicate_Combination* combinationInternal = combination1.mutable_combination();
641     combinationInternal->set_operation(LogicalOperation::NAND);
642     combinationInternal->add_predicate(simple1.id());
643     combinationInternal->add_predicate(simple2.id());
644     *config.add_predicate() = combination1;
645 
646     EXPECT_TRUE(initConfig(config));
647 
648     simple2.mutable_simple_predicate()->set_count_nesting(false);
649 
650     StatsdConfig newConfig;
651     unordered_map<int64_t, int> newConditionTrackerMap;
652     *newConfig.add_predicate() = combination1;
653     newConditionTrackerMap[combination1.id()] = 0;
654     *newConfig.add_predicate() = simple2;
655     newConditionTrackerMap[simple2.id()] = 1;
656     *newConfig.add_predicate() = simple1;
657     newConditionTrackerMap[simple1.id()] = 2;
658 
659     set<int64_t> replacedMatchers;
660     vector<UpdateStatus> conditionsToUpdate(3, UPDATE_UNKNOWN);
661     vector<bool> cycleTracker(3, false);
662     // Only update the combination. Simple2 and combination1 must be evaluated.
663     EXPECT_TRUE(determineConditionUpdateStatus(newConfig, 0, oldConditionTrackerMap,
664                                                oldConditionTrackers, newConditionTrackerMap,
665                                                replacedMatchers, conditionsToUpdate, cycleTracker));
666     EXPECT_EQ(conditionsToUpdate[0], UPDATE_REPLACE);
667     EXPECT_EQ(conditionsToUpdate[1], UPDATE_REPLACE);
668 }
669 
TEST_F(ConfigUpdateTest,TestUpdateConditions)670 TEST_F(ConfigUpdateTest, TestUpdateConditions) {
671     StatsdConfig config;
672     // Add atom matchers. These are mostly needed for initStatsdConfig
673     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
674     int64_t matcher1Id = matcher1.id();
675     *config.add_atom_matcher() = matcher1;
676 
677     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
678     int64_t matcher2Id = matcher2.id();
679     *config.add_atom_matcher() = matcher2;
680 
681     AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
682     int64_t matcher3Id = matcher3.id();
683     *config.add_atom_matcher() = matcher3;
684 
685     AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
686     int64_t matcher4Id = matcher4.id();
687     *config.add_atom_matcher() = matcher4;
688 
689     AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
690     int64_t matcher5Id = matcher5.id();
691     *config.add_atom_matcher() = matcher5;
692 
693     AtomMatcher matcher6 = CreateBatterySaverModeStopAtomMatcher();
694     int64_t matcher6Id = matcher6.id();
695     *config.add_atom_matcher() = matcher6;
696 
697     // Add the predicates.
698     // Will be preserved.
699     Predicate simple1 = CreateScreenIsOnPredicate();
700     int64_t simple1Id = simple1.id();
701     *config.add_predicate() = simple1;
702 
703     // Will be preserved.
704     Predicate simple2 = CreateScheduledJobPredicate();
705     int64_t simple2Id = simple2.id();
706     *config.add_predicate() = simple2;
707 
708     // Will be replaced.
709     Predicate simple3 = CreateBatterySaverModePredicate();
710     int64_t simple3Id = simple3.id();
711     *config.add_predicate() = simple3;
712 
713     // Will be preserved
714     Predicate combination1;
715     combination1.set_id(StringToId("COMBINATION1"));
716     combination1.mutable_combination()->set_operation(LogicalOperation::AND);
717     combination1.mutable_combination()->add_predicate(simple1Id);
718     combination1.mutable_combination()->add_predicate(simple2Id);
719     int64_t combination1Id = combination1.id();
720     *config.add_predicate() = combination1;
721 
722     // Will be replaced since simple3 will be replaced.
723     Predicate combination2;
724     combination2.set_id(StringToId("COMBINATION2"));
725     combination2.mutable_combination()->set_operation(LogicalOperation::OR);
726     combination2.mutable_combination()->add_predicate(simple1Id);
727     combination2.mutable_combination()->add_predicate(simple3Id);
728     int64_t combination2Id = combination2.id();
729     *config.add_predicate() = combination2;
730 
731     // Will be removed.
732     Predicate combination3;
733     combination3.set_id(StringToId("COMBINATION3"));
734     combination3.mutable_combination()->set_operation(LogicalOperation::NOT);
735     combination3.mutable_combination()->add_predicate(simple2Id);
736     int64_t combination3Id = combination3.id();
737     *config.add_predicate() = combination3;
738 
739     EXPECT_TRUE(initConfig(config));
740 
741     // Mark marcher 5 as replaced. Causes simple3, and therefore combination2 to be replaced.
742     set<int64_t> replacedMatchers;
743     replacedMatchers.insert(matcher6Id);
744 
745     // Change the condition of simple1 to false.
746     ASSERT_EQ(oldConditionTrackers[0]->getConditionId(), simple1Id);
747     LogEvent event(/*uid=*/0, /*pid=*/0);  // Empty event is fine since there are no dimensions.
748     // Mark the stop matcher as matched, condition should be false.
749     vector<MatchingState> eventMatcherValues(6, MatchingState::kNotMatched);
750     eventMatcherValues[1] = MatchingState::kMatched;
751     vector<ConditionState> tmpConditionCache(6, ConditionState::kNotEvaluated);
752     vector<bool> conditionChangeCache(6, false);
753     oldConditionTrackers[0]->evaluateCondition(event, eventMatcherValues, oldConditionTrackers,
754                                                tmpConditionCache, conditionChangeCache);
755     EXPECT_EQ(tmpConditionCache[0], ConditionState::kFalse);
756     EXPECT_EQ(conditionChangeCache[0], true);
757 
758     // New combination predicate. Should have an initial condition of true since it is NOT(simple1).
759     Predicate combination4;
760     combination4.set_id(StringToId("COMBINATION4"));
761     combination4.mutable_combination()->set_operation(LogicalOperation::NOT);
762     combination4.mutable_combination()->add_predicate(simple1Id);
763     int64_t combination4Id = combination4.id();
764     *config.add_predicate() = combination4;
765 
766     // Map the matchers in reverse order to force the indices to change.
767     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
768     const int matcher6Index = 0;
769     newAtomMatchingTrackerMap[matcher6Id] = 0;
770     const int matcher5Index = 1;
771     newAtomMatchingTrackerMap[matcher5Id] = 1;
772     const int matcher4Index = 2;
773     newAtomMatchingTrackerMap[matcher4Id] = 2;
774     const int matcher3Index = 3;
775     newAtomMatchingTrackerMap[matcher3Id] = 3;
776     const int matcher2Index = 4;
777     newAtomMatchingTrackerMap[matcher2Id] = 4;
778     const int matcher1Index = 5;
779     newAtomMatchingTrackerMap[matcher1Id] = 5;
780 
781     StatsdConfig newConfig;
782     *newConfig.add_predicate() = simple3;
783     const int simple3Index = 0;
784     *newConfig.add_predicate() = combination2;
785     const int combination2Index = 1;
786     *newConfig.add_predicate() = combination4;
787     const int combination4Index = 2;
788     *newConfig.add_predicate() = simple2;
789     const int simple2Index = 3;
790     *newConfig.add_predicate() = combination1;
791     const int combination1Index = 4;
792     *newConfig.add_predicate() = simple1;
793     const int simple1Index = 5;
794 
795     unordered_map<int64_t, int> newConditionTrackerMap;
796     vector<sp<ConditionTracker>> newConditionTrackers;
797     unordered_map<int, vector<int>> trackerToConditionMap;
798     std::vector<ConditionState> conditionCache;
799     std::set<int64_t> replacedConditions;
800     EXPECT_TRUE(updateConditions(key, newConfig, newAtomMatchingTrackerMap, replacedMatchers,
801                                  oldConditionTrackerMap, oldConditionTrackers,
802                                  newConditionTrackerMap, newConditionTrackers,
803                                  trackerToConditionMap, conditionCache, replacedConditions));
804 
805     unordered_map<int64_t, int> expectedConditionTrackerMap = {
806             {simple1Id, simple1Index},           {simple2Id, simple2Index},
807             {simple3Id, simple3Index},           {combination1Id, combination1Index},
808             {combination2Id, combination2Index}, {combination4Id, combination4Index},
809     };
810     EXPECT_THAT(newConditionTrackerMap, ContainerEq(expectedConditionTrackerMap));
811 
812     ASSERT_EQ(newConditionTrackers.size(), 6);
813     // Make sure all conditions are initialized:
814     for (const sp<ConditionTracker>& tracker : newConditionTrackers) {
815         EXPECT_TRUE(tracker->mInitialized);
816     }
817 
818     // Make sure preserved conditions are the same.
819     EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple1Id)],
820               newConditionTrackers[newConditionTrackerMap.at(simple1Id)]);
821     EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(simple2Id)],
822               newConditionTrackers[newConditionTrackerMap.at(simple2Id)]);
823     EXPECT_EQ(oldConditionTrackers[oldConditionTrackerMap.at(combination1Id)],
824               newConditionTrackers[newConditionTrackerMap.at(combination1Id)]);
825 
826     // Make sure replaced conditions are different and included in replacedConditions.
827     EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(simple3Id)],
828               newConditionTrackers[newConditionTrackerMap.at(simple3Id)]);
829     EXPECT_NE(oldConditionTrackers[oldConditionTrackerMap.at(combination2Id)],
830               newConditionTrackers[newConditionTrackerMap.at(combination2Id)]);
831     EXPECT_THAT(replacedConditions, ContainerEq(set({simple3Id, combination2Id})));
832 
833     // Verify the trackerToConditionMap
834     ASSERT_EQ(trackerToConditionMap.size(), 6);
835     const vector<int>& matcher1Conditions = trackerToConditionMap[matcher1Index];
836     EXPECT_THAT(matcher1Conditions, UnorderedElementsAre(simple1Index, combination1Index,
837                                                          combination2Index, combination4Index));
838     const vector<int>& matcher2Conditions = trackerToConditionMap[matcher2Index];
839     EXPECT_THAT(matcher2Conditions, UnorderedElementsAre(simple1Index, combination1Index,
840                                                          combination2Index, combination4Index));
841     const vector<int>& matcher3Conditions = trackerToConditionMap[matcher3Index];
842     EXPECT_THAT(matcher3Conditions, UnorderedElementsAre(simple2Index, combination1Index));
843     const vector<int>& matcher4Conditions = trackerToConditionMap[matcher4Index];
844     EXPECT_THAT(matcher4Conditions, UnorderedElementsAre(simple2Index, combination1Index));
845     const vector<int>& matcher5Conditions = trackerToConditionMap[matcher5Index];
846     EXPECT_THAT(matcher5Conditions, UnorderedElementsAre(simple3Index, combination2Index));
847     const vector<int>& matcher6Conditions = trackerToConditionMap[matcher6Index];
848     EXPECT_THAT(matcher6Conditions, UnorderedElementsAre(simple3Index, combination2Index));
849 
850     // Verify the conditionCache. Specifically, simple1 is false and combination4 is true.
851     ASSERT_EQ(conditionCache.size(), 6);
852     EXPECT_EQ(conditionCache[simple1Index], ConditionState::kFalse);
853     EXPECT_EQ(conditionCache[simple2Index], ConditionState::kUnknown);
854     EXPECT_EQ(conditionCache[simple3Index], ConditionState::kUnknown);
855     EXPECT_EQ(conditionCache[combination1Index], ConditionState::kUnknown);
856     EXPECT_EQ(conditionCache[combination2Index], ConditionState::kUnknown);
857     EXPECT_EQ(conditionCache[combination4Index], ConditionState::kTrue);
858 
859     // Verify tracker indices/ids are correct.
860     EXPECT_EQ(newConditionTrackers[simple1Index]->getConditionId(), simple1Id);
861     EXPECT_EQ(newConditionTrackers[simple1Index]->mIndex, simple1Index);
862     EXPECT_TRUE(newConditionTrackers[simple1Index]->IsSimpleCondition());
863     EXPECT_EQ(newConditionTrackers[simple2Index]->getConditionId(), simple2Id);
864     EXPECT_EQ(newConditionTrackers[simple2Index]->mIndex, simple2Index);
865     EXPECT_TRUE(newConditionTrackers[simple2Index]->IsSimpleCondition());
866     EXPECT_EQ(newConditionTrackers[simple3Index]->getConditionId(), simple3Id);
867     EXPECT_EQ(newConditionTrackers[simple3Index]->mIndex, simple3Index);
868     EXPECT_TRUE(newConditionTrackers[simple3Index]->IsSimpleCondition());
869     EXPECT_EQ(newConditionTrackers[combination1Index]->getConditionId(), combination1Id);
870     EXPECT_EQ(newConditionTrackers[combination1Index]->mIndex, combination1Index);
871     EXPECT_FALSE(newConditionTrackers[combination1Index]->IsSimpleCondition());
872     EXPECT_EQ(newConditionTrackers[combination2Index]->getConditionId(), combination2Id);
873     EXPECT_EQ(newConditionTrackers[combination2Index]->mIndex, combination2Index);
874     EXPECT_FALSE(newConditionTrackers[combination2Index]->IsSimpleCondition());
875     EXPECT_EQ(newConditionTrackers[combination4Index]->getConditionId(), combination4Id);
876     EXPECT_EQ(newConditionTrackers[combination4Index]->mIndex, combination4Index);
877     EXPECT_FALSE(newConditionTrackers[combination4Index]->IsSimpleCondition());
878 
879     // Verify preserved trackers have indices updated.
880     SimpleConditionTracker* simpleTracker1 =
881             static_cast<SimpleConditionTracker*>(newConditionTrackers[simple1Index].get());
882     EXPECT_EQ(simpleTracker1->mStartLogMatcherIndex, matcher1Index);
883     EXPECT_EQ(simpleTracker1->mStopLogMatcherIndex, matcher2Index);
884     EXPECT_EQ(simpleTracker1->mStopAllLogMatcherIndex, -1);
885 
886     SimpleConditionTracker* simpleTracker2 =
887             static_cast<SimpleConditionTracker*>(newConditionTrackers[simple2Index].get());
888     EXPECT_EQ(simpleTracker2->mStartLogMatcherIndex, matcher3Index);
889     EXPECT_EQ(simpleTracker2->mStopLogMatcherIndex, matcher4Index);
890     EXPECT_EQ(simpleTracker2->mStopAllLogMatcherIndex, -1);
891 
892     CombinationConditionTracker* combinationTracker1 = static_cast<CombinationConditionTracker*>(
893             newConditionTrackers[combination1Index].get());
894     EXPECT_THAT(combinationTracker1->mChildren, UnorderedElementsAre(simple1Index, simple2Index));
895     EXPECT_THAT(combinationTracker1->mUnSlicedChildren,
896                 UnorderedElementsAre(simple1Index, simple2Index));
897     EXPECT_THAT(combinationTracker1->mSlicedChildren, IsEmpty());
898 }
899 
TEST_F(ConfigUpdateTest,TestUpdateStates)900 TEST_F(ConfigUpdateTest, TestUpdateStates) {
901     StatsdConfig config;
902     // Add states.
903     // Will be replaced because we add a state map.
904     State state1 = CreateScreenState();
905     int64_t state1Id = state1.id();
906     *config.add_state() = state1;
907 
908     // Will be preserved.
909     State state2 = CreateUidProcessState();
910     int64_t state2Id = state2.id();
911     *config.add_state() = state2;
912 
913     // Will be replaced since the atom changes from overlay to screen.
914     State state3 = CreateOverlayState();
915     int64_t state3Id = state3.id();
916     *config.add_state() = state3;
917 
918     EXPECT_TRUE(initConfig(config));
919 
920     // Change definitions of state1 and state3.
921     int64_t screenOnId = 0x4321, screenOffId = 0x1234;
922     *state1.mutable_map() = CreateScreenStateSimpleOnOffMap(screenOnId, screenOffId);
923     state3.set_atom_id(util::SCREEN_STATE_CHANGED);
924 
925     StatsdConfig newConfig;
926     *newConfig.add_state() = state3;
927     *newConfig.add_state() = state1;
928     *newConfig.add_state() = state2;
929 
930     unordered_map<int64_t, int> stateAtomIdMap;
931     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
932     map<int64_t, uint64_t> newStateProtoHashes;
933     set<int64_t> replacedStates;
934     EXPECT_TRUE(updateStates(newConfig, oldStateHashes, stateAtomIdMap, allStateGroupMaps,
935                              newStateProtoHashes, replacedStates));
936     EXPECT_THAT(replacedStates, ContainerEq(set({state1Id, state3Id})));
937 
938     unordered_map<int64_t, int> expectedStateAtomIdMap = {
939             {state1Id, util::SCREEN_STATE_CHANGED},
940             {state2Id, util::UID_PROCESS_STATE_CHANGED},
941             {state3Id, util::SCREEN_STATE_CHANGED}};
942     EXPECT_THAT(stateAtomIdMap, ContainerEq(expectedStateAtomIdMap));
943 
944     unordered_map<int64_t, unordered_map<int, int64_t>> expectedStateGroupMaps = {
945             {state1Id,
946              {{android::view::DisplayStateEnum::DISPLAY_STATE_OFF, screenOffId},
947               {android::view::DisplayStateEnum::DISPLAY_STATE_ON, screenOnId}}}};
948     EXPECT_THAT(allStateGroupMaps, ContainerEq(expectedStateGroupMaps));
949 }
950 
TEST_F(ConfigUpdateTest,TestEventMetricPreserve)951 TEST_F(ConfigUpdateTest, TestEventMetricPreserve) {
952     StatsdConfig config;
953     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
954     *config.add_atom_matcher() = startMatcher;
955     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
956     *config.add_atom_matcher() = stopMatcher;
957     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
958     *config.add_atom_matcher() = whatMatcher;
959 
960     Predicate predicate = CreateScreenIsOnPredicate();
961     *config.add_predicate() = predicate;
962 
963     EventMetric* metric = config.add_event_metric();
964     metric->set_id(12345);
965     metric->set_what(whatMatcher.id());
966     metric->set_condition(predicate.id());
967 
968     // Create an initial config.
969     EXPECT_TRUE(initConfig(config));
970 
971     unordered_map<int64_t, int> metricToActivationMap;
972     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
973     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
974                                                  metricToActivationMap,
975                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
976                                                  /*replacedStates=*/{}, metricsToUpdate));
977     EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
978 }
979 
TEST_F(ConfigUpdateTest,TestEventMetricActivationAdded)980 TEST_F(ConfigUpdateTest, TestEventMetricActivationAdded) {
981     StatsdConfig config;
982     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
983     *config.add_atom_matcher() = startMatcher;
984     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
985     *config.add_atom_matcher() = stopMatcher;
986     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
987     *config.add_atom_matcher() = whatMatcher;
988 
989     Predicate predicate = CreateScreenIsOnPredicate();
990     *config.add_predicate() = predicate;
991 
992     EventMetric* metric = config.add_event_metric();
993     metric->set_id(12345);
994     metric->set_what(whatMatcher.id());
995     metric->set_condition(predicate.id());
996 
997     // Create an initial config.
998     EXPECT_TRUE(initConfig(config));
999 
1000     // Add a metric activation, which should change the proto, causing replacement.
1001     MetricActivation* activation = config.add_metric_activation();
1002     activation->set_metric_id(12345);
1003     EventActivation* eventActivation = activation->add_event_activation();
1004     eventActivation->set_atom_matcher_id(startMatcher.id());
1005     eventActivation->set_ttl_seconds(5);
1006 
1007     unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
1008     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1009     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1010                                                  metricToActivationMap,
1011                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1012                                                  /*replacedStates=*/{}, metricsToUpdate));
1013     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1014 }
1015 
TEST_F(ConfigUpdateTest,TestEventMetricWhatChanged)1016 TEST_F(ConfigUpdateTest, TestEventMetricWhatChanged) {
1017     StatsdConfig config;
1018     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1019     *config.add_atom_matcher() = startMatcher;
1020     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1021     *config.add_atom_matcher() = stopMatcher;
1022     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1023     *config.add_atom_matcher() = whatMatcher;
1024 
1025     Predicate predicate = CreateScreenIsOnPredicate();
1026     *config.add_predicate() = predicate;
1027 
1028     EventMetric* metric = config.add_event_metric();
1029     metric->set_id(12345);
1030     metric->set_what(whatMatcher.id());
1031     metric->set_condition(predicate.id());
1032 
1033     // Create an initial config.
1034     EXPECT_TRUE(initConfig(config));
1035 
1036     unordered_map<int64_t, int> metricToActivationMap;
1037     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1038     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1039             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1040             /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1041             /*replacedStates=*/{}, metricsToUpdate));
1042     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1043 }
1044 
TEST_F(ConfigUpdateTest,TestEventMetricConditionChanged)1045 TEST_F(ConfigUpdateTest, TestEventMetricConditionChanged) {
1046     StatsdConfig config;
1047     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1048     *config.add_atom_matcher() = startMatcher;
1049     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1050     *config.add_atom_matcher() = stopMatcher;
1051     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1052     *config.add_atom_matcher() = whatMatcher;
1053 
1054     Predicate predicate = CreateScreenIsOnPredicate();
1055     *config.add_predicate() = predicate;
1056 
1057     EventMetric* metric = config.add_event_metric();
1058     metric->set_id(12345);
1059     metric->set_what(whatMatcher.id());
1060     metric->set_condition(predicate.id());
1061 
1062     // Create an initial config.
1063     EXPECT_TRUE(initConfig(config));
1064 
1065     unordered_map<int64_t, int> metricToActivationMap;
1066     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1067     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1068             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1069             /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1070             /*replacedStates=*/{}, metricsToUpdate));
1071     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1072 }
1073 
TEST_F(ConfigUpdateTest,TestMetricConditionLinkDepsChanged)1074 TEST_F(ConfigUpdateTest, TestMetricConditionLinkDepsChanged) {
1075     StatsdConfig config;
1076     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1077     *config.add_atom_matcher() = startMatcher;
1078     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1079     *config.add_atom_matcher() = stopMatcher;
1080     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1081     *config.add_atom_matcher() = whatMatcher;
1082 
1083     Predicate predicate = CreateScreenIsOnPredicate();
1084     *config.add_predicate() = predicate;
1085 
1086     Predicate linkPredicate = CreateScreenIsOffPredicate();
1087     *config.add_predicate() = linkPredicate;
1088 
1089     EventMetric* metric = config.add_event_metric();
1090     metric->set_id(12345);
1091     metric->set_what(whatMatcher.id());
1092     metric->set_condition(predicate.id());
1093     // Doesn't make sense as a real metric definition, but suffices as a separate predicate
1094     // From the one in the condition.
1095     MetricConditionLink* link = metric->add_links();
1096     link->set_condition(linkPredicate.id());
1097 
1098     // Create an initial config.
1099     EXPECT_TRUE(initConfig(config));
1100 
1101     unordered_map<int64_t, int> metricToActivationMap;
1102     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1103     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1104             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1105             /*replacedMatchers*/ {}, /*replacedConditions=*/{linkPredicate.id()},
1106             /*replacedStates=*/{}, metricsToUpdate));
1107     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1108 }
1109 
TEST_F(ConfigUpdateTest,TestEventMetricActivationDepsChange)1110 TEST_F(ConfigUpdateTest, TestEventMetricActivationDepsChange) {
1111     StatsdConfig config;
1112     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1113     *config.add_atom_matcher() = startMatcher;
1114     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1115     *config.add_atom_matcher() = stopMatcher;
1116     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1117     *config.add_atom_matcher() = whatMatcher;
1118 
1119     Predicate predicate = CreateScreenIsOnPredicate();
1120     *config.add_predicate() = predicate;
1121 
1122     EventMetric* metric = config.add_event_metric();
1123     metric->set_id(12345);
1124     metric->set_what(whatMatcher.id());
1125     metric->set_condition(predicate.id());
1126 
1127     MetricActivation* activation = config.add_metric_activation();
1128     activation->set_metric_id(12345);
1129     EventActivation* eventActivation = activation->add_event_activation();
1130     eventActivation->set_atom_matcher_id(startMatcher.id());
1131     eventActivation->set_ttl_seconds(5);
1132 
1133     // Create an initial config.
1134     EXPECT_TRUE(initConfig(config));
1135 
1136     unordered_map<int64_t, int> metricToActivationMap = {{12345, 0}};
1137     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1138     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1139             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1140             /*replacedMatchers*/ {startMatcher.id()}, /*replacedConditions=*/{},
1141             /*replacedStates=*/{}, metricsToUpdate));
1142     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1143 }
1144 
TEST_F(ConfigUpdateTest,TestCountMetricPreserve)1145 TEST_F(ConfigUpdateTest, TestCountMetricPreserve) {
1146     StatsdConfig config;
1147     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1148     *config.add_atom_matcher() = startMatcher;
1149     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1150     *config.add_atom_matcher() = stopMatcher;
1151     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1152     *config.add_atom_matcher() = whatMatcher;
1153 
1154     Predicate predicate = CreateScreenIsOnPredicate();
1155     *config.add_predicate() = predicate;
1156     State sliceState = CreateScreenState();
1157     *config.add_state() = sliceState;
1158 
1159     CountMetric* metric = config.add_count_metric();
1160     metric->set_id(12345);
1161     metric->set_what(whatMatcher.id());
1162     metric->set_condition(predicate.id());
1163     metric->add_slice_by_state(sliceState.id());
1164     metric->set_bucket(ONE_HOUR);
1165 
1166     // Create an initial config.
1167     EXPECT_TRUE(initConfig(config));
1168 
1169     unordered_map<int64_t, int> metricToActivationMap;
1170     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1171     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1172                                                  metricToActivationMap,
1173                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1174                                                  /*replacedStates=*/{}, metricsToUpdate));
1175     EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1176 }
1177 
TEST_F(ConfigUpdateTest,TestCountMetricDefinitionChange)1178 TEST_F(ConfigUpdateTest, TestCountMetricDefinitionChange) {
1179     StatsdConfig config;
1180     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1181     *config.add_atom_matcher() = startMatcher;
1182     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1183     *config.add_atom_matcher() = stopMatcher;
1184     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1185     *config.add_atom_matcher() = whatMatcher;
1186 
1187     Predicate predicate = CreateScreenIsOnPredicate();
1188     *config.add_predicate() = predicate;
1189 
1190     CountMetric* metric = config.add_count_metric();
1191     metric->set_id(12345);
1192     metric->set_what(whatMatcher.id());
1193     metric->set_condition(predicate.id());
1194     metric->set_bucket(ONE_HOUR);
1195 
1196     // Create an initial config.
1197     EXPECT_TRUE(initConfig(config));
1198 
1199     // Change bucket size, which should change the proto, causing replacement.
1200     metric->set_bucket(TEN_MINUTES);
1201 
1202     unordered_map<int64_t, int> metricToActivationMap;
1203     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1204     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1205                                                  metricToActivationMap,
1206                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1207                                                  /*replacedStates=*/{}, metricsToUpdate));
1208     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1209 }
1210 
TEST_F(ConfigUpdateTest,TestCountMetricWhatChanged)1211 TEST_F(ConfigUpdateTest, TestCountMetricWhatChanged) {
1212     StatsdConfig config;
1213     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1214     *config.add_atom_matcher() = startMatcher;
1215     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1216     *config.add_atom_matcher() = stopMatcher;
1217     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1218     *config.add_atom_matcher() = whatMatcher;
1219 
1220     Predicate predicate = CreateScreenIsOnPredicate();
1221     *config.add_predicate() = predicate;
1222 
1223     CountMetric* metric = config.add_count_metric();
1224     metric->set_id(12345);
1225     metric->set_what(whatMatcher.id());
1226     metric->set_condition(predicate.id());
1227     metric->set_bucket(ONE_HOUR);
1228 
1229     // Create an initial config.
1230     EXPECT_TRUE(initConfig(config));
1231 
1232     unordered_map<int64_t, int> metricToActivationMap;
1233     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1234     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1235             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1236             /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1237             /*replacedStates=*/{}, metricsToUpdate));
1238     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1239 }
1240 
TEST_F(ConfigUpdateTest,TestCountMetricConditionChanged)1241 TEST_F(ConfigUpdateTest, TestCountMetricConditionChanged) {
1242     StatsdConfig config;
1243     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1244     *config.add_atom_matcher() = startMatcher;
1245     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1246     *config.add_atom_matcher() = stopMatcher;
1247     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1248     *config.add_atom_matcher() = whatMatcher;
1249 
1250     Predicate predicate = CreateScreenIsOnPredicate();
1251     *config.add_predicate() = predicate;
1252 
1253     CountMetric* metric = config.add_count_metric();
1254     metric->set_id(12345);
1255     metric->set_what(whatMatcher.id());
1256     metric->set_condition(predicate.id());
1257     metric->set_bucket(ONE_HOUR);
1258 
1259     // Create an initial config.
1260     EXPECT_TRUE(initConfig(config));
1261 
1262     unordered_map<int64_t, int> metricToActivationMap;
1263     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1264     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1265             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1266             /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1267             /*replacedStates=*/{}, metricsToUpdate));
1268     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1269 }
1270 
TEST_F(ConfigUpdateTest,TestCountMetricStateChanged)1271 TEST_F(ConfigUpdateTest, TestCountMetricStateChanged) {
1272     StatsdConfig config;
1273     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1274     *config.add_atom_matcher() = startMatcher;
1275     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1276     *config.add_atom_matcher() = stopMatcher;
1277     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1278     *config.add_atom_matcher() = whatMatcher;
1279 
1280     State sliceState = CreateScreenState();
1281     *config.add_state() = sliceState;
1282 
1283     CountMetric* metric = config.add_count_metric();
1284     metric->set_id(12345);
1285     metric->set_what(whatMatcher.id());
1286     metric->add_slice_by_state(sliceState.id());
1287     metric->set_bucket(ONE_HOUR);
1288 
1289     // Create an initial config.
1290     EXPECT_TRUE(initConfig(config));
1291 
1292     unordered_map<int64_t, int> metricToActivationMap;
1293     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1294     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1295             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1296             /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1297             /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
1298     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1299 }
1300 
TEST_F(ConfigUpdateTest,TestGaugeMetricPreserve)1301 TEST_F(ConfigUpdateTest, TestGaugeMetricPreserve) {
1302     StatsdConfig config;
1303     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1304     *config.add_atom_matcher() = startMatcher;
1305     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1306     *config.add_atom_matcher() = stopMatcher;
1307     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1308     *config.add_atom_matcher() = whatMatcher;
1309 
1310     Predicate predicate = CreateScreenIsOnPredicate();
1311     *config.add_predicate() = predicate;
1312 
1313     *config.add_gauge_metric() = createGaugeMetric(
1314             "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);
1315 
1316     EXPECT_TRUE(initConfig(config));
1317 
1318     unordered_map<int64_t, int> metricToActivationMap;
1319     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1320     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1321                                                  metricToActivationMap,
1322                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1323                                                  /*replacedStates=*/{}, metricsToUpdate));
1324     EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1325 }
1326 
TEST_F(ConfigUpdateTest,TestGaugeMetricDefinitionChange)1327 TEST_F(ConfigUpdateTest, TestGaugeMetricDefinitionChange) {
1328     StatsdConfig config;
1329     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1330     *config.add_atom_matcher() = whatMatcher;
1331 
1332     *config.add_gauge_metric() = createGaugeMetric(
1333             "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
1334 
1335     EXPECT_TRUE(initConfig(config));
1336 
1337     // Change split bucket on app upgrade, which should change the proto, causing replacement.
1338     config.mutable_gauge_metric(0)->set_split_bucket_for_app_upgrade(false);
1339 
1340     unordered_map<int64_t, int> metricToActivationMap;
1341     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1342     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1343                                                  metricToActivationMap,
1344                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1345                                                  /*replacedStates=*/{}, metricsToUpdate));
1346     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1347 }
1348 
TEST_F(ConfigUpdateTest,TestGaugeMetricWhatChanged)1349 TEST_F(ConfigUpdateTest, TestGaugeMetricWhatChanged) {
1350     StatsdConfig config;
1351     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1352     *config.add_atom_matcher() = whatMatcher;
1353 
1354     *config.add_gauge_metric() = createGaugeMetric(
1355             "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
1356 
1357     EXPECT_TRUE(initConfig(config));
1358 
1359     unordered_map<int64_t, int> metricToActivationMap;
1360     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1361     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1362             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1363             /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1364             /*replacedStates=*/{}, metricsToUpdate));
1365     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1366 }
1367 
TEST_F(ConfigUpdateTest,TestGaugeMetricConditionChanged)1368 TEST_F(ConfigUpdateTest, TestGaugeMetricConditionChanged) {
1369     StatsdConfig config;
1370     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1371     *config.add_atom_matcher() = startMatcher;
1372     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1373     *config.add_atom_matcher() = stopMatcher;
1374     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1375     *config.add_atom_matcher() = whatMatcher;
1376 
1377     Predicate predicate = CreateScreenIsOnPredicate();
1378     *config.add_predicate() = predicate;
1379 
1380     *config.add_gauge_metric() = createGaugeMetric(
1381             "GAUGE1", whatMatcher.id(), GaugeMetric::RANDOM_ONE_SAMPLE, predicate.id(), nullopt);
1382 
1383     EXPECT_TRUE(initConfig(config));
1384 
1385     unordered_map<int64_t, int> metricToActivationMap;
1386     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1387     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1388             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1389             /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1390             /*replacedStates=*/{}, metricsToUpdate));
1391     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1392 }
1393 
TEST_F(ConfigUpdateTest,TestGaugeMetricTriggerEventChanged)1394 TEST_F(ConfigUpdateTest, TestGaugeMetricTriggerEventChanged) {
1395     StatsdConfig config;
1396     AtomMatcher triggerEvent = CreateScreenTurnedOnAtomMatcher();
1397     *config.add_atom_matcher() = triggerEvent;
1398     AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1399     *config.add_atom_matcher() = whatMatcher;
1400 
1401     *config.add_gauge_metric() = createGaugeMetric(
1402             "GAUGE1", whatMatcher.id(), GaugeMetric::FIRST_N_SAMPLES, nullopt, triggerEvent.id());
1403 
1404     EXPECT_TRUE(initConfig(config));
1405 
1406     unordered_map<int64_t, int> metricToActivationMap;
1407     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1408     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1409             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1410             /*replacedMatchers*/ {triggerEvent.id()}, /*replacedConditions=*/{},
1411             /*replacedStates=*/{}, metricsToUpdate));
1412     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1413 }
1414 
TEST_F(ConfigUpdateTest,TestDurationMetricPreserve)1415 TEST_F(ConfigUpdateTest, TestDurationMetricPreserve) {
1416     StatsdConfig config;
1417     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1418     *config.add_atom_matcher() = startMatcher;
1419     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1420     *config.add_atom_matcher() = stopMatcher;
1421 
1422     Predicate what = CreateScreenIsOnPredicate();
1423     *config.add_predicate() = what;
1424     Predicate condition = CreateScreenIsOffPredicate();
1425     *config.add_predicate() = condition;
1426 
1427     State sliceState = CreateScreenState();
1428     *config.add_state() = sliceState;
1429 
1430     *config.add_duration_metric() =
1431             createDurationMetric("DURATION1", what.id(), condition.id(), {sliceState.id()});
1432     EXPECT_TRUE(initConfig(config));
1433 
1434     unordered_map<int64_t, int> metricToActivationMap;
1435     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1436     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1437                                                  metricToActivationMap,
1438                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1439                                                  /*replacedStates=*/{}, metricsToUpdate));
1440     EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1441 }
1442 
TEST_F(ConfigUpdateTest,TestDurationMetricDefinitionChange)1443 TEST_F(ConfigUpdateTest, TestDurationMetricDefinitionChange) {
1444     StatsdConfig config;
1445     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1446     *config.add_atom_matcher() = startMatcher;
1447     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1448     *config.add_atom_matcher() = stopMatcher;
1449 
1450     Predicate what = CreateScreenIsOnPredicate();
1451     *config.add_predicate() = what;
1452 
1453     *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
1454     EXPECT_TRUE(initConfig(config));
1455 
1456     config.mutable_duration_metric(0)->set_aggregation_type(DurationMetric::MAX_SPARSE);
1457 
1458     unordered_map<int64_t, int> metricToActivationMap;
1459     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1460     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1461                                                  metricToActivationMap, /*replacedMatchers*/ {},
1462                                                  /*replacedConditions=*/{}, /*replacedStates=*/{},
1463                                                  metricsToUpdate));
1464     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1465 }
1466 
TEST_F(ConfigUpdateTest,TestDurationMetricWhatChanged)1467 TEST_F(ConfigUpdateTest, TestDurationMetricWhatChanged) {
1468     StatsdConfig config;
1469     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1470     *config.add_atom_matcher() = startMatcher;
1471     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1472     *config.add_atom_matcher() = stopMatcher;
1473 
1474     Predicate what = CreateScreenIsOnPredicate();
1475     *config.add_predicate() = what;
1476 
1477     *config.add_duration_metric() = createDurationMetric("DURATION1", what.id(), nullopt, {});
1478     EXPECT_TRUE(initConfig(config));
1479 
1480     unordered_map<int64_t, int> metricToActivationMap;
1481     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1482     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1483             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1484             /*replacedMatchers*/ {}, /*replacedConditions=*/{what.id()},
1485             /*replacedStates=*/{}, metricsToUpdate));
1486     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1487 }
1488 
TEST_F(ConfigUpdateTest,TestDurationMetricConditionChanged)1489 TEST_F(ConfigUpdateTest, TestDurationMetricConditionChanged) {
1490     StatsdConfig config;
1491     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1492     *config.add_atom_matcher() = startMatcher;
1493     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1494     *config.add_atom_matcher() = stopMatcher;
1495 
1496     Predicate what = CreateScreenIsOnPredicate();
1497     *config.add_predicate() = what;
1498     Predicate condition = CreateScreenIsOffPredicate();
1499     *config.add_predicate() = condition;
1500 
1501     *config.add_duration_metric() = createDurationMetric("DURATION", what.id(), condition.id(), {});
1502     EXPECT_TRUE(initConfig(config));
1503 
1504     unordered_map<int64_t, int> metricToActivationMap;
1505     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1506     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1507             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1508             /*replacedMatchers*/ {}, /*replacedConditions=*/{condition.id()},
1509             /*replacedStates=*/{}, metricsToUpdate));
1510     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1511 }
1512 
TEST_F(ConfigUpdateTest,TestDurationMetricStateChange)1513 TEST_F(ConfigUpdateTest, TestDurationMetricStateChange) {
1514     StatsdConfig config;
1515     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1516     *config.add_atom_matcher() = startMatcher;
1517     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1518     *config.add_atom_matcher() = stopMatcher;
1519 
1520     Predicate what = CreateScreenIsOnPredicate();
1521     *config.add_predicate() = what;
1522 
1523     State sliceState = CreateScreenState();
1524     *config.add_state() = sliceState;
1525 
1526     *config.add_duration_metric() =
1527             createDurationMetric("DURATION1", what.id(), nullopt, {sliceState.id()});
1528     EXPECT_TRUE(initConfig(config));
1529 
1530     unordered_map<int64_t, int> metricToActivationMap;
1531     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1532     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1533             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1534             /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1535             /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
1536     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1537 }
1538 
TEST_F(ConfigUpdateTest,TestValueMetricPreserve)1539 TEST_F(ConfigUpdateTest, TestValueMetricPreserve) {
1540     StatsdConfig config;
1541     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1542     *config.add_atom_matcher() = startMatcher;
1543     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1544     *config.add_atom_matcher() = stopMatcher;
1545     AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1546     *config.add_atom_matcher() = whatMatcher;
1547 
1548     Predicate predicate = CreateScreenIsOnPredicate();
1549     *config.add_predicate() = predicate;
1550     State sliceState = CreateScreenState();
1551     *config.add_state() = sliceState;
1552 
1553     *config.add_value_metric() =
1554             createValueMetric("VALUE1", whatMatcher, 2, predicate.id(), {sliceState.id()});
1555     EXPECT_TRUE(initConfig(config));
1556 
1557     unordered_map<int64_t, int> metricToActivationMap;
1558     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1559     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1560                                                  metricToActivationMap,
1561                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1562                                                  /*replacedStates=*/{}, metricsToUpdate));
1563     EXPECT_EQ(metricsToUpdate[0], UPDATE_PRESERVE);
1564 }
1565 
TEST_F(ConfigUpdateTest,TestValueMetricDefinitionChange)1566 TEST_F(ConfigUpdateTest, TestValueMetricDefinitionChange) {
1567     StatsdConfig config;
1568     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1569     *config.add_atom_matcher() = whatMatcher;
1570 
1571     *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, 2, nullopt, {});
1572     EXPECT_TRUE(initConfig(config));
1573 
1574     // Change skip zero diff output, which should change the proto, causing replacement.
1575     config.mutable_value_metric(0)->set_skip_zero_diff_output(true);
1576 
1577     unordered_map<int64_t, int> metricToActivationMap;
1578     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1579     EXPECT_TRUE(determineAllMetricUpdateStatuses(config, oldMetricProducerMap, oldMetricProducers,
1580                                                  metricToActivationMap,
1581                                                  /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1582                                                  /*replacedStates=*/{}, metricsToUpdate));
1583     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1584 }
1585 
TEST_F(ConfigUpdateTest,TestValueMetricWhatChanged)1586 TEST_F(ConfigUpdateTest, TestValueMetricWhatChanged) {
1587     StatsdConfig config;
1588     AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1589     *config.add_atom_matcher() = whatMatcher;
1590 
1591     *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, 2, nullopt, {});
1592     EXPECT_TRUE(initConfig(config));
1593 
1594     unordered_map<int64_t, int> metricToActivationMap;
1595     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1596     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1597             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1598             /*replacedMatchers*/ {whatMatcher.id()}, /*replacedConditions=*/{},
1599             /*replacedStates=*/{}, metricsToUpdate));
1600     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1601 }
1602 
TEST_F(ConfigUpdateTest,TestValueMetricConditionChanged)1603 TEST_F(ConfigUpdateTest, TestValueMetricConditionChanged) {
1604     StatsdConfig config;
1605     AtomMatcher startMatcher = CreateScreenTurnedOnAtomMatcher();
1606     *config.add_atom_matcher() = startMatcher;
1607     AtomMatcher stopMatcher = CreateScreenTurnedOffAtomMatcher();
1608     *config.add_atom_matcher() = stopMatcher;
1609     AtomMatcher whatMatcher = CreateTemperatureAtomMatcher();
1610     *config.add_atom_matcher() = whatMatcher;
1611 
1612     Predicate predicate = CreateScreenIsOnPredicate();
1613     *config.add_predicate() = predicate;
1614 
1615     *config.add_value_metric() = createValueMetric("VALUE1", whatMatcher, 2, predicate.id(), {});
1616     EXPECT_TRUE(initConfig(config));
1617 
1618     unordered_map<int64_t, int> metricToActivationMap;
1619     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1620     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1621             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1622             /*replacedMatchers*/ {}, /*replacedConditions=*/{predicate.id()},
1623             /*replacedStates=*/{}, metricsToUpdate));
1624     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1625 }
1626 
TEST_F(ConfigUpdateTest,TestValueMetricStateChanged)1627 TEST_F(ConfigUpdateTest, TestValueMetricStateChanged) {
1628     StatsdConfig config;
1629     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
1630     *config.add_atom_matcher() = whatMatcher;
1631 
1632     State sliceState = CreateScreenState();
1633     *config.add_state() = sliceState;
1634 
1635     *config.add_value_metric() =
1636             createValueMetric("VALUE1", whatMatcher, 2, nullopt, {sliceState.id()});
1637     EXPECT_TRUE(initConfig(config));
1638 
1639     unordered_map<int64_t, int> metricToActivationMap;
1640     vector<UpdateStatus> metricsToUpdate(1, UPDATE_UNKNOWN);
1641     EXPECT_TRUE(determineAllMetricUpdateStatuses(
1642             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
1643             /*replacedMatchers*/ {}, /*replacedConditions=*/{},
1644             /*replacedStates=*/{sliceState.id()}, metricsToUpdate));
1645     EXPECT_EQ(metricsToUpdate[0], UPDATE_REPLACE);
1646 }
1647 
TEST_F(ConfigUpdateTest,TestUpdateEventMetrics)1648 TEST_F(ConfigUpdateTest, TestUpdateEventMetrics) {
1649     StatsdConfig config;
1650 
1651     // Add atom matchers/predicates. These are mostly needed for initStatsdConfig
1652     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
1653     int64_t matcher1Id = matcher1.id();
1654     *config.add_atom_matcher() = matcher1;
1655 
1656     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
1657     int64_t matcher2Id = matcher2.id();
1658     *config.add_atom_matcher() = matcher2;
1659 
1660     AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
1661     int64_t matcher3Id = matcher3.id();
1662     *config.add_atom_matcher() = matcher3;
1663 
1664     AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
1665     int64_t matcher4Id = matcher4.id();
1666     *config.add_atom_matcher() = matcher4;
1667 
1668     AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
1669     int64_t matcher5Id = matcher5.id();
1670     *config.add_atom_matcher() = matcher5;
1671 
1672     Predicate predicate1 = CreateScreenIsOnPredicate();
1673     int64_t predicate1Id = predicate1.id();
1674     *config.add_predicate() = predicate1;
1675 
1676     Predicate predicate2 = CreateScheduledJobPredicate();
1677     int64_t predicate2Id = predicate2.id();
1678     *config.add_predicate() = predicate2;
1679 
1680     // Add a few event metrics.
1681     // Will be preserved.
1682     EventMetric event1 = createEventMetric("EVENT1", matcher1Id, predicate2Id);
1683     int64_t event1Id = event1.id();
1684     *config.add_event_metric() = event1;
1685 
1686     // Will be replaced.
1687     EventMetric event2 = createEventMetric("EVENT2", matcher2Id, nullopt);
1688     int64_t event2Id = event2.id();
1689     *config.add_event_metric() = event2;
1690 
1691     // Will be replaced.
1692     EventMetric event3 = createEventMetric("EVENT3", matcher3Id, nullopt);
1693     int64_t event3Id = event3.id();
1694     *config.add_event_metric() = event3;
1695 
1696     MetricActivation event3Activation;
1697     event3Activation.set_metric_id(event3Id);
1698     EventActivation* eventActivation = event3Activation.add_event_activation();
1699     eventActivation->set_atom_matcher_id(matcher5Id);
1700     eventActivation->set_ttl_seconds(5);
1701     *config.add_metric_activation() = event3Activation;
1702 
1703     // Will be replaced.
1704     EventMetric event4 = createEventMetric("EVENT4", matcher4Id, predicate1Id);
1705     int64_t event4Id = event4.id();
1706     *config.add_event_metric() = event4;
1707 
1708     // Will be deleted.
1709     EventMetric event5 = createEventMetric("EVENT5", matcher5Id, nullopt);
1710     int64_t event5Id = event5.id();
1711     *config.add_event_metric() = event5;
1712 
1713     EXPECT_TRUE(initConfig(config));
1714 
1715     // Used later to ensure the condition wizard is replaced. Get it before doing the update.
1716     sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
1717     EXPECT_EQ(oldConditionWizard->getStrongCount(), oldMetricProducers.size() + 1);
1718 
1719     // Add a condition to event2, causing it to be replaced.
1720     event2.set_condition(predicate1Id);
1721 
1722     // Mark matcher 5 as replaced. Causes event3 to be replaced.
1723     set<int64_t> replacedMatchers;
1724     replacedMatchers.insert(matcher5Id);
1725 
1726     // Mark predicate 1 as replaced. Causes event4 to be replaced.
1727     set<int64_t> replacedConditions;
1728     replacedConditions.insert(predicate1Id);
1729 
1730     // Fake that predicate 2 is true.
1731     ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
1732     oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
1733     EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);
1734 
1735     // New event metric. Should have an initial condition of true since it depends on predicate2.
1736     EventMetric event6 = createEventMetric("EVENT6", matcher3Id, predicate2Id);
1737     int64_t event6Id = event6.id();
1738     MetricActivation event6Activation;
1739     event6Activation.set_metric_id(event6Id);
1740     eventActivation = event6Activation.add_event_activation();
1741     eventActivation->set_atom_matcher_id(matcher5Id);
1742     eventActivation->set_ttl_seconds(20);
1743 
1744     // Map the matchers and predicates in reverse order to force the indices to change.
1745     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
1746     const int matcher5Index = 0;
1747     newAtomMatchingTrackerMap[matcher5Id] = 0;
1748     const int matcher4Index = 1;
1749     newAtomMatchingTrackerMap[matcher4Id] = 1;
1750     const int matcher3Index = 2;
1751     newAtomMatchingTrackerMap[matcher3Id] = 2;
1752     const int matcher2Index = 3;
1753     newAtomMatchingTrackerMap[matcher2Id] = 3;
1754     const int matcher1Index = 4;
1755     newAtomMatchingTrackerMap[matcher1Id] = 4;
1756     // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
1757     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
1758     std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
1759                       newAtomMatchingTrackers.begin());
1760 
1761     std::unordered_map<int64_t, int> newConditionTrackerMap;
1762     const int predicate2Index = 0;
1763     newConditionTrackerMap[predicate2Id] = 0;
1764     const int predicate1Index = 1;
1765     newConditionTrackerMap[predicate1Id] = 1;
1766     // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
1767     vector<sp<ConditionTracker>> newConditionTrackers(2);
1768     std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
1769                       newConditionTrackers.begin());
1770     // Fake that predicate2 is true.
1771     vector<ConditionState> conditionCache = {ConditionState::kTrue, ConditionState::kUnknown};
1772 
1773     StatsdConfig newConfig;
1774     *newConfig.add_event_metric() = event6;
1775     const int event6Index = 0;
1776     *newConfig.add_event_metric() = event3;
1777     const int event3Index = 1;
1778     *newConfig.add_event_metric() = event1;
1779     const int event1Index = 2;
1780     *newConfig.add_event_metric() = event4;
1781     const int event4Index = 3;
1782     *newConfig.add_event_metric() = event2;
1783     const int event2Index = 4;
1784     *newConfig.add_metric_activation() = event3Activation;
1785     *newConfig.add_metric_activation() = event6Activation;
1786 
1787     // Output data structures to validate.
1788     unordered_map<int64_t, int> newMetricProducerMap;
1789     vector<sp<MetricProducer>> newMetricProducers;
1790     unordered_map<int, vector<int>> conditionToMetricMap;
1791     unordered_map<int, vector<int>> trackerToMetricMap;
1792     set<int64_t> noReportMetricIds;
1793     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
1794     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
1795     vector<int> metricsWithActivation;
1796     set<int64_t> replacedMetrics;
1797     EXPECT_TRUE(updateMetrics(
1798             key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
1799             oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
1800             newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
1801             newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
1802             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
1803             newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
1804             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1805             metricsWithActivation, replacedMetrics));
1806 
1807     unordered_map<int64_t, int> expectedMetricProducerMap = {
1808             {event1Id, event1Index}, {event2Id, event2Index}, {event3Id, event3Index},
1809             {event4Id, event4Index}, {event6Id, event6Index},
1810     };
1811     EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
1812     EXPECT_EQ(replacedMetrics, set<int64_t>({event2Id, event3Id, event4Id}));
1813 
1814     // Make sure preserved metrics are the same.
1815     ASSERT_EQ(newMetricProducers.size(), 5);
1816     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(event1Id)],
1817               newMetricProducers[newMetricProducerMap.at(event1Id)]);
1818 
1819     // Make sure replaced metrics are different.
1820     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event2Id)],
1821               newMetricProducers[newMetricProducerMap.at(event2Id)]);
1822     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event3Id)],
1823               newMetricProducers[newMetricProducerMap.at(event3Id)]);
1824     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(event4Id)],
1825               newMetricProducers[newMetricProducerMap.at(event4Id)]);
1826 
1827     // Verify the conditionToMetricMap.
1828     ASSERT_EQ(conditionToMetricMap.size(), 2);
1829     const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
1830     EXPECT_THAT(condition1Metrics, UnorderedElementsAre(event2Index, event4Index));
1831     const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
1832     EXPECT_THAT(condition2Metrics, UnorderedElementsAre(event1Index, event6Index));
1833 
1834     // Verify the trackerToMetricMap.
1835     ASSERT_EQ(trackerToMetricMap.size(), 4);
1836     const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
1837     EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(event1Index));
1838     const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
1839     EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(event2Index));
1840     const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
1841     EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(event3Index, event6Index));
1842     const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
1843     EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(event4Index));
1844 
1845     // Verify event activation/deactivation maps.
1846     ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 1);
1847     EXPECT_THAT(activationAtomTrackerToMetricMap[matcher5Index],
1848                 UnorderedElementsAre(event3Index, event6Index));
1849     ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
1850     ASSERT_EQ(metricsWithActivation.size(), 2);
1851     EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(event3Index, event6Index));
1852 
1853     // Verify tracker indices/ids/conditions are correct.
1854     EXPECT_EQ(newMetricProducers[event1Index]->getMetricId(), event1Id);
1855     EXPECT_EQ(newMetricProducers[event1Index]->mConditionTrackerIndex, predicate2Index);
1856     EXPECT_EQ(newMetricProducers[event1Index]->mCondition, ConditionState::kTrue);
1857     EXPECT_EQ(newMetricProducers[event2Index]->getMetricId(), event2Id);
1858     EXPECT_EQ(newMetricProducers[event2Index]->mConditionTrackerIndex, predicate1Index);
1859     EXPECT_EQ(newMetricProducers[event2Index]->mCondition, ConditionState::kUnknown);
1860     EXPECT_EQ(newMetricProducers[event3Index]->getMetricId(), event3Id);
1861     EXPECT_EQ(newMetricProducers[event3Index]->mConditionTrackerIndex, -1);
1862     EXPECT_EQ(newMetricProducers[event3Index]->mCondition, ConditionState::kTrue);
1863     EXPECT_EQ(newMetricProducers[event4Index]->getMetricId(), event4Id);
1864     EXPECT_EQ(newMetricProducers[event4Index]->mConditionTrackerIndex, predicate1Index);
1865     EXPECT_EQ(newMetricProducers[event4Index]->mCondition, ConditionState::kUnknown);
1866     EXPECT_EQ(newMetricProducers[event6Index]->getMetricId(), event6Id);
1867     EXPECT_EQ(newMetricProducers[event6Index]->mConditionTrackerIndex, predicate2Index);
1868     EXPECT_EQ(newMetricProducers[event6Index]->mCondition, ConditionState::kTrue);
1869 
1870     sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
1871     EXPECT_NE(newConditionWizard, oldConditionWizard);
1872     EXPECT_EQ(newConditionWizard->getStrongCount(), newMetricProducers.size() + 1);
1873     oldMetricProducers.clear();
1874     // Only reference to the old wizard should be the one in the test.
1875     EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
1876 }
1877 
TEST_F(ConfigUpdateTest,TestUpdateCountMetrics)1878 TEST_F(ConfigUpdateTest, TestUpdateCountMetrics) {
1879     StatsdConfig config;
1880 
1881     // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
1882     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
1883     int64_t matcher1Id = matcher1.id();
1884     *config.add_atom_matcher() = matcher1;
1885 
1886     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
1887     int64_t matcher2Id = matcher2.id();
1888     *config.add_atom_matcher() = matcher2;
1889 
1890     AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
1891     int64_t matcher3Id = matcher3.id();
1892     *config.add_atom_matcher() = matcher3;
1893 
1894     AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
1895     int64_t matcher4Id = matcher4.id();
1896     *config.add_atom_matcher() = matcher4;
1897 
1898     AtomMatcher matcher5 = CreateBatterySaverModeStartAtomMatcher();
1899     int64_t matcher5Id = matcher5.id();
1900     *config.add_atom_matcher() = matcher5;
1901 
1902     Predicate predicate1 = CreateScreenIsOnPredicate();
1903     int64_t predicate1Id = predicate1.id();
1904     *config.add_predicate() = predicate1;
1905 
1906     State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
1907     int64_t state1Id = state1.id();
1908     *config.add_state() = state1;
1909 
1910     State state2 = CreateScreenState();
1911     int64_t state2Id = state2.id();
1912     *config.add_state() = state2;
1913 
1914     // Add a few count metrics.
1915     // Will be preserved.
1916     CountMetric count1 = createCountMetric("COUNT1", matcher1Id, predicate1Id, {state1Id});
1917     int64_t count1Id = count1.id();
1918     *config.add_count_metric() = count1;
1919 
1920     // Will be replaced.
1921     CountMetric count2 = createCountMetric("COUNT2", matcher2Id, nullopt, {});
1922     int64_t count2Id = count2.id();
1923     *config.add_count_metric() = count2;
1924 
1925     // Will be replaced.
1926     CountMetric count3 = createCountMetric("COUNT3", matcher3Id, nullopt, {});
1927     int64_t count3Id = count3.id();
1928     *config.add_count_metric() = count3;
1929 
1930     // Will be replaced.
1931     CountMetric count4 = createCountMetric("COUNT4", matcher4Id, nullopt, {state2Id});
1932     int64_t count4Id = count4.id();
1933     *config.add_count_metric() = count4;
1934 
1935     // Will be deleted.
1936     CountMetric count5 = createCountMetric("COUNT5", matcher5Id, nullopt, {});
1937     int64_t count5Id = count5.id();
1938     *config.add_count_metric() = count5;
1939 
1940     EXPECT_TRUE(initConfig(config));
1941 
1942     // Change bucket size of count2, causing it to be replaced.
1943     count2.set_bucket(ONE_HOUR);
1944 
1945     // Mark matcher 3 as replaced. Causes count3 to be replaced.
1946     set<int64_t> replacedMatchers;
1947     replacedMatchers.insert(matcher3Id);
1948 
1949     // Mark state 2 as replaced and change the state to be about a different atom.
1950     // Causes count4 to be replaced.
1951     set<int64_t> replacedStates;
1952     replacedStates.insert(state2Id);
1953     state2.set_atom_id(util::BATTERY_SAVER_MODE_STATE_CHANGED);
1954 
1955     // Fake that predicate 1 is true for count metric 1.
1956     ASSERT_EQ(oldMetricProducers[0]->getMetricId(), count1Id);
1957     oldMetricProducers[0]->onConditionChanged(true, /*timestamp=*/0);
1958     EXPECT_EQ(oldMetricProducers[0]->mCondition, ConditionState::kTrue);
1959 
1960     EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 1);
1961     // Tell the StateManager that the screen is on.
1962     unique_ptr<LogEvent> event =
1963             CreateScreenStateChangedEvent(0, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
1964     StateManager::getInstance().onLogEvent(*event);
1965 
1966     // New count metric. Should have an initial condition of true since it depends on predicate1.
1967     CountMetric count6 = createCountMetric("EVENT6", matcher2Id, predicate1Id, {state1Id});
1968     int64_t count6Id = count6.id();
1969 
1970     // Map the matchers and predicates in reverse order to force the indices to change.
1971     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
1972     const int matcher5Index = 0;
1973     newAtomMatchingTrackerMap[matcher5Id] = 0;
1974     const int matcher4Index = 1;
1975     newAtomMatchingTrackerMap[matcher4Id] = 1;
1976     const int matcher3Index = 2;
1977     newAtomMatchingTrackerMap[matcher3Id] = 2;
1978     const int matcher2Index = 3;
1979     newAtomMatchingTrackerMap[matcher2Id] = 3;
1980     const int matcher1Index = 4;
1981     newAtomMatchingTrackerMap[matcher1Id] = 4;
1982     // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
1983     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
1984     std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
1985                       newAtomMatchingTrackers.begin());
1986 
1987     std::unordered_map<int64_t, int> newConditionTrackerMap;
1988     const int predicate1Index = 0;
1989     newConditionTrackerMap[predicate1Id] = 0;
1990     // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
1991     vector<sp<ConditionTracker>> newConditionTrackers(1);
1992     std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
1993                       newConditionTrackers.begin());
1994     // Fake that predicate1 is true for all new metrics.
1995     vector<ConditionState> conditionCache = {ConditionState::kTrue};
1996 
1997     StatsdConfig newConfig;
1998     *newConfig.add_count_metric() = count6;
1999     const int count6Index = 0;
2000     *newConfig.add_count_metric() = count3;
2001     const int count3Index = 1;
2002     *newConfig.add_count_metric() = count1;
2003     const int count1Index = 2;
2004     *newConfig.add_count_metric() = count4;
2005     const int count4Index = 3;
2006     *newConfig.add_count_metric() = count2;
2007     const int count2Index = 4;
2008 
2009     *newConfig.add_state() = state1;
2010     *newConfig.add_state() = state2;
2011 
2012     unordered_map<int64_t, int> stateAtomIdMap;
2013     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
2014     map<int64_t, uint64_t> stateProtoHashes;
2015     EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));
2016     EXPECT_EQ(stateAtomIdMap[state2Id], util::BATTERY_SAVER_MODE_STATE_CHANGED);
2017 
2018     // Output data structures to validate.
2019     unordered_map<int64_t, int> newMetricProducerMap;
2020     vector<sp<MetricProducer>> newMetricProducers;
2021     unordered_map<int, vector<int>> conditionToMetricMap;
2022     unordered_map<int, vector<int>> trackerToMetricMap;
2023     set<int64_t> noReportMetricIds;
2024     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2025     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2026     vector<int> metricsWithActivation;
2027     set<int64_t> replacedMetrics;
2028     EXPECT_TRUE(updateMetrics(
2029             key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
2030             oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
2031             newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
2032             newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
2033             oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
2034             conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
2035             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
2036             metricsWithActivation, replacedMetrics));
2037 
2038     unordered_map<int64_t, int> expectedMetricProducerMap = {
2039             {count1Id, count1Index}, {count2Id, count2Index}, {count3Id, count3Index},
2040             {count4Id, count4Index}, {count6Id, count6Index},
2041     };
2042     EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
2043     EXPECT_EQ(replacedMetrics, set<int64_t>({count2Id, count3Id, count4Id}));
2044 
2045     // Make sure preserved metrics are the same.
2046     ASSERT_EQ(newMetricProducers.size(), 5);
2047     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(count1Id)],
2048               newMetricProducers[newMetricProducerMap.at(count1Id)]);
2049 
2050     // Make sure replaced metrics are different.
2051     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count2Id)],
2052               newMetricProducers[newMetricProducerMap.at(count2Id)]);
2053     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count3Id)],
2054               newMetricProducers[newMetricProducerMap.at(count3Id)]);
2055     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(count4Id)],
2056               newMetricProducers[newMetricProducerMap.at(count4Id)]);
2057 
2058     // Verify the conditionToMetricMap.
2059     ASSERT_EQ(conditionToMetricMap.size(), 1);
2060     const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
2061     EXPECT_THAT(condition1Metrics, UnorderedElementsAre(count1Index, count6Index));
2062 
2063     // Verify the trackerToMetricMap.
2064     ASSERT_EQ(trackerToMetricMap.size(), 4);
2065     const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2066     EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(count1Index));
2067     const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
2068     EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(count2Index, count6Index));
2069     const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2070     EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(count3Index));
2071     const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2072     EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(count4Index));
2073 
2074     // Verify event activation/deactivation maps.
2075     ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
2076     ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2077     ASSERT_EQ(metricsWithActivation.size(), 0);
2078 
2079     // Verify tracker indices/ids/conditions/states are correct.
2080     EXPECT_EQ(newMetricProducers[count1Index]->getMetricId(), count1Id);
2081     EXPECT_EQ(newMetricProducers[count1Index]->mConditionTrackerIndex, predicate1Index);
2082     EXPECT_EQ(newMetricProducers[count1Index]->mCondition, ConditionState::kTrue);
2083     EXPECT_THAT(newMetricProducers[count1Index]->getSlicedStateAtoms(),
2084                 UnorderedElementsAre(util::SCREEN_STATE_CHANGED));
2085     EXPECT_EQ(newMetricProducers[count2Index]->getMetricId(), count2Id);
2086     EXPECT_EQ(newMetricProducers[count2Index]->mConditionTrackerIndex, -1);
2087     EXPECT_EQ(newMetricProducers[count2Index]->mCondition, ConditionState::kTrue);
2088     EXPECT_TRUE(newMetricProducers[count2Index]->getSlicedStateAtoms().empty());
2089     EXPECT_EQ(newMetricProducers[count3Index]->getMetricId(), count3Id);
2090     EXPECT_EQ(newMetricProducers[count3Index]->mConditionTrackerIndex, -1);
2091     EXPECT_EQ(newMetricProducers[count3Index]->mCondition, ConditionState::kTrue);
2092     EXPECT_TRUE(newMetricProducers[count3Index]->getSlicedStateAtoms().empty());
2093     EXPECT_EQ(newMetricProducers[count4Index]->getMetricId(), count4Id);
2094     EXPECT_EQ(newMetricProducers[count4Index]->mConditionTrackerIndex, -1);
2095     EXPECT_EQ(newMetricProducers[count4Index]->mCondition, ConditionState::kTrue);
2096     EXPECT_THAT(newMetricProducers[count4Index]->getSlicedStateAtoms(),
2097                 UnorderedElementsAre(util::BATTERY_SAVER_MODE_STATE_CHANGED));
2098     EXPECT_EQ(newMetricProducers[count6Index]->getMetricId(), count6Id);
2099     EXPECT_EQ(newMetricProducers[count6Index]->mConditionTrackerIndex, predicate1Index);
2100     EXPECT_EQ(newMetricProducers[count6Index]->mCondition, ConditionState::kTrue);
2101     EXPECT_THAT(newMetricProducers[count6Index]->getSlicedStateAtoms(),
2102                 UnorderedElementsAre(util::SCREEN_STATE_CHANGED));
2103 
2104     oldMetricProducers.clear();
2105     // Ensure that the screen state StateTracker did not get deleted and replaced.
2106     EXPECT_EQ(StateManager::getInstance().getStateTrackersCount(), 2);
2107     FieldValue screenState;
2108     StateManager::getInstance().getStateValue(util::SCREEN_STATE_CHANGED, DEFAULT_DIMENSION_KEY,
2109                                               &screenState);
2110     EXPECT_EQ(screenState.mValue.int_value, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
2111 }
2112 
TEST_F(ConfigUpdateTest,TestUpdateGaugeMetrics)2113 TEST_F(ConfigUpdateTest, TestUpdateGaugeMetrics) {
2114     StatsdConfig config;
2115 
2116     // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
2117     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2118     int64_t matcher1Id = matcher1.id();
2119     *config.add_atom_matcher() = matcher1;
2120 
2121     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2122     int64_t matcher2Id = matcher2.id();
2123     *config.add_atom_matcher() = matcher2;
2124 
2125     AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
2126     int64_t matcher3Id = matcher3.id();
2127     *config.add_atom_matcher() = matcher3;
2128 
2129     AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
2130     int64_t matcher4Id = matcher4.id();
2131     *config.add_atom_matcher() = matcher4;
2132 
2133     AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
2134     int64_t matcher5Id = matcher5.id();
2135     *config.add_atom_matcher() = matcher5;
2136 
2137     Predicate predicate1 = CreateScreenIsOnPredicate();
2138     int64_t predicate1Id = predicate1.id();
2139     *config.add_predicate() = predicate1;
2140 
2141     // Add a few gauge metrics.
2142     // Will be preserved.
2143     GaugeMetric gauge1 = createGaugeMetric("GAUGE1", matcher4Id, GaugeMetric::FIRST_N_SAMPLES,
2144                                            predicate1Id, matcher1Id);
2145     int64_t gauge1Id = gauge1.id();
2146     *config.add_gauge_metric() = gauge1;
2147 
2148     // Will be replaced.
2149     GaugeMetric gauge2 =
2150             createGaugeMetric("GAUGE2", matcher1Id, GaugeMetric::FIRST_N_SAMPLES, nullopt, nullopt);
2151     int64_t gauge2Id = gauge2.id();
2152     *config.add_gauge_metric() = gauge2;
2153 
2154     // Will be replaced.
2155     GaugeMetric gauge3 = createGaugeMetric("GAUGE3", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
2156                                            nullopt, matcher3Id);
2157     int64_t gauge3Id = gauge3.id();
2158     *config.add_gauge_metric() = gauge3;
2159 
2160     // Will be replaced.
2161     GaugeMetric gauge4 = createGaugeMetric("GAUGE4", matcher3Id, GaugeMetric::RANDOM_ONE_SAMPLE,
2162                                            predicate1Id, nullopt);
2163     int64_t gauge4Id = gauge4.id();
2164     *config.add_gauge_metric() = gauge4;
2165 
2166     // Will be deleted.
2167     GaugeMetric gauge5 =
2168             createGaugeMetric("GAUGE5", matcher2Id, GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, {});
2169     int64_t gauge5Id = gauge5.id();
2170     *config.add_gauge_metric() = gauge5;
2171 
2172     EXPECT_TRUE(initConfig(config));
2173 
2174     // Used later to ensure the condition wizard is replaced. Get it before doing the update.
2175     sp<EventMatcherWizard> oldMatcherWizard =
2176             static_cast<GaugeMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard;
2177     EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);
2178 
2179     // Change gauge2, causing it to be replaced.
2180     gauge2.set_max_num_gauge_atoms_per_bucket(50);
2181 
2182     // Mark matcher 3 as replaced. Causes gauge3 and gauge4 to be replaced.
2183     set<int64_t> replacedMatchers = {matcher3Id};
2184 
2185     // New gauge metric.
2186     GaugeMetric gauge6 = createGaugeMetric("GAUGE6", matcher5Id, GaugeMetric::FIRST_N_SAMPLES,
2187                                            predicate1Id, matcher3Id);
2188     int64_t gauge6Id = gauge6.id();
2189 
2190     // Map the matchers and predicates in reverse order to force the indices to change.
2191     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
2192     const int matcher5Index = 0;
2193     newAtomMatchingTrackerMap[matcher5Id] = 0;
2194     const int matcher4Index = 1;
2195     newAtomMatchingTrackerMap[matcher4Id] = 1;
2196     const int matcher3Index = 2;
2197     newAtomMatchingTrackerMap[matcher3Id] = 2;
2198     const int matcher2Index = 3;
2199     newAtomMatchingTrackerMap[matcher2Id] = 3;
2200     const int matcher1Index = 4;
2201     newAtomMatchingTrackerMap[matcher1Id] = 4;
2202     // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2203     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
2204     std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2205                       newAtomMatchingTrackers.begin());
2206 
2207     std::unordered_map<int64_t, int> newConditionTrackerMap;
2208     const int predicate1Index = 0;
2209     newConditionTrackerMap[predicate1Id] = 0;
2210     // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
2211     vector<sp<ConditionTracker>> newConditionTrackers(1);
2212     std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
2213                       newConditionTrackers.begin());
2214     // Say that predicate1 is unknown since the initial condition never changed.
2215     vector<ConditionState> conditionCache = {ConditionState::kUnknown};
2216 
2217     StatsdConfig newConfig;
2218     *newConfig.add_gauge_metric() = gauge6;
2219     const int gauge6Index = 0;
2220     *newConfig.add_gauge_metric() = gauge3;
2221     const int gauge3Index = 1;
2222     *newConfig.add_gauge_metric() = gauge1;
2223     const int gauge1Index = 2;
2224     *newConfig.add_gauge_metric() = gauge4;
2225     const int gauge4Index = 3;
2226     *newConfig.add_gauge_metric() = gauge2;
2227     const int gauge2Index = 4;
2228 
2229     // Output data structures to validate.
2230     unordered_map<int64_t, int> newMetricProducerMap;
2231     vector<sp<MetricProducer>> newMetricProducers;
2232     unordered_map<int, vector<int>> conditionToMetricMap;
2233     unordered_map<int, vector<int>> trackerToMetricMap;
2234     set<int64_t> noReportMetricIds;
2235     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2236     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2237     vector<int> metricsWithActivation;
2238     set<int64_t> replacedMetrics;
2239     EXPECT_TRUE(updateMetrics(
2240             key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
2241             oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
2242             newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
2243             newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
2244             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
2245             newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
2246             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
2247             metricsWithActivation, replacedMetrics));
2248 
2249     unordered_map<int64_t, int> expectedMetricProducerMap = {
2250             {gauge1Id, gauge1Index}, {gauge2Id, gauge2Index}, {gauge3Id, gauge3Index},
2251             {gauge4Id, gauge4Index}, {gauge6Id, gauge6Index},
2252     };
2253     EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
2254     EXPECT_EQ(replacedMetrics, set<int64_t>({gauge2Id, gauge3Id, gauge4Id}));
2255 
2256     // Make sure preserved metrics are the same.
2257     ASSERT_EQ(newMetricProducers.size(), 5);
2258     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(gauge1Id)],
2259               newMetricProducers[newMetricProducerMap.at(gauge1Id)]);
2260 
2261     // Make sure replaced metrics are different.
2262     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge2Id)],
2263               newMetricProducers[newMetricProducerMap.at(gauge2Id)]);
2264     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge3Id)],
2265               newMetricProducers[newMetricProducerMap.at(gauge3Id)]);
2266     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gauge4Id)],
2267               newMetricProducers[newMetricProducerMap.at(gauge4Id)]);
2268 
2269     // Verify the conditionToMetricMap.
2270     ASSERT_EQ(conditionToMetricMap.size(), 1);
2271     const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
2272     EXPECT_THAT(condition1Metrics, UnorderedElementsAre(gauge1Index, gauge4Index, gauge6Index));
2273 
2274     // Verify the trackerToMetricMap.
2275     ASSERT_EQ(trackerToMetricMap.size(), 4);
2276     const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2277     EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(gauge1Index, gauge2Index));
2278     const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2279     EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gauge3Index, gauge4Index, gauge6Index));
2280     const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2281     EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(gauge1Index));
2282     const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
2283     EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(gauge3Index, gauge6Index));
2284 
2285     // Verify event activation/deactivation maps.
2286     ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
2287     ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2288     ASSERT_EQ(metricsWithActivation.size(), 0);
2289 
2290     // Verify tracker indices/ids/conditions/states are correct.
2291     GaugeMetricProducer* gaugeProducer1 =
2292             static_cast<GaugeMetricProducer*>(newMetricProducers[gauge1Index].get());
2293     EXPECT_EQ(gaugeProducer1->getMetricId(), gauge1Id);
2294     EXPECT_EQ(gaugeProducer1->mConditionTrackerIndex, predicate1Index);
2295     EXPECT_EQ(gaugeProducer1->mCondition, ConditionState::kUnknown);
2296     EXPECT_EQ(gaugeProducer1->mWhatMatcherIndex, matcher4Index);
2297     GaugeMetricProducer* gaugeProducer2 =
2298             static_cast<GaugeMetricProducer*>(newMetricProducers[gauge2Index].get());
2299     EXPECT_EQ(gaugeProducer2->getMetricId(), gauge2Id);
2300     EXPECT_EQ(gaugeProducer2->mConditionTrackerIndex, -1);
2301     EXPECT_EQ(gaugeProducer2->mCondition, ConditionState::kTrue);
2302     EXPECT_EQ(gaugeProducer2->mWhatMatcherIndex, matcher1Index);
2303     GaugeMetricProducer* gaugeProducer3 =
2304             static_cast<GaugeMetricProducer*>(newMetricProducers[gauge3Index].get());
2305     EXPECT_EQ(gaugeProducer3->getMetricId(), gauge3Id);
2306     EXPECT_EQ(gaugeProducer3->mConditionTrackerIndex, -1);
2307     EXPECT_EQ(gaugeProducer3->mCondition, ConditionState::kTrue);
2308     EXPECT_EQ(gaugeProducer3->mWhatMatcherIndex, matcher5Index);
2309     GaugeMetricProducer* gaugeProducer4 =
2310             static_cast<GaugeMetricProducer*>(newMetricProducers[gauge4Index].get());
2311     EXPECT_EQ(gaugeProducer4->getMetricId(), gauge4Id);
2312     EXPECT_EQ(gaugeProducer4->mConditionTrackerIndex, predicate1Index);
2313     EXPECT_EQ(gaugeProducer4->mCondition, ConditionState::kUnknown);
2314     EXPECT_EQ(gaugeProducer4->mWhatMatcherIndex, matcher3Index);
2315     GaugeMetricProducer* gaugeProducer6 =
2316             static_cast<GaugeMetricProducer*>(newMetricProducers[gauge6Index].get());
2317     EXPECT_EQ(gaugeProducer6->getMetricId(), gauge6Id);
2318     EXPECT_EQ(gaugeProducer6->mConditionTrackerIndex, predicate1Index);
2319     EXPECT_EQ(gaugeProducer6->mCondition, ConditionState::kUnknown);
2320     EXPECT_EQ(gaugeProducer6->mWhatMatcherIndex, matcher5Index);
2321 
2322     sp<EventMatcherWizard> newMatcherWizard = gaugeProducer1->mEventMatcherWizard;
2323     EXPECT_NE(newMatcherWizard, oldMatcherWizard);
2324     EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
2325     oldMetricProducers.clear();
2326     // Only reference to the old wizard should be the one in the test.
2327     EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
2328 }
2329 
TEST_F(ConfigUpdateTest,TestUpdateDurationMetrics)2330 TEST_F(ConfigUpdateTest, TestUpdateDurationMetrics) {
2331     StatsdConfig config;
2332     // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
2333     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2334     int64_t matcher1Id = matcher1.id();
2335     *config.add_atom_matcher() = matcher1;
2336 
2337     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2338     int64_t matcher2Id = matcher2.id();
2339     *config.add_atom_matcher() = matcher2;
2340 
2341     AtomMatcher matcher3 = CreateAcquireWakelockAtomMatcher();
2342     int64_t matcher3Id = matcher3.id();
2343     *config.add_atom_matcher() = matcher3;
2344 
2345     AtomMatcher matcher4 = CreateReleaseWakelockAtomMatcher();
2346     int64_t matcher4Id = matcher4.id();
2347     *config.add_atom_matcher() = matcher4;
2348 
2349     AtomMatcher matcher5 = CreateMoveToForegroundAtomMatcher();
2350     int64_t matcher5Id = matcher5.id();
2351     *config.add_atom_matcher() = matcher5;
2352 
2353     AtomMatcher matcher6 = CreateMoveToBackgroundAtomMatcher();
2354     int64_t matcher6Id = matcher6.id();
2355     *config.add_atom_matcher() = matcher6;
2356 
2357     AtomMatcher matcher7 = CreateBatteryStateNoneMatcher();
2358     int64_t matcher7Id = matcher7.id();
2359     *config.add_atom_matcher() = matcher7;
2360 
2361     AtomMatcher matcher8 = CreateBatteryStateUsbMatcher();
2362     int64_t matcher8Id = matcher8.id();
2363     *config.add_atom_matcher() = matcher8;
2364 
2365     Predicate predicate1 = CreateScreenIsOnPredicate();
2366     int64_t predicate1Id = predicate1.id();
2367     *config.add_predicate() = predicate1;
2368 
2369     Predicate predicate2 = CreateScreenIsOffPredicate();
2370     int64_t predicate2Id = predicate2.id();
2371     *config.add_predicate() = predicate2;
2372 
2373     Predicate predicate3 = CreateDeviceUnpluggedPredicate();
2374     int64_t predicate3Id = predicate3.id();
2375     *config.add_predicate() = predicate3;
2376 
2377     Predicate predicate4 = CreateIsInBackgroundPredicate();
2378     *predicate4.mutable_simple_predicate()->mutable_dimensions() =
2379             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1});
2380     int64_t predicate4Id = predicate4.id();
2381     *config.add_predicate() = predicate4;
2382 
2383     Predicate predicate5 = CreateHoldingWakelockPredicate();
2384     *predicate5.mutable_simple_predicate()->mutable_dimensions() =
2385             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2386     predicate5.mutable_simple_predicate()->set_stop_all(matcher7Id);
2387     int64_t predicate5Id = predicate5.id();
2388     *config.add_predicate() = predicate5;
2389 
2390     State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
2391     int64_t state1Id = state1.id();
2392     *config.add_state() = state1;
2393 
2394     State state2 = CreateScreenState();
2395     int64_t state2Id = state2.id();
2396     *config.add_state() = state2;
2397 
2398     // Add a few duration metrics.
2399     // Will be preserved.
2400     DurationMetric duration1 =
2401             createDurationMetric("DURATION1", predicate5Id, predicate4Id, {state2Id});
2402     *duration1.mutable_dimensions_in_what() =
2403             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2404     MetricConditionLink* link = duration1.add_links();
2405     link->set_condition(predicate4Id);
2406     *link->mutable_fields_in_what() =
2407             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2408     *link->mutable_fields_in_condition() =
2409             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
2410     int64_t duration1Id = duration1.id();
2411     *config.add_duration_metric() = duration1;
2412 
2413     // Will be replaced.
2414     DurationMetric duration2 = createDurationMetric("DURATION2", predicate1Id, nullopt, {});
2415     int64_t duration2Id = duration2.id();
2416     *config.add_duration_metric() = duration2;
2417 
2418     // Will be replaced.
2419     DurationMetric duration3 = createDurationMetric("DURATION3", predicate3Id, nullopt, {state1Id});
2420     int64_t duration3Id = duration3.id();
2421     *config.add_duration_metric() = duration3;
2422 
2423     // Will be replaced.
2424     DurationMetric duration4 = createDurationMetric("DURATION4", predicate3Id, predicate2Id, {});
2425     int64_t duration4Id = duration4.id();
2426     *config.add_duration_metric() = duration4;
2427 
2428     // Will be deleted.
2429     DurationMetric duration5 = createDurationMetric("DURATION5", predicate2Id, nullopt, {});
2430     int64_t duration5Id = duration5.id();
2431     *config.add_duration_metric() = duration5;
2432 
2433     EXPECT_TRUE(initConfig(config));
2434 
2435     // Make some sliced conditions true.
2436     int uid1 = 10;
2437     int uid2 = 11;
2438     vector<MatchingState> matchingStates(8, MatchingState::kNotMatched);
2439     matchingStates[2] = kMatched;
2440     vector<ConditionState> conditionCache(5, ConditionState::kNotEvaluated);
2441     vector<bool> changedCache(5, false);
2442     unique_ptr<LogEvent> event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid1}, {"tag"}, "wl1");
2443     oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
2444                                                conditionCache, changedCache);
2445     EXPECT_TRUE(oldConditionTrackers[4]->isSliced());
2446     EXPECT_TRUE(changedCache[4]);
2447     EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
2448     oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());
2449 
2450     fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
2451     fill(changedCache.begin(), changedCache.end(), false);
2452     event = CreateAcquireWakelockEvent(timeBaseNs + 3, {uid2}, {"tag"}, "wl2");
2453     oldConditionTrackers[4]->evaluateCondition(*event.get(), matchingStates, oldConditionTrackers,
2454                                                conditionCache, changedCache);
2455     EXPECT_TRUE(changedCache[4]);
2456     EXPECT_EQ(conditionCache[4], ConditionState::kTrue);
2457     oldMetricProducers[0]->onMatchedLogEvent(2, *event.get());
2458 
2459     // Used later to ensure the condition wizard is replaced. Get it before doing the update.
2460     // The duration trackers have a pointer to the wizard, and 2 trackers were created above.
2461     sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
2462     EXPECT_EQ(oldConditionWizard->getStrongCount(), 8);
2463 
2464     // Replace predicate1, predicate3, and state1. Causes duration2/3/4 to be replaced.
2465     set<int64_t> replacedConditions({predicate1Id, predicate2Id});
2466     set<int64_t> replacedStates({state1Id});
2467 
2468     // New duration metric.
2469     DurationMetric duration6 = createDurationMetric("DURATION6", predicate4Id, predicate5Id, {});
2470     *duration6.mutable_dimensions_in_what() =
2471             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
2472     link = duration6.add_links();
2473     link->set_condition(predicate5Id);
2474     *link->mutable_fields_in_what() =
2475             CreateDimensions(util::ACTIVITY_FOREGROUND_STATE_CHANGED, {1} /*uid field*/);
2476     *link->mutable_fields_in_condition() =
2477             CreateAttributionUidDimensions(util::WAKELOCK_STATE_CHANGED, {Position::FIRST});
2478     int64_t duration6Id = duration6.id();
2479 
2480     // Map the matchers and predicates in reverse order to force the indices to change.
2481     const int matcher8Index = 0, matcher7Index = 1, matcher6Index = 2, matcher5Index = 3,
2482               matcher4Index = 4, matcher3Index = 5, matcher2Index = 6, matcher1Index = 7;
2483     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap({{matcher8Id, matcher8Index},
2484                                                                 {matcher7Id, matcher7Index},
2485                                                                 {matcher6Id, matcher6Index},
2486                                                                 {matcher5Id, matcher5Index},
2487                                                                 {matcher4Id, matcher4Index},
2488                                                                 {matcher3Id, matcher3Index},
2489                                                                 {matcher2Id, matcher2Index},
2490                                                                 {matcher1Id, matcher1Index}});
2491     // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2492     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(8);
2493     reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2494                  newAtomMatchingTrackers.begin());
2495 
2496     const int predicate5Index = 0, predicate4Index = 1, predicate3Index = 2, predicate2Index = 3,
2497               predicate1Index = 4;
2498     std::unordered_map<int64_t, int> newConditionTrackerMap({
2499             {predicate5Id, predicate5Index},
2500             {predicate4Id, predicate4Index},
2501             {predicate3Id, predicate3Index},
2502             {predicate2Id, predicate2Index},
2503             {predicate1Id, predicate1Index},
2504     });
2505     // Use the existing conditionTrackers and reinitialize them to get the initial condition cache.
2506     vector<sp<ConditionTracker>> newConditionTrackers(5);
2507     reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
2508                  newConditionTrackers.begin());
2509     vector<Predicate> conditionProtos(5);
2510     reverse_copy(config.predicate().begin(), config.predicate().end(), conditionProtos.begin());
2511     for (int i = 0; i < newConditionTrackers.size(); i++) {
2512         EXPECT_TRUE(newConditionTrackers[i]->onConfigUpdated(
2513                 conditionProtos, i, newConditionTrackers, newAtomMatchingTrackerMap,
2514                 newConditionTrackerMap));
2515     }
2516     vector<bool> cycleTracker(5, false);
2517     fill(conditionCache.begin(), conditionCache.end(), ConditionState::kNotEvaluated);
2518     for (int i = 0; i < newConditionTrackers.size(); i++) {
2519         EXPECT_TRUE(newConditionTrackers[i]->init(conditionProtos, newConditionTrackers,
2520                                                   newConditionTrackerMap, cycleTracker,
2521                                                   conditionCache));
2522     }
2523     // Predicate5 should be true since 2 uids have wakelocks
2524     EXPECT_EQ(conditionCache, vector({kTrue, kUnknown, kUnknown, kUnknown, kUnknown}));
2525 
2526     StatsdConfig newConfig;
2527     *newConfig.add_duration_metric() = duration6;
2528     const int duration6Index = 0;
2529     *newConfig.add_duration_metric() = duration3;
2530     const int duration3Index = 1;
2531     *newConfig.add_duration_metric() = duration1;
2532     const int duration1Index = 2;
2533     *newConfig.add_duration_metric() = duration4;
2534     const int duration4Index = 3;
2535     *newConfig.add_duration_metric() = duration2;
2536     const int duration2Index = 4;
2537 
2538     for (const Predicate& predicate : conditionProtos) {
2539         *newConfig.add_predicate() = predicate;
2540     }
2541     *newConfig.add_state() = state1;
2542     *newConfig.add_state() = state2;
2543     unordered_map<int64_t, int> stateAtomIdMap;
2544     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
2545     map<int64_t, uint64_t> stateProtoHashes;
2546     EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));
2547 
2548     // Output data structures to validate.
2549     unordered_map<int64_t, int> newMetricProducerMap;
2550     vector<sp<MetricProducer>> newMetricProducers;
2551     unordered_map<int, vector<int>> conditionToMetricMap;
2552     unordered_map<int, vector<int>> trackerToMetricMap;
2553     set<int64_t> noReportMetricIds;
2554     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2555     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2556     vector<int> metricsWithActivation;
2557     set<int64_t> replacedMetrics;
2558     EXPECT_TRUE(updateMetrics(
2559             key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
2560             oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
2561             newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
2562             newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
2563             oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
2564             conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
2565             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
2566             metricsWithActivation, replacedMetrics));
2567 
2568     unordered_map<int64_t, int> expectedMetricProducerMap = {
2569             {duration1Id, duration1Index}, {duration2Id, duration2Index},
2570             {duration3Id, duration3Index}, {duration4Id, duration4Index},
2571             {duration6Id, duration6Index},
2572     };
2573     EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
2574     EXPECT_EQ(replacedMetrics, set<int64_t>({duration2Id, duration3Id, duration4Id}));
2575     // Make sure preserved metrics are the same.
2576     ASSERT_EQ(newMetricProducers.size(), 5);
2577     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(duration1Id)],
2578               newMetricProducers[newMetricProducerMap.at(duration1Id)]);
2579 
2580     // Make sure replaced metrics are different.
2581     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration2Id)],
2582               newMetricProducers[newMetricProducerMap.at(duration2Id)]);
2583     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration3Id)],
2584               newMetricProducers[newMetricProducerMap.at(duration3Id)]);
2585     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(duration4Id)],
2586               newMetricProducers[newMetricProducerMap.at(duration4Id)]);
2587 
2588     // Verify the conditionToMetricMap. Note that the "what" is not in this map.
2589     ASSERT_EQ(conditionToMetricMap.size(), 3);
2590     const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
2591     EXPECT_THAT(condition2Metrics, UnorderedElementsAre(duration4Index));
2592     const vector<int>& condition4Metrics = conditionToMetricMap[predicate4Index];
2593     EXPECT_THAT(condition4Metrics, UnorderedElementsAre(duration1Index));
2594     const vector<int>& condition5Metrics = conditionToMetricMap[predicate5Index];
2595     EXPECT_THAT(condition5Metrics, UnorderedElementsAre(duration6Index));
2596 
2597     // Verify the trackerToMetricMap. The start/stop/stopall indices from the "what" should be here.
2598     ASSERT_EQ(trackerToMetricMap.size(), 8);
2599     const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2600     EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(duration2Index));
2601     const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
2602     EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(duration2Index));
2603     const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2604     EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(duration1Index));
2605     const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2606     EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(duration1Index));
2607     const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
2608     EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(duration6Index));
2609     const vector<int>& matcher6Metrics = trackerToMetricMap[matcher6Index];
2610     EXPECT_THAT(matcher6Metrics, UnorderedElementsAre(duration6Index));
2611     const vector<int>& matcher7Metrics = trackerToMetricMap[matcher7Index];
2612     EXPECT_THAT(matcher7Metrics,
2613                 UnorderedElementsAre(duration1Index, duration3Index, duration4Index));
2614     const vector<int>& matcher8Metrics = trackerToMetricMap[matcher8Index];
2615     EXPECT_THAT(matcher8Metrics, UnorderedElementsAre(duration3Index, duration4Index));
2616 
2617     // Verify event activation/deactivation maps.
2618     ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
2619     ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2620     ASSERT_EQ(metricsWithActivation.size(), 0);
2621 
2622     // Verify tracker indices/ids/conditions are correct.
2623     DurationMetricProducer* durationProducer1 =
2624             static_cast<DurationMetricProducer*>(newMetricProducers[duration1Index].get());
2625     EXPECT_EQ(durationProducer1->getMetricId(), duration1Id);
2626     EXPECT_EQ(durationProducer1->mConditionTrackerIndex, predicate4Index);
2627     EXPECT_EQ(durationProducer1->mCondition, ConditionState::kUnknown);
2628     EXPECT_EQ(durationProducer1->mStartIndex, matcher3Index);
2629     EXPECT_EQ(durationProducer1->mStopIndex, matcher4Index);
2630     EXPECT_EQ(durationProducer1->mStopAllIndex, matcher7Index);
2631     EXPECT_EQ(durationProducer1->mCurrentSlicedDurationTrackerMap.size(), 2);
2632     for (const auto& durationTrackerIt : durationProducer1->mCurrentSlicedDurationTrackerMap) {
2633         EXPECT_EQ(durationTrackerIt.second->mConditionTrackerIndex, predicate4Index);
2634     }
2635     DurationMetricProducer* durationProducer2 =
2636             static_cast<DurationMetricProducer*>(newMetricProducers[duration2Index].get());
2637     EXPECT_EQ(durationProducer2->getMetricId(), duration2Id);
2638     EXPECT_EQ(durationProducer2->mConditionTrackerIndex, -1);
2639     EXPECT_EQ(durationProducer2->mCondition, ConditionState::kTrue);
2640     EXPECT_EQ(durationProducer2->mStartIndex, matcher1Index);
2641     EXPECT_EQ(durationProducer2->mStopIndex, matcher2Index);
2642     EXPECT_EQ(durationProducer2->mStopAllIndex, -1);
2643     DurationMetricProducer* durationProducer3 =
2644             static_cast<DurationMetricProducer*>(newMetricProducers[duration3Index].get());
2645     EXPECT_EQ(durationProducer3->getMetricId(), duration3Id);
2646     EXPECT_EQ(durationProducer3->mConditionTrackerIndex, -1);
2647     EXPECT_EQ(durationProducer3->mCondition, ConditionState::kTrue);
2648     EXPECT_EQ(durationProducer3->mStartIndex, matcher7Index);
2649     EXPECT_EQ(durationProducer3->mStopIndex, matcher8Index);
2650     EXPECT_EQ(durationProducer3->mStopAllIndex, -1);
2651     DurationMetricProducer* durationProducer4 =
2652             static_cast<DurationMetricProducer*>(newMetricProducers[duration4Index].get());
2653     EXPECT_EQ(durationProducer4->getMetricId(), duration4Id);
2654     EXPECT_EQ(durationProducer4->mConditionTrackerIndex, predicate2Index);
2655     EXPECT_EQ(durationProducer4->mCondition, ConditionState::kUnknown);
2656     EXPECT_EQ(durationProducer4->mStartIndex, matcher7Index);
2657     EXPECT_EQ(durationProducer4->mStopIndex, matcher8Index);
2658     EXPECT_EQ(durationProducer4->mStopAllIndex, -1);
2659     DurationMetricProducer* durationProducer6 =
2660             static_cast<DurationMetricProducer*>(newMetricProducers[duration6Index].get());
2661     EXPECT_EQ(durationProducer6->getMetricId(), duration6Id);
2662     EXPECT_EQ(durationProducer6->mConditionTrackerIndex, predicate5Index);
2663     // TODO(b/167491517): should this be unknown since the condition is sliced?
2664     EXPECT_EQ(durationProducer6->mCondition, ConditionState::kTrue);
2665     EXPECT_EQ(durationProducer6->mStartIndex, matcher6Index);
2666     EXPECT_EQ(durationProducer6->mStopIndex, matcher5Index);
2667     EXPECT_EQ(durationProducer6->mStopAllIndex, -1);
2668 
2669     sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
2670     EXPECT_NE(newConditionWizard, oldConditionWizard);
2671     EXPECT_EQ(newConditionWizard->getStrongCount(), 8);
2672     oldMetricProducers.clear();
2673     // Only reference to the old wizard should be the one in the test.
2674     EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
2675 }
2676 
TEST_F(ConfigUpdateTest,TestUpdateValueMetrics)2677 TEST_F(ConfigUpdateTest, TestUpdateValueMetrics) {
2678     StatsdConfig config;
2679 
2680     // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig.
2681     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2682     int64_t matcher1Id = matcher1.id();
2683     *config.add_atom_matcher() = matcher1;
2684 
2685     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2686     int64_t matcher2Id = matcher2.id();
2687     *config.add_atom_matcher() = matcher2;
2688 
2689     AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
2690     int64_t matcher3Id = matcher3.id();
2691     *config.add_atom_matcher() = matcher3;
2692 
2693     AtomMatcher matcher4 = CreateTemperatureAtomMatcher();
2694     int64_t matcher4Id = matcher4.id();
2695     *config.add_atom_matcher() = matcher4;
2696 
2697     AtomMatcher matcher5 = CreateSimpleAtomMatcher("SubsystemSleep", util::SUBSYSTEM_SLEEP_STATE);
2698     int64_t matcher5Id = matcher5.id();
2699     *config.add_atom_matcher() = matcher5;
2700 
2701     Predicate predicate1 = CreateScreenIsOnPredicate();
2702     int64_t predicate1Id = predicate1.id();
2703     *config.add_predicate() = predicate1;
2704 
2705     Predicate predicate2 = CreateScreenIsOffPredicate();
2706     int64_t predicate2Id = predicate2.id();
2707     *config.add_predicate() = predicate2;
2708 
2709     State state1 = CreateScreenStateWithOnOffMap(0x123, 0x321);
2710     int64_t state1Id = state1.id();
2711     *config.add_state() = state1;
2712 
2713     State state2 = CreateScreenState();
2714     int64_t state2Id = state2.id();
2715     *config.add_state() = state2;
2716 
2717     // Add a few value metrics.
2718     // Note that these will not work as "real" metrics since the value field is always 2.
2719     // Will be preserved.
2720     ValueMetric value1 = createValueMetric("VALUE1", matcher4, 2, predicate1Id, {state1Id});
2721     int64_t value1Id = value1.id();
2722     *config.add_value_metric() = value1;
2723 
2724     // Will be replaced - definition change.
2725     ValueMetric value2 = createValueMetric("VALUE2", matcher1, 2, nullopt, {});
2726     int64_t value2Id = value2.id();
2727     *config.add_value_metric() = value2;
2728 
2729     // Will be replaced - condition change.
2730     ValueMetric value3 = createValueMetric("VALUE3", matcher5, 2, predicate2Id, {});
2731     int64_t value3Id = value3.id();
2732     *config.add_value_metric() = value3;
2733 
2734     // Will be replaced - state change.
2735     ValueMetric value4 = createValueMetric("VALUE4", matcher3, 2, nullopt, {state2Id});
2736     int64_t value4Id = value4.id();
2737     *config.add_value_metric() = value4;
2738 
2739     // Will be deleted.
2740     ValueMetric value5 = createValueMetric("VALUE5", matcher2, 2, nullopt, {});
2741     int64_t value5Id = value5.id();
2742     *config.add_value_metric() = value5;
2743 
2744     EXPECT_TRUE(initConfig(config));
2745 
2746     // Used later to ensure the condition wizard is replaced. Get it before doing the update.
2747     sp<EventMatcherWizard> oldMatcherWizard =
2748             static_cast<ValueMetricProducer*>(oldMetricProducers[0].get())->mEventMatcherWizard;
2749     EXPECT_EQ(oldMatcherWizard->getStrongCount(), 6);
2750 
2751     // Change value2, causing it to be replaced.
2752     value2.set_aggregation_type(ValueMetric::AVG);
2753 
2754     // Mark predicate 2 as replaced. Causes value3 to be replaced.
2755     set<int64_t> replacedConditions = {predicate2Id};
2756 
2757     // Mark state 2 as replaced. Causes value4 to be replaced.
2758     set<int64_t> replacedStates = {state2Id};
2759 
2760     // New value metric.
2761     ValueMetric value6 = createValueMetric("VALUE6", matcher5, 2, predicate1Id, {state1Id});
2762     int64_t value6Id = value6.id();
2763 
2764     // Map the matchers and predicates in reverse order to force the indices to change.
2765     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
2766     const int matcher5Index = 0;
2767     newAtomMatchingTrackerMap[matcher5Id] = 0;
2768     const int matcher4Index = 1;
2769     newAtomMatchingTrackerMap[matcher4Id] = 1;
2770     const int matcher3Index = 2;
2771     newAtomMatchingTrackerMap[matcher3Id] = 2;
2772     const int matcher2Index = 3;
2773     newAtomMatchingTrackerMap[matcher2Id] = 3;
2774     const int matcher1Index = 4;
2775     newAtomMatchingTrackerMap[matcher1Id] = 4;
2776     // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2777     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(5);
2778     std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2779                       newAtomMatchingTrackers.begin());
2780 
2781     std::unordered_map<int64_t, int> newConditionTrackerMap;
2782     const int predicate2Index = 0;
2783     newConditionTrackerMap[predicate2Id] = 0;
2784     const int predicate1Index = 1;
2785     newConditionTrackerMap[predicate1Id] = 1;
2786     // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
2787     vector<sp<ConditionTracker>> newConditionTrackers(2);
2788     std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
2789                       newConditionTrackers.begin());
2790     // Say that predicate1 & predicate2 is unknown since the initial condition never changed.
2791     vector<ConditionState> conditionCache = {ConditionState::kUnknown, ConditionState::kUnknown};
2792 
2793     StatsdConfig newConfig;
2794     *newConfig.add_value_metric() = value6;
2795     const int value6Index = 0;
2796     *newConfig.add_value_metric() = value3;
2797     const int value3Index = 1;
2798     *newConfig.add_value_metric() = value1;
2799     const int value1Index = 2;
2800     *newConfig.add_value_metric() = value4;
2801     const int value4Index = 3;
2802     *newConfig.add_value_metric() = value2;
2803     const int value2Index = 4;
2804 
2805     *newConfig.add_state() = state1;
2806     *newConfig.add_state() = state2;
2807 
2808     unordered_map<int64_t, int> stateAtomIdMap;
2809     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
2810     map<int64_t, uint64_t> stateProtoHashes;
2811     EXPECT_TRUE(initStates(newConfig, stateAtomIdMap, allStateGroupMaps, stateProtoHashes));
2812 
2813     // Output data structures to validate.
2814     unordered_map<int64_t, int> newMetricProducerMap;
2815     vector<sp<MetricProducer>> newMetricProducers;
2816     unordered_map<int, vector<int>> conditionToMetricMap;
2817     unordered_map<int, vector<int>> trackerToMetricMap;
2818     set<int64_t> noReportMetricIds;
2819     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2820     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2821     vector<int> metricsWithActivation;
2822     set<int64_t> replacedMetrics;
2823     EXPECT_TRUE(updateMetrics(
2824             key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
2825             oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, /*replacedMatchers=*/{},
2826             newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
2827             newConditionTrackers, conditionCache, stateAtomIdMap, allStateGroupMaps, replacedStates,
2828             oldMetricProducerMap, oldMetricProducers, newMetricProducerMap, newMetricProducers,
2829             conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
2830             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
2831             metricsWithActivation, replacedMetrics));
2832 
2833     unordered_map<int64_t, int> expectedMetricProducerMap = {
2834             {value1Id, value1Index}, {value2Id, value2Index}, {value3Id, value3Index},
2835             {value4Id, value4Index}, {value6Id, value6Index},
2836     };
2837     EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
2838     EXPECT_EQ(replacedMetrics, set<int64_t>({value2Id, value3Id, value4Id}));
2839 
2840     // Make sure preserved metrics are the same.
2841     ASSERT_EQ(newMetricProducers.size(), 5);
2842     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(value1Id)],
2843               newMetricProducers[newMetricProducerMap.at(value1Id)]);
2844 
2845     // Make sure replaced metrics are different.
2846     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value2Id)],
2847               newMetricProducers[newMetricProducerMap.at(value2Id)]);
2848     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value3Id)],
2849               newMetricProducers[newMetricProducerMap.at(value3Id)]);
2850     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(value4Id)],
2851               newMetricProducers[newMetricProducerMap.at(value4Id)]);
2852 
2853     // Verify the conditionToMetricMap.
2854     ASSERT_EQ(conditionToMetricMap.size(), 2);
2855     const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
2856     EXPECT_THAT(condition1Metrics, UnorderedElementsAre(value1Index, value6Index));
2857     const vector<int>& condition2Metrics = conditionToMetricMap[predicate2Index];
2858     EXPECT_THAT(condition2Metrics, UnorderedElementsAre(value3Index));
2859 
2860     // Verify the trackerToMetricMap.
2861     ASSERT_EQ(trackerToMetricMap.size(), 4);
2862     const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
2863     EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(value2Index));
2864     const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
2865     EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(value4Index));
2866     const vector<int>& matcher4Metrics = trackerToMetricMap[matcher4Index];
2867     EXPECT_THAT(matcher4Metrics, UnorderedElementsAre(value1Index));
2868     const vector<int>& matcher5Metrics = trackerToMetricMap[matcher5Index];
2869     EXPECT_THAT(matcher5Metrics, UnorderedElementsAre(value3Index, value6Index));
2870 
2871     // Verify event activation/deactivation maps.
2872     ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
2873     ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
2874     ASSERT_EQ(metricsWithActivation.size(), 0);
2875 
2876     // Verify tracker indices/ids/conditions/states are correct.
2877     ValueMetricProducer* valueProducer1 =
2878             static_cast<ValueMetricProducer*>(newMetricProducers[value1Index].get());
2879     EXPECT_EQ(valueProducer1->getMetricId(), value1Id);
2880     EXPECT_EQ(valueProducer1->mConditionTrackerIndex, predicate1Index);
2881     EXPECT_EQ(valueProducer1->mCondition, ConditionState::kUnknown);
2882     EXPECT_EQ(valueProducer1->mWhatMatcherIndex, matcher4Index);
2883     ValueMetricProducer* valueProducer2 =
2884             static_cast<ValueMetricProducer*>(newMetricProducers[value2Index].get());
2885     EXPECT_EQ(valueProducer2->getMetricId(), value2Id);
2886     EXPECT_EQ(valueProducer2->mConditionTrackerIndex, -1);
2887     EXPECT_EQ(valueProducer2->mCondition, ConditionState::kTrue);
2888     EXPECT_EQ(valueProducer2->mWhatMatcherIndex, matcher1Index);
2889     ValueMetricProducer* valueProducer3 =
2890             static_cast<ValueMetricProducer*>(newMetricProducers[value3Index].get());
2891     EXPECT_EQ(valueProducer3->getMetricId(), value3Id);
2892     EXPECT_EQ(valueProducer3->mConditionTrackerIndex, predicate2Index);
2893     EXPECT_EQ(valueProducer3->mCondition, ConditionState::kUnknown);
2894     EXPECT_EQ(valueProducer3->mWhatMatcherIndex, matcher5Index);
2895     ValueMetricProducer* valueProducer4 =
2896             static_cast<ValueMetricProducer*>(newMetricProducers[value4Index].get());
2897     EXPECT_EQ(valueProducer4->getMetricId(), value4Id);
2898     EXPECT_EQ(valueProducer4->mConditionTrackerIndex, -1);
2899     EXPECT_EQ(valueProducer4->mCondition, ConditionState::kTrue);
2900     EXPECT_EQ(valueProducer4->mWhatMatcherIndex, matcher3Index);
2901     ValueMetricProducer* valueProducer6 =
2902             static_cast<ValueMetricProducer*>(newMetricProducers[value6Index].get());
2903     EXPECT_EQ(valueProducer6->getMetricId(), value6Id);
2904     EXPECT_EQ(valueProducer6->mConditionTrackerIndex, predicate1Index);
2905     EXPECT_EQ(valueProducer6->mCondition, ConditionState::kUnknown);
2906     EXPECT_EQ(valueProducer6->mWhatMatcherIndex, matcher5Index);
2907 
2908     sp<EventMatcherWizard> newMatcherWizard = valueProducer1->mEventMatcherWizard;
2909     EXPECT_NE(newMatcherWizard, oldMatcherWizard);
2910     EXPECT_EQ(newMatcherWizard->getStrongCount(), 6);
2911     oldMetricProducers.clear();
2912     // Only reference to the old wizard should be the one in the test.
2913     EXPECT_EQ(oldMatcherWizard->getStrongCount(), 1);
2914 }
2915 
TEST_F(ConfigUpdateTest,TestUpdateMetricActivations)2916 TEST_F(ConfigUpdateTest, TestUpdateMetricActivations) {
2917     StatsdConfig config;
2918     // Add atom matchers
2919     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
2920     int64_t matcher1Id = matcher1.id();
2921     *config.add_atom_matcher() = matcher1;
2922 
2923     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
2924     int64_t matcher2Id = matcher2.id();
2925     *config.add_atom_matcher() = matcher2;
2926 
2927     AtomMatcher matcher3 = CreateStartScheduledJobAtomMatcher();
2928     int64_t matcher3Id = matcher3.id();
2929     *config.add_atom_matcher() = matcher3;
2930 
2931     AtomMatcher matcher4 = CreateFinishScheduledJobAtomMatcher();
2932     int64_t matcher4Id = matcher4.id();
2933     *config.add_atom_matcher() = matcher4;
2934 
2935     // Add an event metric with multiple activations.
2936     EventMetric event1 = createEventMetric("EVENT1", matcher1Id, nullopt);
2937     int64_t event1Id = event1.id();
2938     *config.add_event_metric() = event1;
2939 
2940     int64_t matcher2TtlSec = 2, matcher3TtlSec = 3, matcher4TtlSec = 4;
2941     MetricActivation metricActivation;
2942     metricActivation.set_metric_id(event1Id);
2943     EventActivation* activation = metricActivation.add_event_activation();
2944     activation->set_atom_matcher_id(matcher2Id);
2945     activation->set_ttl_seconds(matcher2TtlSec);
2946     activation->set_activation_type(ACTIVATE_IMMEDIATELY);
2947     activation->set_deactivation_atom_matcher_id(matcher1Id);
2948     activation = metricActivation.add_event_activation();
2949     activation->set_atom_matcher_id(matcher3Id);
2950     activation->set_ttl_seconds(matcher3TtlSec);
2951     activation->set_activation_type(ACTIVATE_ON_BOOT);
2952     activation->set_deactivation_atom_matcher_id(matcher1Id);
2953     activation = metricActivation.add_event_activation();
2954     activation->set_atom_matcher_id(matcher4Id);
2955     activation->set_ttl_seconds(matcher4TtlSec);
2956     activation->set_activation_type(ACTIVATE_IMMEDIATELY);
2957     activation->set_deactivation_atom_matcher_id(matcher2Id);
2958     *config.add_metric_activation() = metricActivation;
2959 
2960     EXPECT_TRUE(initConfig(config));
2961 
2962     // Activate some of the event activations.
2963     ASSERT_EQ(oldMetricProducers[0]->getMetricId(), event1Id);
2964     int64_t matcher2StartNs = 12345;
2965     oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher2Id], matcher2StartNs);
2966     int64_t matcher3StartNs = 23456;
2967     oldMetricProducers[0]->activate(oldAtomMatchingTrackerMap[matcher3Id], matcher3StartNs);
2968     EXPECT_TRUE(oldMetricProducers[0]->isActive());
2969 
2970     // Map the matchers and predicates in reverse order to force the indices to change.
2971     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
2972     const int matcher4Index = 0;
2973     newAtomMatchingTrackerMap[matcher4Id] = 0;
2974     const int matcher3Index = 1;
2975     newAtomMatchingTrackerMap[matcher3Id] = 1;
2976     const int matcher2Index = 2;
2977     newAtomMatchingTrackerMap[matcher2Id] = 2;
2978     const int matcher1Index = 3;
2979     newAtomMatchingTrackerMap[matcher1Id] = 3;
2980     // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
2981     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(4);
2982     std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
2983                       newAtomMatchingTrackers.begin());
2984     set<int64_t> replacedMatchers;
2985 
2986     unordered_map<int64_t, int> newConditionTrackerMap;
2987     vector<sp<ConditionTracker>> newConditionTrackers;
2988     set<int64_t> replacedConditions;
2989     vector<ConditionState> conditionCache;
2990     unordered_map<int64_t, int> newMetricProducerMap;
2991     vector<sp<MetricProducer>> newMetricProducers;
2992     unordered_map<int, vector<int>> conditionToMetricMap;
2993     unordered_map<int, vector<int>> trackerToMetricMap;
2994     set<int64_t> noReportMetricIds;
2995     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
2996     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
2997     vector<int> metricsWithActivation;
2998     set<int64_t> replacedMetrics;
2999     EXPECT_TRUE(updateMetrics(
3000             key, config, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
3001             oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
3002             newAtomMatchingTrackers, newConditionTrackerMap, replacedConditions,
3003             newConditionTrackers, conditionCache, /*stateAtomIdMap=*/{}, /*allStateGroupMaps=*/{},
3004             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
3005             newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
3006             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
3007             metricsWithActivation, replacedMetrics));
3008 
3009     // Verify event activation/deactivation maps.
3010     ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 3);
3011     EXPECT_THAT(activationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
3012     EXPECT_THAT(activationAtomTrackerToMetricMap[matcher3Index], UnorderedElementsAre(0));
3013     EXPECT_THAT(activationAtomTrackerToMetricMap[matcher4Index], UnorderedElementsAre(0));
3014     ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 2);
3015     EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher1Index], UnorderedElementsAre(0, 0));
3016     EXPECT_THAT(deactivationAtomTrackerToMetricMap[matcher2Index], UnorderedElementsAre(0));
3017     ASSERT_EQ(metricsWithActivation.size(), 1);
3018     EXPECT_THAT(metricsWithActivation, UnorderedElementsAre(0));
3019 
3020     // Verify mEventActivation and mEventDeactivation map of the producer.
3021     sp<MetricProducer> producer = newMetricProducers[0];
3022     EXPECT_TRUE(producer->isActive());
3023     ASSERT_EQ(producer->mEventActivationMap.size(), 3);
3024     shared_ptr<Activation> matcher2Activation = producer->mEventActivationMap[matcher2Index];
3025     EXPECT_EQ(matcher2Activation->ttl_ns, matcher2TtlSec * NS_PER_SEC);
3026     EXPECT_EQ(matcher2Activation->activationType, ACTIVATE_IMMEDIATELY);
3027     EXPECT_EQ(matcher2Activation->state, kActive);
3028     EXPECT_EQ(matcher2Activation->start_ns, matcher2StartNs);
3029     shared_ptr<Activation> matcher3Activation = producer->mEventActivationMap[matcher3Index];
3030     EXPECT_EQ(matcher3Activation->ttl_ns, matcher3TtlSec * NS_PER_SEC);
3031     EXPECT_EQ(matcher3Activation->activationType, ACTIVATE_ON_BOOT);
3032     EXPECT_EQ(matcher3Activation->state, kActiveOnBoot);
3033     shared_ptr<Activation> matcher4Activation = producer->mEventActivationMap[matcher4Index];
3034     EXPECT_EQ(matcher4Activation->ttl_ns, matcher4TtlSec * NS_PER_SEC);
3035     EXPECT_EQ(matcher4Activation->activationType, ACTIVATE_IMMEDIATELY);
3036     EXPECT_EQ(matcher4Activation->state, kNotActive);
3037 
3038     ASSERT_EQ(producer->mEventDeactivationMap.size(), 2);
3039     EXPECT_THAT(producer->mEventDeactivationMap[matcher1Index],
3040                 UnorderedElementsAre(matcher2Activation, matcher3Activation));
3041     EXPECT_THAT(producer->mEventDeactivationMap[matcher2Index],
3042                 UnorderedElementsAre(matcher4Activation));
3043 }
3044 
TEST_F(ConfigUpdateTest,TestUpdateMetricsMultipleTypes)3045 TEST_F(ConfigUpdateTest, TestUpdateMetricsMultipleTypes) {
3046     StatsdConfig config;
3047     // Add atom matchers/predicates/states. These are mostly needed for initStatsdConfig
3048     AtomMatcher matcher1 = CreateScreenTurnedOnAtomMatcher();
3049     int64_t matcher1Id = matcher1.id();
3050     *config.add_atom_matcher() = matcher1;
3051 
3052     AtomMatcher matcher2 = CreateScreenTurnedOffAtomMatcher();
3053     int64_t matcher2Id = matcher2.id();
3054     *config.add_atom_matcher() = matcher2;
3055 
3056     AtomMatcher matcher3 = CreateTemperatureAtomMatcher();
3057     int64_t matcher3Id = matcher3.id();
3058     *config.add_atom_matcher() = matcher3;
3059 
3060     Predicate predicate1 = CreateScreenIsOnPredicate();
3061     int64_t predicate1Id = predicate1.id();
3062     *config.add_predicate() = predicate1;
3063 
3064     // Add a few count metrics.
3065     // Will be preserved.
3066     CountMetric countMetric = createCountMetric("COUNT1", matcher1Id, predicate1Id, {});
3067     int64_t countMetricId = countMetric.id();
3068     *config.add_count_metric() = countMetric;
3069 
3070     // Will be replaced since matcher2 is replaced.
3071     EventMetric eventMetric = createEventMetric("EVENT1", matcher2Id, nullopt);
3072     int64_t eventMetricId = eventMetric.id();
3073     *config.add_event_metric() = eventMetric;
3074 
3075     // Will be replaced because the definition changes - a predicate is added.
3076     GaugeMetric gaugeMetric = createGaugeMetric("GAUGE1", matcher3Id,
3077                                                 GaugeMetric::RANDOM_ONE_SAMPLE, nullopt, nullopt);
3078     int64_t gaugeMetricId = gaugeMetric.id();
3079     *config.add_gauge_metric() = gaugeMetric;
3080 
3081     // Preserved.
3082     ValueMetric valueMetric = createValueMetric("VALUE1", matcher3, 2, predicate1Id, {});
3083     int64_t valueMetricId = valueMetric.id();
3084     *config.add_value_metric() = valueMetric;
3085 
3086     // Preserved.
3087     DurationMetric durationMetric = createDurationMetric("DURATION1", predicate1Id, nullopt, {});
3088     int64_t durationMetricId = durationMetric.id();
3089     *config.add_duration_metric() = durationMetric;
3090 
3091     EXPECT_TRUE(initConfig(config));
3092 
3093     // Used later to ensure the condition wizard is replaced. Get it before doing the update.
3094     sp<ConditionWizard> oldConditionWizard = oldMetricProducers[0]->mWizard;
3095     EXPECT_EQ(oldConditionWizard->getStrongCount(), 6);
3096 
3097     // Mark matcher 2 as replaced. Causes eventMetric to be replaced.
3098     set<int64_t> replacedMatchers;
3099     replacedMatchers.insert(matcher2Id);
3100 
3101     // Add predicate1 as a predicate on gaugeMetric, causing it to be replaced.
3102     gaugeMetric.set_condition(predicate1Id);
3103 
3104     // Map the matchers and predicates in reverse order to force the indices to change.
3105     std::unordered_map<int64_t, int> newAtomMatchingTrackerMap;
3106     const int matcher3Index = 0;
3107     newAtomMatchingTrackerMap[matcher3Id] = 0;
3108     const int matcher2Index = 1;
3109     newAtomMatchingTrackerMap[matcher2Id] = 1;
3110     const int matcher1Index = 2;
3111     newAtomMatchingTrackerMap[matcher1Id] = 2;
3112     // Use the existing matchers. A bit hacky, but saves code and we don't rely on them.
3113     vector<sp<AtomMatchingTracker>> newAtomMatchingTrackers(3);
3114     std::reverse_copy(oldAtomMatchingTrackers.begin(), oldAtomMatchingTrackers.end(),
3115                       newAtomMatchingTrackers.begin());
3116 
3117     std::unordered_map<int64_t, int> newConditionTrackerMap;
3118     const int predicate1Index = 0;
3119     newConditionTrackerMap[predicate1Id] = 0;
3120     // Use the existing conditionTrackers. A bit hacky, but saves code and we don't rely on them.
3121     vector<sp<ConditionTracker>> newConditionTrackers(1);
3122     std::reverse_copy(oldConditionTrackers.begin(), oldConditionTrackers.end(),
3123                       newConditionTrackers.begin());
3124     vector<ConditionState> conditionCache = {ConditionState::kUnknown};
3125 
3126     // The order matters. we parse in the order of: count, duration, event, value, gauge.
3127     StatsdConfig newConfig;
3128     *newConfig.add_count_metric() = countMetric;
3129     const int countMetricIndex = 0;
3130     *newConfig.add_duration_metric() = durationMetric;
3131     const int durationMetricIndex = 1;
3132     *newConfig.add_event_metric() = eventMetric;
3133     const int eventMetricIndex = 2;
3134     *newConfig.add_value_metric() = valueMetric;
3135     const int valueMetricIndex = 3;
3136     *newConfig.add_gauge_metric() = gaugeMetric;
3137     const int gaugeMetricIndex = 4;
3138 
3139     // Add the predicate since duration metric needs it.
3140     *newConfig.add_predicate() = predicate1;
3141 
3142     // Output data structures to validate.
3143     unordered_map<int64_t, int> newMetricProducerMap;
3144     vector<sp<MetricProducer>> newMetricProducers;
3145     unordered_map<int, vector<int>> conditionToMetricMap;
3146     unordered_map<int, vector<int>> trackerToMetricMap;
3147     set<int64_t> noReportMetricIds;
3148     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3149     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3150     vector<int> metricsWithActivation;
3151     set<int64_t> replacedMetrics;
3152     EXPECT_TRUE(updateMetrics(
3153             key, newConfig, /*timeBaseNs=*/123, /*currentTimeNs=*/12345, new StatsPullerManager(),
3154             oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, replacedMatchers,
3155             newAtomMatchingTrackers, newConditionTrackerMap, /*replacedConditions=*/{},
3156             newConditionTrackers, conditionCache, /*stateAtomIdMap*/ {}, /*allStateGroupMaps=*/{},
3157             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
3158             newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
3159             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
3160             metricsWithActivation, replacedMetrics));
3161 
3162     unordered_map<int64_t, int> expectedMetricProducerMap = {
3163             {countMetricId, countMetricIndex}, {durationMetricId, durationMetricIndex},
3164             {eventMetricId, eventMetricIndex}, {valueMetricId, valueMetricIndex},
3165             {gaugeMetricId, gaugeMetricIndex},
3166     };
3167     EXPECT_THAT(newMetricProducerMap, ContainerEq(expectedMetricProducerMap));
3168 
3169     EXPECT_EQ(replacedMetrics, set<int64_t>({eventMetricId, gaugeMetricId}));
3170 
3171     // Make sure preserved metrics are the same.
3172     ASSERT_EQ(newMetricProducers.size(), 5);
3173     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(countMetricId)],
3174               newMetricProducers[newMetricProducerMap.at(countMetricId)]);
3175     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(durationMetricId)],
3176               newMetricProducers[newMetricProducerMap.at(durationMetricId)]);
3177     EXPECT_EQ(oldMetricProducers[oldMetricProducerMap.at(valueMetricId)],
3178               newMetricProducers[newMetricProducerMap.at(valueMetricId)]);
3179 
3180     // Make sure replaced metrics are different.
3181     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(eventMetricId)],
3182               newMetricProducers[newMetricProducerMap.at(eventMetricId)]);
3183     EXPECT_NE(oldMetricProducers[oldMetricProducerMap.at(gaugeMetricId)],
3184               newMetricProducers[newMetricProducerMap.at(gaugeMetricId)]);
3185 
3186     // Verify the conditionToMetricMap.
3187     ASSERT_EQ(conditionToMetricMap.size(), 1);
3188     const vector<int>& condition1Metrics = conditionToMetricMap[predicate1Index];
3189     EXPECT_THAT(condition1Metrics,
3190                 UnorderedElementsAre(countMetricIndex, gaugeMetricIndex, valueMetricIndex));
3191 
3192     // Verify the trackerToMetricMap.
3193     ASSERT_EQ(trackerToMetricMap.size(), 3);
3194     const vector<int>& matcher1Metrics = trackerToMetricMap[matcher1Index];
3195     EXPECT_THAT(matcher1Metrics, UnorderedElementsAre(countMetricIndex, durationMetricIndex));
3196     const vector<int>& matcher2Metrics = trackerToMetricMap[matcher2Index];
3197     EXPECT_THAT(matcher2Metrics, UnorderedElementsAre(eventMetricIndex, durationMetricIndex));
3198     const vector<int>& matcher3Metrics = trackerToMetricMap[matcher3Index];
3199     EXPECT_THAT(matcher3Metrics, UnorderedElementsAre(gaugeMetricIndex, valueMetricIndex));
3200 
3201     // Verify event activation/deactivation maps.
3202     ASSERT_EQ(activationAtomTrackerToMetricMap.size(), 0);
3203     ASSERT_EQ(deactivationAtomTrackerToMetricMap.size(), 0);
3204     ASSERT_EQ(metricsWithActivation.size(), 0);
3205 
3206     // Verify tracker indices/ids/conditions are correct.
3207     EXPECT_EQ(newMetricProducers[countMetricIndex]->getMetricId(), countMetricId);
3208     EXPECT_EQ(newMetricProducers[countMetricIndex]->mConditionTrackerIndex, predicate1Index);
3209     EXPECT_EQ(newMetricProducers[countMetricIndex]->mCondition, ConditionState::kUnknown);
3210     EXPECT_EQ(newMetricProducers[durationMetricIndex]->getMetricId(), durationMetricId);
3211     EXPECT_EQ(newMetricProducers[durationMetricIndex]->mConditionTrackerIndex, -1);
3212     EXPECT_EQ(newMetricProducers[durationMetricIndex]->mCondition, ConditionState::kTrue);
3213     EXPECT_EQ(newMetricProducers[eventMetricIndex]->getMetricId(), eventMetricId);
3214     EXPECT_EQ(newMetricProducers[eventMetricIndex]->mConditionTrackerIndex, -1);
3215     EXPECT_EQ(newMetricProducers[eventMetricIndex]->mCondition, ConditionState::kTrue);
3216     EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->getMetricId(), gaugeMetricId);
3217     EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mConditionTrackerIndex, predicate1Index);
3218     EXPECT_EQ(newMetricProducers[gaugeMetricIndex]->mCondition, ConditionState::kUnknown);
3219 
3220     sp<ConditionWizard> newConditionWizard = newMetricProducers[0]->mWizard;
3221     EXPECT_NE(newConditionWizard, oldConditionWizard);
3222     EXPECT_EQ(newConditionWizard->getStrongCount(), 6);
3223     oldMetricProducers.clear();
3224     // Only reference to the old wizard should be the one in the test.
3225     EXPECT_EQ(oldConditionWizard->getStrongCount(), 1);
3226 }
3227 
TEST_F(ConfigUpdateTest,TestAlertPreserve)3228 TEST_F(ConfigUpdateTest, TestAlertPreserve) {
3229     StatsdConfig config;
3230     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
3231     *config.add_atom_matcher() = whatMatcher;
3232 
3233     *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
3234 
3235     Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
3236     *config.add_alert() = alert;
3237     EXPECT_TRUE(initConfig(config));
3238 
3239     UpdateStatus updateStatus = UPDATE_UNKNOWN;
3240     EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
3241                                            /*replacedMetrics*/ {}, updateStatus));
3242     EXPECT_EQ(updateStatus, UPDATE_PRESERVE);
3243 }
3244 
TEST_F(ConfigUpdateTest,TestAlertMetricChanged)3245 TEST_F(ConfigUpdateTest, TestAlertMetricChanged) {
3246     StatsdConfig config;
3247     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
3248     *config.add_atom_matcher() = whatMatcher;
3249 
3250     CountMetric metric = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
3251     *config.add_count_metric() = metric;
3252 
3253     Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
3254     *config.add_alert() = alert;
3255     EXPECT_TRUE(initConfig(config));
3256 
3257     UpdateStatus updateStatus = UPDATE_UNKNOWN;
3258     EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
3259                                            /*replacedMetrics*/ {metric.id()}, updateStatus));
3260     EXPECT_EQ(updateStatus, UPDATE_REPLACE);
3261 }
3262 
TEST_F(ConfigUpdateTest,TestAlertDefinitionChanged)3263 TEST_F(ConfigUpdateTest, TestAlertDefinitionChanged) {
3264     StatsdConfig config;
3265     AtomMatcher whatMatcher = CreateScreenBrightnessChangedAtomMatcher();
3266     *config.add_atom_matcher() = whatMatcher;
3267 
3268     *config.add_count_metric() = createCountMetric("VALUE1", whatMatcher.id(), nullopt, {});
3269 
3270     Alert alert = createAlert("Alert1", config.count_metric(0).id(), 1, 1);
3271     *config.add_alert() = alert;
3272     EXPECT_TRUE(initConfig(config));
3273 
3274     alert.set_num_buckets(2);
3275 
3276     UpdateStatus updateStatus = UPDATE_UNKNOWN;
3277     EXPECT_TRUE(determineAlertUpdateStatus(alert, oldAlertTrackerMap, oldAnomalyTrackers,
3278                                            /*replacedMetrics*/ {}, updateStatus));
3279     EXPECT_EQ(updateStatus, UPDATE_REPLACE);
3280 }
3281 
TEST_F(ConfigUpdateTest,TestUpdateAlerts)3282 TEST_F(ConfigUpdateTest, TestUpdateAlerts) {
3283     StatsdConfig config;
3284     // Add atom matchers/predicates/metrics. These are mostly needed for initStatsdConfig
3285     *config.add_atom_matcher() = CreateScreenTurnedOnAtomMatcher();
3286     *config.add_atom_matcher() = CreateScreenTurnedOffAtomMatcher();
3287     *config.add_predicate() = CreateScreenIsOnPredicate();
3288 
3289     CountMetric countMetric = createCountMetric("COUNT1", config.atom_matcher(0).id(), nullopt, {});
3290     int64_t countMetricId = countMetric.id();
3291     *config.add_count_metric() = countMetric;
3292 
3293     DurationMetric durationMetric =
3294             createDurationMetric("DURATION1", config.predicate(0).id(), nullopt, {});
3295     int64_t durationMetricId = durationMetric.id();
3296     *config.add_duration_metric() = durationMetric;
3297 
3298     // Add alerts.
3299     // Preserved.
3300     Alert alert1 = createAlert("Alert1", durationMetricId, /*buckets*/ 1, /*triggerSum*/ 5000);
3301     int64_t alert1Id = alert1.id();
3302     *config.add_alert() = alert1;
3303 
3304     // Replaced.
3305     Alert alert2 = createAlert("Alert2", countMetricId, /*buckets*/ 1, /*triggerSum*/ 2);
3306     int64_t alert2Id = alert2.id();
3307     *config.add_alert() = alert2;
3308 
3309     // Replaced.
3310     Alert alert3 = createAlert("Alert3", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 5000);
3311     int64_t alert3Id = alert3.id();
3312     *config.add_alert() = alert3;
3313 
3314     // Add Subscriptions.
3315     Subscription subscription1 = createSubscription("S1", Subscription::ALERT, alert1Id);
3316     *config.add_subscription() = subscription1;
3317     Subscription subscription2 = createSubscription("S2", Subscription::ALERT, alert1Id);
3318     *config.add_subscription() = subscription2;
3319     Subscription subscription3 = createSubscription("S3", Subscription::ALERT, alert2Id);
3320     *config.add_subscription() = subscription3;
3321 
3322     EXPECT_TRUE(initConfig(config));
3323 
3324     // Add a duration tracker to the duration metric to ensure durationTrackers are updated
3325     // with the proper anomalyTrackers.
3326     unique_ptr<LogEvent> event = CreateScreenStateChangedEvent(
3327             timeBaseNs + 1, android::view::DisplayStateEnum::DISPLAY_STATE_ON);
3328     oldMetricProducers[1]->onMatchedLogEvent(0, *event.get());
3329 
3330     // Change the count metric. Causes alert2 to be replaced.
3331     config.mutable_count_metric(0)->set_bucket(ONE_DAY);
3332     // Change num buckets on alert3, causing replacement.
3333     alert3.set_num_buckets(5);
3334 
3335     // New alert.
3336     Alert alert4 = createAlert("Alert4", durationMetricId, /*buckets*/ 3, /*triggerSum*/ 10000);
3337     int64_t alert4Id = alert4.id();
3338 
3339     // Move subscription2 to be on alert2 and make a new subscription.
3340     subscription2.set_rule_id(alert2Id);
3341     Subscription subscription4 = createSubscription("S4", Subscription::ALERT, alert2Id);
3342 
3343     // Create the new config. Modify the old one to avoid adding the matchers/predicates.
3344     // Add alerts in different order so the map is changed.
3345     config.clear_alert();
3346     *config.add_alert() = alert4;
3347     const int alert4Index = 0;
3348     *config.add_alert() = alert3;
3349     const int alert3Index = 1;
3350     *config.add_alert() = alert1;
3351     const int alert1Index = 2;
3352     *config.add_alert() = alert2;
3353     const int alert2Index = 3;
3354 
3355     // Subscription3 is removed.
3356     config.clear_subscription();
3357     *config.add_subscription() = subscription4;
3358     *config.add_subscription() = subscription2;
3359     *config.add_subscription() = subscription1;
3360 
3361     // Output data structures from update metrics. Don't care about the outputs besides
3362     // replacedMetrics, but need to do this so that the metrics clear their anomaly trackers.
3363     unordered_map<int64_t, int> newMetricProducerMap;
3364     vector<sp<MetricProducer>> newMetricProducers;
3365     unordered_map<int, vector<int>> conditionToMetricMap;
3366     unordered_map<int, vector<int>> trackerToMetricMap;
3367     set<int64_t> noReportMetricIds;
3368     unordered_map<int, vector<int>> activationAtomTrackerToMetricMap;
3369     unordered_map<int, vector<int>> deactivationAtomTrackerToMetricMap;
3370     vector<int> metricsWithActivation;
3371     set<int64_t> replacedMetrics;
3372     int64_t currentTimeNs = 12345;
3373     EXPECT_TRUE(updateMetrics(
3374             key, config, /*timeBaseNs=*/123, currentTimeNs, new StatsPullerManager(),
3375             oldAtomMatchingTrackerMap, oldAtomMatchingTrackerMap, /*replacedMatchers*/ {},
3376             oldAtomMatchingTrackers, oldConditionTrackerMap, /*replacedConditions=*/{},
3377             oldConditionTrackers, {ConditionState::kUnknown}, /*stateAtomIdMap*/ {},
3378             /*allStateGroupMaps=*/{},
3379             /*replacedStates=*/{}, oldMetricProducerMap, oldMetricProducers, newMetricProducerMap,
3380             newMetricProducers, conditionToMetricMap, trackerToMetricMap, noReportMetricIds,
3381             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
3382             metricsWithActivation, replacedMetrics));
3383 
3384     EXPECT_EQ(replacedMetrics, set<int64_t>({countMetricId}));
3385 
3386     unordered_map<int64_t, int> newAlertTrackerMap;
3387     vector<sp<AnomalyTracker>> newAnomalyTrackers;
3388     EXPECT_TRUE(updateAlerts(config, currentTimeNs, newMetricProducerMap, replacedMetrics,
3389                              oldAlertTrackerMap, oldAnomalyTrackers, anomalyAlarmMonitor,
3390                              newMetricProducers, newAlertTrackerMap, newAnomalyTrackers));
3391 
3392     unordered_map<int64_t, int> expectedAlertMap = {
3393             {alert1Id, alert1Index},
3394             {alert2Id, alert2Index},
3395             {alert3Id, alert3Index},
3396             {alert4Id, alert4Index},
3397     };
3398     EXPECT_THAT(newAlertTrackerMap, ContainerEq(expectedAlertMap));
3399 
3400     // Make sure preserved alerts are the same.
3401     ASSERT_EQ(newAnomalyTrackers.size(), 4);
3402     EXPECT_EQ(oldAnomalyTrackers[oldAlertTrackerMap.at(alert1Id)],
3403               newAnomalyTrackers[newAlertTrackerMap.at(alert1Id)]);
3404 
3405     // Make sure replaced alerts are different.
3406     EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert2Id)],
3407               newAnomalyTrackers[newAlertTrackerMap.at(alert2Id)]);
3408     EXPECT_NE(oldAnomalyTrackers[oldAlertTrackerMap.at(alert3Id)],
3409               newAnomalyTrackers[newAlertTrackerMap.at(alert3Id)]);
3410 
3411     // Verify the alerts have the correct anomaly trackers.
3412     ASSERT_EQ(newMetricProducers.size(), 2);
3413     EXPECT_THAT(newMetricProducers[0]->mAnomalyTrackers,
3414                 UnorderedElementsAre(newAnomalyTrackers[alert2Index]));
3415     // For durationMetric, make sure the duration trackers get the updated anomalyTrackers.
3416     DurationMetricProducer* durationProducer =
3417             static_cast<DurationMetricProducer*>(newMetricProducers[1].get());
3418     EXPECT_THAT(
3419             durationProducer->mAnomalyTrackers,
3420             UnorderedElementsAre(newAnomalyTrackers[alert1Index], newAnomalyTrackers[alert3Index],
3421                                  newAnomalyTrackers[alert4Index]));
3422     ASSERT_EQ(durationProducer->mCurrentSlicedDurationTrackerMap.size(), 1);
3423     for (const auto& durationTrackerIt : durationProducer->mCurrentSlicedDurationTrackerMap) {
3424         EXPECT_EQ(durationTrackerIt.second->mAnomalyTrackers, durationProducer->mAnomalyTrackers);
3425     }
3426 
3427     // Verify alerts have the correct subscriptions. Use subscription id as proxy for equivalency.
3428     vector<int64_t> alert1Subscriptions;
3429     for (const Subscription& subscription : newAnomalyTrackers[alert1Index]->mSubscriptions) {
3430         alert1Subscriptions.push_back(subscription.id());
3431     }
3432     EXPECT_THAT(alert1Subscriptions, UnorderedElementsAre(subscription1.id()));
3433     vector<int64_t> alert2Subscriptions;
3434     for (const Subscription& subscription : newAnomalyTrackers[alert2Index]->mSubscriptions) {
3435         alert2Subscriptions.push_back(subscription.id());
3436     }
3437     EXPECT_THAT(alert2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription4.id()));
3438     EXPECT_THAT(newAnomalyTrackers[alert3Index]->mSubscriptions, IsEmpty());
3439     EXPECT_THAT(newAnomalyTrackers[alert4Index]->mSubscriptions, IsEmpty());
3440 }
3441 
TEST_F(ConfigUpdateTest,TestUpdateAlarms)3442 TEST_F(ConfigUpdateTest, TestUpdateAlarms) {
3443     StatsdConfig config;
3444     // Add alarms.
3445     Alarm alarm1 = createAlarm("Alarm1", /*offset*/ 1 * MS_PER_SEC, /*period*/ 50 * MS_PER_SEC);
3446     int64_t alarm1Id = alarm1.id();
3447     *config.add_alarm() = alarm1;
3448 
3449     Alarm alarm2 = createAlarm("Alarm2", /*offset*/ 1 * MS_PER_SEC, /*period*/ 2000 * MS_PER_SEC);
3450     int64_t alarm2Id = alarm2.id();
3451     *config.add_alarm() = alarm2;
3452 
3453     Alarm alarm3 = createAlarm("Alarm3", /*offset*/ 10 * MS_PER_SEC, /*period*/ 5000 * MS_PER_SEC);
3454     int64_t alarm3Id = alarm3.id();
3455     *config.add_alarm() = alarm3;
3456 
3457     // Add Subscriptions.
3458     Subscription subscription1 = createSubscription("S1", Subscription::ALARM, alarm1Id);
3459     *config.add_subscription() = subscription1;
3460     Subscription subscription2 = createSubscription("S2", Subscription::ALARM, alarm1Id);
3461     *config.add_subscription() = subscription2;
3462     Subscription subscription3 = createSubscription("S3", Subscription::ALARM, alarm2Id);
3463     *config.add_subscription() = subscription3;
3464 
3465     EXPECT_TRUE(initConfig(config));
3466 
3467     ASSERT_EQ(oldAlarmTrackers.size(), 3);
3468     // Config is created at statsd start time, so just add the offsets.
3469     EXPECT_EQ(oldAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
3470     EXPECT_EQ(oldAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1);
3471     EXPECT_EQ(oldAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
3472 
3473     // Change alarm2/alarm3.
3474     config.mutable_alarm(1)->set_offset_millis(5 * MS_PER_SEC);
3475     config.mutable_alarm(2)->set_period_millis(10000 * MS_PER_SEC);
3476 
3477     // Move subscription2 to be on alarm2 and make a new subscription.
3478     config.mutable_subscription(1)->set_rule_id(alarm2Id);
3479     Subscription subscription4 = createSubscription("S4", Subscription::ALARM, alarm1Id);
3480     *config.add_subscription() = subscription4;
3481 
3482     // Update time is 2 seconds after the base time.
3483     int64_t currentTimeNs = timeBaseNs + 2 * NS_PER_SEC;
3484     vector<sp<AlarmTracker>> newAlarmTrackers;
3485     EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
3486                            newAlarmTrackers));
3487 
3488     ASSERT_EQ(newAlarmTrackers.size(), 3);
3489     // Config is updated 2 seconds after statsd start
3490     // The offset has passed for alarm1, but not for alarms 2/3.
3491     EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 50);
3492     EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5);
3493     EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10);
3494 
3495     // Verify alarms have the correct subscriptions. Use subscription id as proxy for equivalency.
3496     vector<int64_t> alarm1Subscriptions;
3497     for (const Subscription& subscription : newAlarmTrackers[0]->mSubscriptions) {
3498         alarm1Subscriptions.push_back(subscription.id());
3499     }
3500     EXPECT_THAT(alarm1Subscriptions, UnorderedElementsAre(subscription1.id(), subscription4.id()));
3501     vector<int64_t> alarm2Subscriptions;
3502     for (const Subscription& subscription : newAlarmTrackers[1]->mSubscriptions) {
3503         alarm2Subscriptions.push_back(subscription.id());
3504     }
3505     EXPECT_THAT(alarm2Subscriptions, UnorderedElementsAre(subscription2.id(), subscription3.id()));
3506     EXPECT_THAT(newAlarmTrackers[2]->mSubscriptions, IsEmpty());
3507 
3508     // Verify the alarm monitor is updated accordingly once the old alarms are removed.
3509     // Alarm2 fires the earliest.
3510     oldAlarmTrackers.clear();
3511     EXPECT_EQ(periodicAlarmMonitor->getRegisteredAlarmTimeSec(), timeBaseNs / NS_PER_SEC + 5);
3512 
3513     // Do another update 60 seconds after config creation time, after the offsets of each alarm.
3514     currentTimeNs = timeBaseNs + 60 * NS_PER_SEC;
3515     newAlarmTrackers.clear();
3516     EXPECT_TRUE(initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
3517                            newAlarmTrackers));
3518 
3519     ASSERT_EQ(newAlarmTrackers.size(), 3);
3520     // Config is updated one minute after statsd start.
3521     // Two periods have passed for alarm 1, one has passed for alarms2/3.
3522     EXPECT_EQ(newAlarmTrackers[0]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 1 + 2 * 50);
3523     EXPECT_EQ(newAlarmTrackers[1]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 5 + 2000);
3524     EXPECT_EQ(newAlarmTrackers[2]->getAlarmTimestampSec(), timeBaseNs / NS_PER_SEC + 10 + 10000);
3525 }
3526 
3527 }  // namespace statsd
3528 }  // namespace os
3529 }  // namespace android
3530 
3531 #else
3532 GTEST_LOG_(INFO) << "This test does nothing.\n";
3533 #endif
3534