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