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