• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define STATSD_DEBUG false  // STOPSHIP if true
18 #include "Log.h"
19 
20 #include "config_update_utils.h"
21 
22 #include "external/StatsPullerManager.h"
23 #include "hash.h"
24 #include "matchers/EventMatcherWizard.h"
25 #include "metrics_manager_util.h"
26 
27 using google::protobuf::MessageLite;
28 
29 namespace android {
30 namespace os {
31 namespace statsd {
32 
33 // Recursive function to determine if a matcher needs to be updated. Populates matcherToUpdate.
34 // Returns nullopt if successful and InvalidConfigReason if not.
determineMatcherUpdateStatus(const StatsdConfig & config,const int matcherIdx,const unordered_map<int64_t,int> & oldAtomMatchingTrackerMap,const vector<sp<AtomMatchingTracker>> & oldAtomMatchingTrackers,const unordered_map<int64_t,int> & newAtomMatchingTrackerMap,vector<UpdateStatus> & matchersToUpdate,vector<bool> & cycleTracker)35 optional<InvalidConfigReason> determineMatcherUpdateStatus(
36         const StatsdConfig& config, const int matcherIdx,
37         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
38         const vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
39         const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
40         vector<UpdateStatus>& matchersToUpdate, vector<bool>& cycleTracker) {
41     // Have already examined this matcher.
42     if (matchersToUpdate[matcherIdx] != UPDATE_UNKNOWN) {
43         return nullopt;
44     }
45 
46     const AtomMatcher& matcher = config.atom_matcher(matcherIdx);
47     int64_t id = matcher.id();
48     // Check if new matcher.
49     const auto& oldAtomMatchingTrackerIt = oldAtomMatchingTrackerMap.find(id);
50     if (oldAtomMatchingTrackerIt == oldAtomMatchingTrackerMap.end()) {
51         matchersToUpdate[matcherIdx] = UPDATE_NEW;
52         return nullopt;
53     }
54 
55     // This is an existing matcher. Check if it has changed.
56     string serializedMatcher;
57     if (!matcher.SerializeToString(&serializedMatcher)) {
58         ALOGE("Unable to serialize matcher %lld", (long long)id);
59         return createInvalidConfigReasonWithMatcher(
60                 INVALID_CONFIG_REASON_MATCHER_SERIALIZATION_FAILED, id);
61     }
62     uint64_t newProtoHash = Hash64(serializedMatcher);
63     if (newProtoHash != oldAtomMatchingTrackers[oldAtomMatchingTrackerIt->second]->getProtoHash()) {
64         matchersToUpdate[matcherIdx] = UPDATE_REPLACE;
65         return nullopt;
66     }
67 
68     optional<InvalidConfigReason> invalidConfigReason;
69     switch (matcher.contents_case()) {
70         case AtomMatcher::ContentsCase::kSimpleAtomMatcher: {
71             matchersToUpdate[matcherIdx] = UPDATE_PRESERVE;
72             return nullopt;
73         }
74         case AtomMatcher::ContentsCase::kCombination: {
75             // Recurse to check if children have changed.
76             cycleTracker[matcherIdx] = true;
77             UpdateStatus status = UPDATE_PRESERVE;
78             for (const int64_t childMatcherId : matcher.combination().matcher()) {
79                 const auto& childIt = newAtomMatchingTrackerMap.find(childMatcherId);
80                 if (childIt == newAtomMatchingTrackerMap.end()) {
81                     ALOGW("Matcher %lld not found in the config", (long long)childMatcherId);
82                     invalidConfigReason = createInvalidConfigReasonWithMatcher(
83                             INVALID_CONFIG_REASON_MATCHER_CHILD_NOT_FOUND, id);
84                     invalidConfigReason->matcherIds.push_back(childMatcherId);
85                     return invalidConfigReason;
86                 }
87                 const int childIdx = childIt->second;
88                 if (cycleTracker[childIdx]) {
89                     ALOGE("Cycle detected in matcher config");
90                     invalidConfigReason = createInvalidConfigReasonWithMatcher(
91                             INVALID_CONFIG_REASON_MATCHER_CYCLE, id);
92                     invalidConfigReason->matcherIds.push_back(childMatcherId);
93                     return invalidConfigReason;
94                 }
95                 invalidConfigReason = determineMatcherUpdateStatus(
96                         config, childIdx, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers,
97                         newAtomMatchingTrackerMap, matchersToUpdate, cycleTracker);
98                 if (invalidConfigReason.has_value()) {
99                     invalidConfigReason->matcherIds.push_back(id);
100                     return invalidConfigReason;
101                 }
102 
103                 if (matchersToUpdate[childIdx] == UPDATE_REPLACE) {
104                     status = UPDATE_REPLACE;
105                     break;
106                 }
107             }
108             matchersToUpdate[matcherIdx] = status;
109             cycleTracker[matcherIdx] = false;
110             return nullopt;
111         }
112         default: {
113             ALOGE("Matcher \"%lld\" malformed", (long long)id);
114             return createInvalidConfigReasonWithMatcher(
115                     INVALID_CONFIG_REASON_MATCHER_MALFORMED_CONTENTS_CASE, id);
116         }
117     }
118     return nullopt;
119 }
120 
updateAtomMatchingTrackers(const StatsdConfig & config,const sp<UidMap> & uidMap,const unordered_map<int64_t,int> & oldAtomMatchingTrackerMap,const vector<sp<AtomMatchingTracker>> & oldAtomMatchingTrackers,std::unordered_map<int,std::vector<int>> & allTagIdsToMatchersMap,unordered_map<int64_t,int> & newAtomMatchingTrackerMap,vector<sp<AtomMatchingTracker>> & newAtomMatchingTrackers,set<int64_t> & replacedMatchers)121 optional<InvalidConfigReason> updateAtomMatchingTrackers(
122         const StatsdConfig& config, const sp<UidMap>& uidMap,
123         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
124         const vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
125         std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
126         unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
127         vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers, set<int64_t>& replacedMatchers) {
128     const int atomMatcherCount = config.atom_matcher_size();
129     vector<AtomMatcher> matcherProtos;
130     matcherProtos.reserve(atomMatcherCount);
131     newAtomMatchingTrackers.reserve(atomMatcherCount);
132     optional<InvalidConfigReason> invalidConfigReason;
133 
134     // Maps matcher id to their position in the config. For fast lookup of dependencies.
135     for (int i = 0; i < atomMatcherCount; i++) {
136         const AtomMatcher& matcher = config.atom_matcher(i);
137         if (newAtomMatchingTrackerMap.find(matcher.id()) != newAtomMatchingTrackerMap.end()) {
138             ALOGE("Duplicate atom matcher found for id %lld", (long long)matcher.id());
139             return createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_DUPLICATE,
140                                                         matcher.id());
141         }
142         newAtomMatchingTrackerMap[matcher.id()] = i;
143         matcherProtos.push_back(matcher);
144     }
145 
146     // For combination matchers, we need to determine if any children need to be updated.
147     vector<UpdateStatus> matchersToUpdate(atomMatcherCount, UPDATE_UNKNOWN);
148     vector<bool> cycleTracker(atomMatcherCount, false);
149     for (int i = 0; i < atomMatcherCount; i++) {
150         invalidConfigReason = determineMatcherUpdateStatus(
151                 config, i, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers,
152                 newAtomMatchingTrackerMap, matchersToUpdate, cycleTracker);
153         if (invalidConfigReason.has_value()) {
154             return invalidConfigReason;
155         }
156     }
157 
158     for (int i = 0; i < atomMatcherCount; i++) {
159         const AtomMatcher& matcher = config.atom_matcher(i);
160         const int64_t id = matcher.id();
161         switch (matchersToUpdate[i]) {
162             case UPDATE_PRESERVE: {
163                 const auto& oldAtomMatchingTrackerIt = oldAtomMatchingTrackerMap.find(id);
164                 if (oldAtomMatchingTrackerIt == oldAtomMatchingTrackerMap.end()) {
165                     ALOGE("Could not find AtomMatcher %lld in the previous config, but expected it "
166                           "to be there",
167                           (long long)id);
168                     return createInvalidConfigReasonWithMatcher(
169                             INVALID_CONFIG_REASON_MATCHER_NOT_IN_PREV_CONFIG, id);
170                 }
171                 const sp<AtomMatchingTracker>& tracker =
172                         oldAtomMatchingTrackers[oldAtomMatchingTrackerIt->second];
173                 invalidConfigReason =
174                         tracker->onConfigUpdated(matcherProtos[i], i, newAtomMatchingTrackerMap);
175                 if (invalidConfigReason.has_value()) {
176                     ALOGW("Config update failed for matcher %lld", (long long)id);
177                     return invalidConfigReason;
178                 }
179                 newAtomMatchingTrackers.push_back(tracker);
180                 break;
181             }
182             case UPDATE_REPLACE:
183                 replacedMatchers.insert(id);
184                 [[fallthrough]];  // Intentionally fallthrough to create the new matcher.
185             case UPDATE_NEW: {
186                 sp<AtomMatchingTracker> tracker =
187                         createAtomMatchingTracker(matcher, i, uidMap, invalidConfigReason);
188                 if (tracker == nullptr) {
189                     return invalidConfigReason;
190                 }
191                 newAtomMatchingTrackers.push_back(tracker);
192                 break;
193             }
194             default: {
195                 ALOGE("Matcher \"%lld\" update state is unknown. This should never happen",
196                       (long long)id);
197                 return createInvalidConfigReasonWithMatcher(
198                         INVALID_CONFIG_REASON_MATCHER_UPDATE_STATUS_UNKNOWN, id);
199             }
200         }
201     }
202 
203     std::fill(cycleTracker.begin(), cycleTracker.end(), false);
204     for (size_t matcherIndex = 0; matcherIndex < newAtomMatchingTrackers.size(); matcherIndex++) {
205         auto& matcher = newAtomMatchingTrackers[matcherIndex];
206         invalidConfigReason = matcher->init(matcherProtos, newAtomMatchingTrackers,
207                                             newAtomMatchingTrackerMap, cycleTracker);
208         if (invalidConfigReason.has_value()) {
209             return invalidConfigReason;
210         }
211 
212         // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
213         const set<int>& tagIds = matcher->getAtomIds();
214         for (int atomId : tagIds) {
215             auto& matchers = allTagIdsToMatchersMap[atomId];
216             // Performance note:
217             // For small amount of elements linear search in vector will be
218             // faster then look up in a set:
219             // - we do not expect matchers vector per atom id will have significant size (< 10)
220             // - iteration via vector is the fastest way compared to other containers (set, etc.)
221             //   in the hot path MetricsManager::onLogEvent()
222             // - vector<T> will have the smallest memory footprint compared to any other
223             //   std containers implementation
224             if (find(matchers.begin(), matchers.end(), matcherIndex) == matchers.end()) {
225                 matchers.push_back(matcherIndex);
226             }
227         }
228     }
229 
230     return nullopt;
231 }
232 
233 // Recursive function to determine if a condition needs to be updated. Populates conditionsToUpdate.
234 // Returns nullopt if successful and InvalidConfigReason if not.
determineConditionUpdateStatus(const StatsdConfig & config,const int conditionIdx,const unordered_map<int64_t,int> & oldConditionTrackerMap,const vector<sp<ConditionTracker>> & oldConditionTrackers,const unordered_map<int64_t,int> & newConditionTrackerMap,const set<int64_t> & replacedMatchers,vector<UpdateStatus> & conditionsToUpdate,vector<bool> & cycleTracker)235 optional<InvalidConfigReason> determineConditionUpdateStatus(
236         const StatsdConfig& config, const int conditionIdx,
237         const unordered_map<int64_t, int>& oldConditionTrackerMap,
238         const vector<sp<ConditionTracker>>& oldConditionTrackers,
239         const unordered_map<int64_t, int>& newConditionTrackerMap,
240         const set<int64_t>& replacedMatchers, vector<UpdateStatus>& conditionsToUpdate,
241         vector<bool>& cycleTracker) {
242     // Have already examined this condition.
243     if (conditionsToUpdate[conditionIdx] != UPDATE_UNKNOWN) {
244         return nullopt;
245     }
246 
247     const Predicate& predicate = config.predicate(conditionIdx);
248     int64_t id = predicate.id();
249     // Check if new condition.
250     const auto& oldConditionTrackerIt = oldConditionTrackerMap.find(id);
251     if (oldConditionTrackerIt == oldConditionTrackerMap.end()) {
252         conditionsToUpdate[conditionIdx] = UPDATE_NEW;
253         return nullopt;
254     }
255 
256     // This is an existing condition. Check if it has changed.
257     string serializedCondition;
258     if (!predicate.SerializeToString(&serializedCondition)) {
259         ALOGE("Unable to serialize predicate %lld", (long long)id);
260         return createInvalidConfigReasonWithPredicate(
261                 INVALID_CONFIG_REASON_CONDITION_SERIALIZATION_FAILED, id);
262     }
263     uint64_t newProtoHash = Hash64(serializedCondition);
264     if (newProtoHash != oldConditionTrackers[oldConditionTrackerIt->second]->getProtoHash()) {
265         conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
266         return nullopt;
267     }
268 
269     optional<InvalidConfigReason> invalidConfigReason;
270     switch (predicate.contents_case()) {
271         case Predicate::ContentsCase::kSimplePredicate: {
272             // Need to check if any of the underlying matchers changed.
273             const SimplePredicate& simplePredicate = predicate.simple_predicate();
274             if (simplePredicate.has_start()) {
275                 if (replacedMatchers.find(simplePredicate.start()) != replacedMatchers.end()) {
276                     conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
277                     return nullopt;
278                 }
279             }
280             if (simplePredicate.has_stop()) {
281                 if (replacedMatchers.find(simplePredicate.stop()) != replacedMatchers.end()) {
282                     conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
283                     return nullopt;
284                 }
285             }
286             if (simplePredicate.has_stop_all()) {
287                 if (replacedMatchers.find(simplePredicate.stop_all()) != replacedMatchers.end()) {
288                     conditionsToUpdate[conditionIdx] = UPDATE_REPLACE;
289                     return nullopt;
290                 }
291             }
292             conditionsToUpdate[conditionIdx] = UPDATE_PRESERVE;
293             return nullopt;
294         }
295         case Predicate::ContentsCase::kCombination: {
296             // Need to recurse on the children to see if any of the child predicates changed.
297             cycleTracker[conditionIdx] = true;
298             UpdateStatus status = UPDATE_PRESERVE;
299             for (const int64_t childPredicateId : predicate.combination().predicate()) {
300                 const auto& childIt = newConditionTrackerMap.find(childPredicateId);
301                 if (childIt == newConditionTrackerMap.end()) {
302                     ALOGW("Predicate %lld not found in the config", (long long)childPredicateId);
303                     invalidConfigReason = createInvalidConfigReasonWithPredicate(
304                             INVALID_CONFIG_REASON_CONDITION_CHILD_NOT_FOUND, id);
305                     invalidConfigReason->conditionIds.push_back(childPredicateId);
306                     return invalidConfigReason;
307                 }
308                 const int childIdx = childIt->second;
309                 if (cycleTracker[childIdx]) {
310                     ALOGE("Cycle detected in predicate config");
311                     invalidConfigReason = createInvalidConfigReasonWithPredicate(
312                             INVALID_CONFIG_REASON_CONDITION_CYCLE, id);
313                     invalidConfigReason->conditionIds.push_back(childPredicateId);
314                     return invalidConfigReason;
315                 }
316                 invalidConfigReason = determineConditionUpdateStatus(
317                         config, childIdx, oldConditionTrackerMap, oldConditionTrackers,
318                         newConditionTrackerMap, replacedMatchers, conditionsToUpdate, cycleTracker);
319                 if (invalidConfigReason.has_value()) {
320                     invalidConfigReason->conditionIds.push_back(id);
321                     return invalidConfigReason;
322                 }
323 
324                 if (conditionsToUpdate[childIdx] == UPDATE_REPLACE) {
325                     status = UPDATE_REPLACE;
326                     break;
327                 }
328             }
329             conditionsToUpdate[conditionIdx] = status;
330             cycleTracker[conditionIdx] = false;
331             return nullopt;
332         }
333         default: {
334             ALOGE("Predicate \"%lld\" malformed", (long long)id);
335             return createInvalidConfigReasonWithPredicate(
336                     INVALID_CONFIG_REASON_CONDITION_MALFORMED_CONTENTS_CASE, id);
337         }
338     }
339 
340     return nullopt;
341 }
342 
updateConditions(const ConfigKey & key,const StatsdConfig & config,const unordered_map<int64_t,int> & atomMatchingTrackerMap,const set<int64_t> & replacedMatchers,const unordered_map<int64_t,int> & oldConditionTrackerMap,const vector<sp<ConditionTracker>> & oldConditionTrackers,unordered_map<int64_t,int> & newConditionTrackerMap,vector<sp<ConditionTracker>> & newConditionTrackers,unordered_map<int,vector<int>> & trackerToConditionMap,vector<ConditionState> & conditionCache,set<int64_t> & replacedConditions)343 optional<InvalidConfigReason> updateConditions(
344         const ConfigKey& key, const StatsdConfig& config,
345         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
346         const set<int64_t>& replacedMatchers,
347         const unordered_map<int64_t, int>& oldConditionTrackerMap,
348         const vector<sp<ConditionTracker>>& oldConditionTrackers,
349         unordered_map<int64_t, int>& newConditionTrackerMap,
350         vector<sp<ConditionTracker>>& newConditionTrackers,
351         unordered_map<int, vector<int>>& trackerToConditionMap,
352         vector<ConditionState>& conditionCache, set<int64_t>& replacedConditions) {
353     vector<Predicate> conditionProtos;
354     const int conditionTrackerCount = config.predicate_size();
355     conditionProtos.reserve(conditionTrackerCount);
356     newConditionTrackers.reserve(conditionTrackerCount);
357     conditionCache.assign(conditionTrackerCount, ConditionState::kNotEvaluated);
358     optional<InvalidConfigReason> invalidConfigReason;
359 
360     for (int i = 0; i < conditionTrackerCount; i++) {
361         const Predicate& condition = config.predicate(i);
362         if (newConditionTrackerMap.find(condition.id()) != newConditionTrackerMap.end()) {
363             ALOGE("Duplicate Predicate found!");
364             return createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_DUPLICATE,
365                                                           condition.id());
366         }
367         newConditionTrackerMap[condition.id()] = i;
368         conditionProtos.push_back(condition);
369     }
370 
371     vector<UpdateStatus> conditionsToUpdate(conditionTrackerCount, UPDATE_UNKNOWN);
372     vector<bool> cycleTracker(conditionTrackerCount, false);
373     for (int i = 0; i < conditionTrackerCount; i++) {
374         invalidConfigReason = determineConditionUpdateStatus(
375                 config, i, oldConditionTrackerMap, oldConditionTrackers, newConditionTrackerMap,
376                 replacedMatchers, conditionsToUpdate, cycleTracker);
377         if (invalidConfigReason.has_value()) {
378             return invalidConfigReason;
379         }
380     }
381 
382     // Update status has been determined for all conditions. Now perform the update.
383     set<int> preservedConditions;
384     for (int i = 0; i < conditionTrackerCount; i++) {
385         const Predicate& predicate = config.predicate(i);
386         const int64_t id = predicate.id();
387         switch (conditionsToUpdate[i]) {
388             case UPDATE_PRESERVE: {
389                 preservedConditions.insert(i);
390                 const auto& oldConditionTrackerIt = oldConditionTrackerMap.find(id);
391                 if (oldConditionTrackerIt == oldConditionTrackerMap.end()) {
392                     ALOGE("Could not find Predicate %lld in the previous config, but expected it "
393                           "to be there",
394                           (long long)id);
395                     return createInvalidConfigReasonWithPredicate(
396                             INVALID_CONFIG_REASON_CONDITION_NOT_IN_PREV_CONFIG, id);
397                 }
398                 const int oldIndex = oldConditionTrackerIt->second;
399                 newConditionTrackers.push_back(oldConditionTrackers[oldIndex]);
400                 break;
401             }
402             case UPDATE_REPLACE:
403                 replacedConditions.insert(id);
404                 [[fallthrough]];  // Intentionally fallthrough to create the new condition tracker.
405             case UPDATE_NEW: {
406                 sp<ConditionTracker> tracker = createConditionTracker(
407                         key, predicate, i, atomMatchingTrackerMap, invalidConfigReason);
408                 if (tracker == nullptr) {
409                     return invalidConfigReason;
410                 }
411                 newConditionTrackers.push_back(tracker);
412                 break;
413             }
414             default: {
415                 ALOGE("Condition \"%lld\" update state is unknown. This should never happen",
416                       (long long)id);
417                 return createInvalidConfigReasonWithPredicate(
418                         INVALID_CONFIG_REASON_CONDITION_UPDATE_STATUS_UNKNOWN, id);
419             }
420         }
421     }
422 
423     // Update indices of preserved predicates.
424     for (const int conditionIndex : preservedConditions) {
425         invalidConfigReason = newConditionTrackers[conditionIndex]->onConfigUpdated(
426                 conditionProtos, conditionIndex, newConditionTrackers, atomMatchingTrackerMap,
427                 newConditionTrackerMap);
428         if (invalidConfigReason.has_value()) {
429             ALOGE("Failed to update condition %lld",
430                   (long long)newConditionTrackers[conditionIndex]->getConditionId());
431             return invalidConfigReason;
432         }
433     }
434 
435     std::fill(cycleTracker.begin(), cycleTracker.end(), false);
436     for (int conditionIndex = 0; conditionIndex < conditionTrackerCount; conditionIndex++) {
437         const sp<ConditionTracker>& conditionTracker = newConditionTrackers[conditionIndex];
438         // Calling init on preserved conditions is OK. It is needed to fill the condition cache.
439         invalidConfigReason =
440                 conditionTracker->init(conditionProtos, newConditionTrackers,
441                                        newConditionTrackerMap, cycleTracker, conditionCache);
442         if (invalidConfigReason.has_value()) {
443             return invalidConfigReason;
444         }
445         for (const int trackerIndex : conditionTracker->getAtomMatchingTrackerIndex()) {
446             vector<int>& conditionList = trackerToConditionMap[trackerIndex];
447             conditionList.push_back(conditionIndex);
448         }
449     }
450     return nullopt;
451 }
452 
updateStates(const StatsdConfig & config,const map<int64_t,uint64_t> & oldStateProtoHashes,unordered_map<int64_t,int> & stateAtomIdMap,unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,map<int64_t,uint64_t> & newStateProtoHashes,set<int64_t> & replacedStates)453 optional<InvalidConfigReason> updateStates(
454         const StatsdConfig& config, const map<int64_t, uint64_t>& oldStateProtoHashes,
455         unordered_map<int64_t, int>& stateAtomIdMap,
456         unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
457         map<int64_t, uint64_t>& newStateProtoHashes, set<int64_t>& replacedStates) {
458     // Share with metrics_manager_util.
459     optional<InvalidConfigReason> invalidConfigReason =
460             initStates(config, stateAtomIdMap, allStateGroupMaps, newStateProtoHashes);
461     if (invalidConfigReason.has_value()) {
462         return invalidConfigReason;
463     }
464 
465     for (const auto& [stateId, stateHash] : oldStateProtoHashes) {
466         const auto& it = newStateProtoHashes.find(stateId);
467         if (it != newStateProtoHashes.end() && it->second != stateHash) {
468             replacedStates.insert(stateId);
469         }
470     }
471     return nullopt;
472 }
473 // Returns true if any matchers in the metric activation were replaced.
metricActivationDepsChange(const StatsdConfig & config,const unordered_map<int64_t,int> & metricToActivationMap,const int64_t metricId,const set<int64_t> & replacedMatchers)474 bool metricActivationDepsChange(const StatsdConfig& config,
475                                 const unordered_map<int64_t, int>& metricToActivationMap,
476                                 const int64_t metricId, const set<int64_t>& replacedMatchers) {
477     const auto& metricActivationIt = metricToActivationMap.find(metricId);
478     if (metricActivationIt == metricToActivationMap.end()) {
479         return false;
480     }
481     const MetricActivation& metricActivation = config.metric_activation(metricActivationIt->second);
482     for (int i = 0; i < metricActivation.event_activation_size(); i++) {
483         const EventActivation& activation = metricActivation.event_activation(i);
484         if (replacedMatchers.find(activation.atom_matcher_id()) != replacedMatchers.end()) {
485             return true;
486         }
487         if (activation.has_deactivation_atom_matcher_id()) {
488             if (replacedMatchers.find(activation.deactivation_atom_matcher_id()) !=
489                 replacedMatchers.end()) {
490                 return true;
491             }
492         }
493     }
494     return false;
495 }
496 
determineMetricUpdateStatus(const StatsdConfig & config,const MessageLite & metric,const int64_t metricId,const MetricType metricType,const set<int64_t> & matcherDependencies,const set<int64_t> & conditionDependencies,const::google::protobuf::RepeatedField<int64_t> & stateDependencies,const::google::protobuf::RepeatedPtrField<MetricConditionLink> & conditionLinks,const unordered_map<int64_t,int> & oldMetricProducerMap,const vector<sp<MetricProducer>> & oldMetricProducers,const unordered_map<int64_t,int> & metricToActivationMap,const set<int64_t> & replacedMatchers,const set<int64_t> & replacedConditions,const set<int64_t> & replacedStates,UpdateStatus & updateStatus)497 optional<InvalidConfigReason> determineMetricUpdateStatus(
498         const StatsdConfig& config, const MessageLite& metric, const int64_t metricId,
499         const MetricType metricType, const set<int64_t>& matcherDependencies,
500         const set<int64_t>& conditionDependencies,
501         const ::google::protobuf::RepeatedField<int64_t>& stateDependencies,
502         const ::google::protobuf::RepeatedPtrField<MetricConditionLink>& conditionLinks,
503         const unordered_map<int64_t, int>& oldMetricProducerMap,
504         const vector<sp<MetricProducer>>& oldMetricProducers,
505         const unordered_map<int64_t, int>& metricToActivationMap,
506         const set<int64_t>& replacedMatchers, const set<int64_t>& replacedConditions,
507         const set<int64_t>& replacedStates, UpdateStatus& updateStatus) {
508     // Check if new metric
509     const auto& oldMetricProducerIt = oldMetricProducerMap.find(metricId);
510     if (oldMetricProducerIt == oldMetricProducerMap.end()) {
511         updateStatus = UPDATE_NEW;
512         return nullopt;
513     }
514 
515     // This is an existing metric, check if it has changed.
516     uint64_t metricHash;
517     optional<InvalidConfigReason> invalidConfigReason =
518             getMetricProtoHash(config, metric, metricId, metricToActivationMap, metricHash);
519     if (invalidConfigReason.has_value()) {
520         return invalidConfigReason;
521     }
522     const sp<MetricProducer> oldMetricProducer = oldMetricProducers[oldMetricProducerIt->second];
523     if (oldMetricProducer->getMetricType() != metricType ||
524         oldMetricProducer->getProtoHash() != metricHash) {
525         updateStatus = UPDATE_REPLACE;
526         return nullopt;
527     }
528 
529     // Take intersections of the matchers/predicates/states that the metric
530     // depends on with those that have been replaced. If a metric depends on any
531     // replaced component, it too must be replaced.
532     set<int64_t> intersection;
533     set_intersection(matcherDependencies.begin(), matcherDependencies.end(),
534                      replacedMatchers.begin(), replacedMatchers.end(),
535                      inserter(intersection, intersection.begin()));
536     if (intersection.size() > 0) {
537         updateStatus = UPDATE_REPLACE;
538         return nullopt;
539     }
540     set_intersection(conditionDependencies.begin(), conditionDependencies.end(),
541                      replacedConditions.begin(), replacedConditions.end(),
542                      inserter(intersection, intersection.begin()));
543     if (intersection.size() > 0) {
544         updateStatus = UPDATE_REPLACE;
545         return nullopt;
546     }
547     set_intersection(stateDependencies.begin(), stateDependencies.end(), replacedStates.begin(),
548                      replacedStates.end(), inserter(intersection, intersection.begin()));
549     if (intersection.size() > 0) {
550         updateStatus = UPDATE_REPLACE;
551         return nullopt;
552     }
553 
554     for (const auto& metricConditionLink : conditionLinks) {
555         if (replacedConditions.find(metricConditionLink.condition()) != replacedConditions.end()) {
556             updateStatus = UPDATE_REPLACE;
557             return nullopt;
558         }
559     }
560 
561     if (metricActivationDepsChange(config, metricToActivationMap, metricId, replacedMatchers)) {
562         updateStatus = UPDATE_REPLACE;
563         return nullopt;
564     }
565 
566     updateStatus = UPDATE_PRESERVE;
567     return nullopt;
568 }
569 
determineAllMetricUpdateStatuses(const StatsdConfig & config,const unordered_map<int64_t,int> & oldMetricProducerMap,const vector<sp<MetricProducer>> & oldMetricProducers,const unordered_map<int64_t,int> & metricToActivationMap,const set<int64_t> & replacedMatchers,const set<int64_t> & replacedConditions,const set<int64_t> & replacedStates,vector<UpdateStatus> & metricsToUpdate)570 optional<InvalidConfigReason> determineAllMetricUpdateStatuses(
571         const StatsdConfig& config, const unordered_map<int64_t, int>& oldMetricProducerMap,
572         const vector<sp<MetricProducer>>& oldMetricProducers,
573         const unordered_map<int64_t, int>& metricToActivationMap,
574         const set<int64_t>& replacedMatchers, const set<int64_t>& replacedConditions,
575         const set<int64_t>& replacedStates, vector<UpdateStatus>& metricsToUpdate) {
576     int metricIndex = 0;
577     optional<InvalidConfigReason> invalidConfigReason;
578     for (int i = 0; i < config.count_metric_size(); i++, metricIndex++) {
579         const CountMetric& metric = config.count_metric(i);
580         set<int64_t> conditionDependencies;
581         if (metric.has_condition()) {
582             conditionDependencies.insert(metric.condition());
583         }
584         invalidConfigReason = determineMetricUpdateStatus(
585                 config, metric, metric.id(), METRIC_TYPE_COUNT, {metric.what()},
586                 conditionDependencies, metric.slice_by_state(), metric.links(),
587                 oldMetricProducerMap, oldMetricProducers, metricToActivationMap, replacedMatchers,
588                 replacedConditions, replacedStates, metricsToUpdate[metricIndex]);
589         if (invalidConfigReason.has_value()) {
590             return invalidConfigReason;
591         }
592     }
593     for (int i = 0; i < config.duration_metric_size(); i++, metricIndex++) {
594         const DurationMetric& metric = config.duration_metric(i);
595         set<int64_t> conditionDependencies({metric.what()});
596         if (metric.has_condition()) {
597             conditionDependencies.insert(metric.condition());
598         }
599         invalidConfigReason = determineMetricUpdateStatus(
600                 config, metric, metric.id(), METRIC_TYPE_DURATION, /*matcherDependencies=*/{},
601                 conditionDependencies, metric.slice_by_state(), metric.links(),
602                 oldMetricProducerMap, oldMetricProducers, metricToActivationMap, replacedMatchers,
603                 replacedConditions, replacedStates, metricsToUpdate[metricIndex]);
604         if (invalidConfigReason.has_value()) {
605             return invalidConfigReason;
606         }
607     }
608     for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
609         const EventMetric& metric = config.event_metric(i);
610         set<int64_t> conditionDependencies;
611         if (metric.has_condition()) {
612             conditionDependencies.insert(metric.condition());
613         }
614         invalidConfigReason = determineMetricUpdateStatus(
615                 config, metric, metric.id(), METRIC_TYPE_EVENT, {metric.what()},
616                 conditionDependencies, ::google::protobuf::RepeatedField<int64_t>(), metric.links(),
617                 oldMetricProducerMap, oldMetricProducers, metricToActivationMap, replacedMatchers,
618                 replacedConditions, replacedStates, metricsToUpdate[metricIndex]);
619         if (invalidConfigReason.has_value()) {
620             return invalidConfigReason;
621         }
622     }
623     for (int i = 0; i < config.value_metric_size(); i++, metricIndex++) {
624         const ValueMetric& metric = config.value_metric(i);
625         set<int64_t> conditionDependencies;
626         if (metric.has_condition()) {
627             conditionDependencies.insert(metric.condition());
628         }
629         invalidConfigReason = determineMetricUpdateStatus(
630                 config, metric, metric.id(), METRIC_TYPE_VALUE, {metric.what()},
631                 conditionDependencies, metric.slice_by_state(), metric.links(),
632                 oldMetricProducerMap, oldMetricProducers, metricToActivationMap, replacedMatchers,
633                 replacedConditions, replacedStates, metricsToUpdate[metricIndex]);
634         if (invalidConfigReason.has_value()) {
635             return invalidConfigReason;
636         }
637     }
638     for (int i = 0; i < config.gauge_metric_size(); i++, metricIndex++) {
639         const GaugeMetric& metric = config.gauge_metric(i);
640         set<int64_t> conditionDependencies;
641         if (metric.has_condition()) {
642             conditionDependencies.insert(metric.condition());
643         }
644         set<int64_t> matcherDependencies({metric.what()});
645         if (metric.has_trigger_event()) {
646             matcherDependencies.insert(metric.trigger_event());
647         }
648         invalidConfigReason = determineMetricUpdateStatus(
649                 config, metric, metric.id(), METRIC_TYPE_GAUGE, matcherDependencies,
650                 conditionDependencies, ::google::protobuf::RepeatedField<int64_t>(), metric.links(),
651                 oldMetricProducerMap, oldMetricProducers, metricToActivationMap, replacedMatchers,
652                 replacedConditions, replacedStates, metricsToUpdate[metricIndex]);
653         if (invalidConfigReason.has_value()) {
654             return invalidConfigReason;
655         }
656     }
657 
658     for (int i = 0; i < config.kll_metric_size(); i++, metricIndex++) {
659         const KllMetric& metric = config.kll_metric(i);
660         set<int64_t> conditionDependencies;
661         if (metric.has_condition()) {
662             conditionDependencies.insert(metric.condition());
663         }
664         invalidConfigReason = determineMetricUpdateStatus(
665                 config, metric, metric.id(), METRIC_TYPE_KLL, {metric.what()},
666                 conditionDependencies, metric.slice_by_state(), metric.links(),
667                 oldMetricProducerMap, oldMetricProducers, metricToActivationMap, replacedMatchers,
668                 replacedConditions, replacedStates, metricsToUpdate[metricIndex]);
669         if (invalidConfigReason.has_value()) {
670             return invalidConfigReason;
671         }
672     }
673 
674     return nullopt;
675 }
676 
677 // Called when a metric is preserved during a config update. Finds the metric in oldMetricProducers
678 // and calls onConfigUpdated to update all indices.
updateMetric(const StatsdConfig & config,const int configIndex,const int metricIndex,const int64_t metricId,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & oldAtomMatchingTrackerMap,const unordered_map<int64_t,int> & newAtomMatchingTrackerMap,const sp<EventMatcherWizard> & matcherWizard,const vector<sp<ConditionTracker>> & allConditionTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const sp<ConditionWizard> & wizard,const unordered_map<int64_t,int> & oldMetricProducerMap,const vector<sp<MetricProducer>> & oldMetricProducers,const unordered_map<int64_t,int> & metricToActivationMap,unordered_map<int,vector<int>> & trackerToMetricMap,unordered_map<int,vector<int>> & conditionToMetricMap,unordered_map<int,vector<int>> & activationAtomTrackerToMetricMap,unordered_map<int,vector<int>> & deactivationAtomTrackerToMetricMap,vector<int> & metricsWithActivation,optional<InvalidConfigReason> & invalidConfigReason)679 optional<sp<MetricProducer>> updateMetric(
680         const StatsdConfig& config, const int configIndex, const int metricIndex,
681         const int64_t metricId, const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
682         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
683         const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
684         const sp<EventMatcherWizard>& matcherWizard,
685         const vector<sp<ConditionTracker>>& allConditionTrackers,
686         const unordered_map<int64_t, int>& conditionTrackerMap, const sp<ConditionWizard>& wizard,
687         const unordered_map<int64_t, int>& oldMetricProducerMap,
688         const vector<sp<MetricProducer>>& oldMetricProducers,
689         const unordered_map<int64_t, int>& metricToActivationMap,
690         unordered_map<int, vector<int>>& trackerToMetricMap,
691         unordered_map<int, vector<int>>& conditionToMetricMap,
692         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
693         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
694         vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
695     const auto& oldMetricProducerIt = oldMetricProducerMap.find(metricId);
696     if (oldMetricProducerIt == oldMetricProducerMap.end()) {
697         ALOGE("Could not find Metric %lld in the previous config, but expected it "
698               "to be there",
699               (long long)metricId);
700         invalidConfigReason =
701                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_NOT_IN_PREV_CONFIG, metricId);
702         return nullopt;
703     }
704     const int oldIndex = oldMetricProducerIt->second;
705     sp<MetricProducer> producer = oldMetricProducers[oldIndex];
706     invalidConfigReason = producer->onConfigUpdated(
707             config, configIndex, metricIndex, allAtomMatchingTrackers, oldAtomMatchingTrackerMap,
708             newAtomMatchingTrackerMap, matcherWizard, allConditionTrackers, conditionTrackerMap,
709             wizard, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
710             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
711             metricsWithActivation);
712     if (invalidConfigReason.has_value()) {
713         return nullopt;
714     }
715     return {producer};
716 }
717 
updateMetrics(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseNs,const int64_t currentTimeNs,const sp<StatsPullerManager> & pullerManager,const unordered_map<int64_t,int> & oldAtomMatchingTrackerMap,const unordered_map<int64_t,int> & newAtomMatchingTrackerMap,const set<int64_t> & replacedMatchers,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const set<int64_t> & replacedConditions,vector<sp<ConditionTracker>> & allConditionTrackers,const vector<ConditionState> & initialConditionCache,const unordered_map<int64_t,int> & stateAtomIdMap,const unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,const set<int64_t> & replacedStates,const unordered_map<int64_t,int> & oldMetricProducerMap,const vector<sp<MetricProducer>> & oldMetricProducers,unordered_map<int64_t,int> & newMetricProducerMap,vector<sp<MetricProducer>> & newMetricProducers,unordered_map<int,vector<int>> & conditionToMetricMap,unordered_map<int,vector<int>> & trackerToMetricMap,set<int64_t> & noReportMetricIds,unordered_map<int,vector<int>> & activationAtomTrackerToMetricMap,unordered_map<int,vector<int>> & deactivationAtomTrackerToMetricMap,vector<int> & metricsWithActivation,set<int64_t> & replacedMetrics)718 optional<InvalidConfigReason> updateMetrics(
719         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
720         const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
721         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
722         const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
723         const set<int64_t>& replacedMatchers,
724         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
725         const unordered_map<int64_t, int>& conditionTrackerMap,
726         const set<int64_t>& replacedConditions, vector<sp<ConditionTracker>>& allConditionTrackers,
727         const vector<ConditionState>& initialConditionCache,
728         const unordered_map<int64_t, int>& stateAtomIdMap,
729         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
730         const set<int64_t>& replacedStates, const unordered_map<int64_t, int>& oldMetricProducerMap,
731         const vector<sp<MetricProducer>>& oldMetricProducers,
732         unordered_map<int64_t, int>& newMetricProducerMap,
733         vector<sp<MetricProducer>>& newMetricProducers,
734         unordered_map<int, vector<int>>& conditionToMetricMap,
735         unordered_map<int, vector<int>>& trackerToMetricMap, set<int64_t>& noReportMetricIds,
736         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
737         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
738         vector<int>& metricsWithActivation, set<int64_t>& replacedMetrics) {
739     sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
740     sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchingTrackers);
741     const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
742                                 config.event_metric_size() + config.gauge_metric_size() +
743                                 config.value_metric_size() + config.kll_metric_size();
744     newMetricProducers.reserve(allMetricsCount);
745     optional<InvalidConfigReason> invalidConfigReason;
746 
747     if (config.has_restricted_metrics_delegate_package_name() &&
748         allMetricsCount != config.event_metric_size()) {
749         ALOGE("Restricted metrics only support event metric");
750         return InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED);
751     }
752 
753     // Construct map from metric id to metric activation index. The map will be used to determine
754     // the metric activation corresponding to a metric.
755     unordered_map<int64_t, int> metricToActivationMap;
756     for (int i = 0; i < config.metric_activation_size(); i++) {
757         const MetricActivation& metricActivation = config.metric_activation(i);
758         int64_t metricId = metricActivation.metric_id();
759         if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
760             ALOGE("Metric %lld has multiple MetricActivations", (long long)metricId);
761             return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_HAS_MULTIPLE_ACTIVATIONS,
762                                        metricId);
763         }
764         metricToActivationMap.insert({metricId, i});
765     }
766 
767     vector<UpdateStatus> metricsToUpdate(allMetricsCount, UPDATE_UNKNOWN);
768     invalidConfigReason = determineAllMetricUpdateStatuses(
769             config, oldMetricProducerMap, oldMetricProducers, metricToActivationMap,
770             replacedMatchers, replacedConditions, replacedStates, metricsToUpdate);
771     if (invalidConfigReason.has_value()) {
772         return invalidConfigReason;
773     }
774 
775     // Now, perform the update. Must iterate the metric types in the same order
776     int metricIndex = 0;
777     for (int i = 0; i < config.count_metric_size(); i++, metricIndex++) {
778         const CountMetric& metric = config.count_metric(i);
779         newMetricProducerMap[metric.id()] = metricIndex;
780         optional<sp<MetricProducer>> producer;
781         switch (metricsToUpdate[metricIndex]) {
782             case UPDATE_PRESERVE: {
783                 producer = updateMetric(
784                         config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
785                         oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
786                         allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
787                         oldMetricProducers, metricToActivationMap, trackerToMetricMap,
788                         conditionToMetricMap, activationAtomTrackerToMetricMap,
789                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
790                         invalidConfigReason);
791                 break;
792             }
793             case UPDATE_REPLACE:
794                 replacedMetrics.insert(metric.id());
795                 [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
796             case UPDATE_NEW: {
797                 producer = createCountMetricProducerAndUpdateMetadata(
798                         key, config, timeBaseNs, currentTimeNs, metric, metricIndex,
799                         allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
800                         conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
801                         allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
802                         conditionToMetricMap, activationAtomTrackerToMetricMap,
803                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
804                         invalidConfigReason);
805                 break;
806             }
807             default: {
808                 ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
809                       (long long)metric.id());
810                 return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_UPDATE_STATUS_UNKNOWN,
811                                            metric.id());
812             }
813         }
814         if (!producer) {
815             return invalidConfigReason;
816         }
817         newMetricProducers.push_back(producer.value());
818     }
819     for (int i = 0; i < config.duration_metric_size(); i++, metricIndex++) {
820         const DurationMetric& metric = config.duration_metric(i);
821         newMetricProducerMap[metric.id()] = metricIndex;
822         optional<sp<MetricProducer>> producer;
823         switch (metricsToUpdate[metricIndex]) {
824             case UPDATE_PRESERVE: {
825                 producer = updateMetric(
826                         config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
827                         oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
828                         allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
829                         oldMetricProducers, metricToActivationMap, trackerToMetricMap,
830                         conditionToMetricMap, activationAtomTrackerToMetricMap,
831                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
832                         invalidConfigReason);
833                 break;
834             }
835             case UPDATE_REPLACE:
836                 replacedMetrics.insert(metric.id());
837                 [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
838             case UPDATE_NEW: {
839                 producer = createDurationMetricProducerAndUpdateMetadata(
840                         key, config, timeBaseNs, currentTimeNs, metric, metricIndex,
841                         allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
842                         conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
843                         allStateGroupMaps, metricToActivationMap, trackerToMetricMap,
844                         conditionToMetricMap, activationAtomTrackerToMetricMap,
845                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
846                         invalidConfigReason);
847                 break;
848             }
849             default: {
850                 ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
851                       (long long)metric.id());
852                 return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_UPDATE_STATUS_UNKNOWN,
853                                            metric.id());
854             }
855         }
856         if (!producer) {
857             return invalidConfigReason;
858         }
859         newMetricProducers.push_back(producer.value());
860     }
861     for (int i = 0; i < config.event_metric_size(); i++, metricIndex++) {
862         const EventMetric& metric = config.event_metric(i);
863         newMetricProducerMap[metric.id()] = metricIndex;
864         optional<sp<MetricProducer>> producer;
865         switch (metricsToUpdate[metricIndex]) {
866             case UPDATE_PRESERVE: {
867                 producer = updateMetric(
868                         config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
869                         oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
870                         allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
871                         oldMetricProducers, metricToActivationMap, trackerToMetricMap,
872                         conditionToMetricMap, activationAtomTrackerToMetricMap,
873                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
874                         invalidConfigReason);
875                 break;
876             }
877             case UPDATE_REPLACE:
878                 replacedMetrics.insert(metric.id());
879                 [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
880             case UPDATE_NEW: {
881                 producer = createEventMetricProducerAndUpdateMetadata(
882                         key, config, timeBaseNs, metric, metricIndex, allAtomMatchingTrackers,
883                         newAtomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap,
884                         initialConditionCache, wizard, metricToActivationMap, trackerToMetricMap,
885                         conditionToMetricMap, activationAtomTrackerToMetricMap,
886                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
887                         invalidConfigReason);
888                 break;
889             }
890             default: {
891                 ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
892                       (long long)metric.id());
893                 return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_UPDATE_STATUS_UNKNOWN,
894                                            metric.id());
895             }
896         }
897         if (!producer) {
898             return invalidConfigReason;
899         }
900         newMetricProducers.push_back(producer.value());
901     }
902 
903     for (int i = 0; i < config.value_metric_size(); i++, metricIndex++) {
904         const ValueMetric& metric = config.value_metric(i);
905         newMetricProducerMap[metric.id()] = metricIndex;
906         optional<sp<MetricProducer>> producer;
907         switch (metricsToUpdate[metricIndex]) {
908             case UPDATE_PRESERVE: {
909                 producer = updateMetric(
910                         config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
911                         oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
912                         allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
913                         oldMetricProducers, metricToActivationMap, trackerToMetricMap,
914                         conditionToMetricMap, activationAtomTrackerToMetricMap,
915                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
916                         invalidConfigReason);
917                 break;
918             }
919             case UPDATE_REPLACE:
920                 replacedMetrics.insert(metric.id());
921                 [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
922             case UPDATE_NEW: {
923                 producer = createNumericValueMetricProducerAndUpdateMetadata(
924                         key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex,
925                         allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
926                         conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
927                         stateAtomIdMap, allStateGroupMaps, metricToActivationMap,
928                         trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
929                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
930                         invalidConfigReason);
931                 break;
932             }
933             default: {
934                 ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
935                       (long long)metric.id());
936                 return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_UPDATE_STATUS_UNKNOWN,
937                                            metric.id());
938             }
939         }
940         if (!producer) {
941             return invalidConfigReason;
942         }
943         newMetricProducers.push_back(producer.value());
944     }
945 
946     for (int i = 0; i < config.gauge_metric_size(); i++, metricIndex++) {
947         const GaugeMetric& metric = config.gauge_metric(i);
948         newMetricProducerMap[metric.id()] = metricIndex;
949         optional<sp<MetricProducer>> producer;
950         switch (metricsToUpdate[metricIndex]) {
951             case UPDATE_PRESERVE: {
952                 producer = updateMetric(
953                         config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
954                         oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
955                         allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
956                         oldMetricProducers, metricToActivationMap, trackerToMetricMap,
957                         conditionToMetricMap, activationAtomTrackerToMetricMap,
958                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
959                         invalidConfigReason);
960                 break;
961             }
962             case UPDATE_REPLACE:
963                 replacedMetrics.insert(metric.id());
964                 [[fallthrough]];  // Intentionally fallthrough to create the new metric producer.
965             case UPDATE_NEW: {
966                 producer = createGaugeMetricProducerAndUpdateMetadata(
967                         key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex,
968                         allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
969                         conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
970                         metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
971                         activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
972                         metricsWithActivation, invalidConfigReason);
973                 break;
974             }
975             default: {
976                 ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
977                       (long long)metric.id());
978                 return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_UPDATE_STATUS_UNKNOWN,
979                                            metric.id());
980             }
981         }
982         if (!producer) {
983             return invalidConfigReason;
984         }
985         newMetricProducers.push_back(producer.value());
986     }
987 
988     for (int i = 0; i < config.kll_metric_size(); i++, metricIndex++) {
989         const KllMetric& metric = config.kll_metric(i);
990         newMetricProducerMap[metric.id()] = metricIndex;
991         optional<sp<MetricProducer>> producer;
992         switch (metricsToUpdate[metricIndex]) {
993             case UPDATE_PRESERVE: {
994                 producer = updateMetric(
995                         config, i, metricIndex, metric.id(), allAtomMatchingTrackers,
996                         oldAtomMatchingTrackerMap, newAtomMatchingTrackerMap, matcherWizard,
997                         allConditionTrackers, conditionTrackerMap, wizard, oldMetricProducerMap,
998                         oldMetricProducers, metricToActivationMap, trackerToMetricMap,
999                         conditionToMetricMap, activationAtomTrackerToMetricMap,
1000                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
1001                         invalidConfigReason);
1002                 break;
1003             }
1004             case UPDATE_REPLACE:
1005                 replacedMetrics.insert(metric.id());
1006                 [[fallthrough]];  // Intentionally fallthrough to create the new metric
1007                                   // producer.
1008             case UPDATE_NEW: {
1009                 producer = createKllMetricProducerAndUpdateMetadata(
1010                         key, config, timeBaseNs, currentTimeNs, pullerManager, metric, metricIndex,
1011                         allAtomMatchingTrackers, newAtomMatchingTrackerMap, allConditionTrackers,
1012                         conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
1013                         stateAtomIdMap, allStateGroupMaps, metricToActivationMap,
1014                         trackerToMetricMap, conditionToMetricMap, activationAtomTrackerToMetricMap,
1015                         deactivationAtomTrackerToMetricMap, metricsWithActivation,
1016                         invalidConfigReason);
1017                 break;
1018             }
1019             default: {
1020                 ALOGE("Metric \"%lld\" update state is unknown. This should never happen",
1021                       (long long)metric.id());
1022                 return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_UPDATE_STATUS_UNKNOWN,
1023                                            metric.id());
1024             }
1025         }
1026         if (!producer) {
1027             return invalidConfigReason;
1028         }
1029         newMetricProducers.push_back(producer.value());
1030     }
1031 
1032     for (int i = 0; i < config.no_report_metric_size(); ++i) {
1033         const int64_t noReportMetric = config.no_report_metric(i);
1034         if (newMetricProducerMap.find(noReportMetric) == newMetricProducerMap.end()) {
1035             ALOGW("no_report_metric %" PRId64 " not exist", noReportMetric);
1036             return InvalidConfigReason(INVALID_CONFIG_REASON_NO_REPORT_METRIC_NOT_FOUND,
1037                                        noReportMetric);
1038         }
1039         noReportMetricIds.insert(noReportMetric);
1040     }
1041     const set<int> atomsAllowedFromAnyUid(config.whitelisted_atom_ids().begin(),
1042                                           config.whitelisted_atom_ids().end());
1043     for (int i = 0; i < allMetricsCount; i++) {
1044         sp<MetricProducer> producer = newMetricProducers[i];
1045         // Register metrics to StateTrackers
1046         for (int atomId : producer->getSlicedStateAtoms()) {
1047             // Register listener for atoms that use allowed_log_sources.
1048             // Using atoms allowed from any uid as a sliced state atom is not allowed.
1049             // Redo this check for all metrics in case the atoms allowed from any uid changed.
1050             if (atomsAllowedFromAnyUid.find(atomId) != atomsAllowedFromAnyUid.end()) {
1051                 return InvalidConfigReason(
1052                         INVALID_CONFIG_REASON_METRIC_SLICED_STATE_ATOM_ALLOWED_FROM_ANY_UID,
1053                         producer->getMetricId());
1054                 // Preserved metrics should've already registered.`
1055             } else if (metricsToUpdate[i] != UPDATE_PRESERVE) {
1056                 StateManager::getInstance().registerListener(atomId, producer);
1057             }
1058         }
1059     }
1060 
1061     // Init new/replaced metrics.
1062     for (size_t i = 0; i < newMetricProducers.size(); i++) {
1063         if (metricsToUpdate[i] == UPDATE_REPLACE || metricsToUpdate[i] == UPDATE_NEW) {
1064             newMetricProducers[i]->prepareFirstBucket();
1065         }
1066     }
1067 
1068     for (const sp<MetricProducer>& oldMetricProducer : oldMetricProducers) {
1069         const auto& it = newMetricProducerMap.find(oldMetricProducer->getMetricId());
1070         // Consider metric removed if it's not present in newMetricProducerMap or it's replaced.
1071         if (it == newMetricProducerMap.end() ||
1072             replacedMetrics.find(oldMetricProducer->getMetricId()) != replacedMetrics.end()) {
1073             oldMetricProducer->onMetricRemove();
1074         }
1075     }
1076     return nullopt;
1077 }
1078 
determineAlertUpdateStatus(const Alert & alert,const unordered_map<int64_t,int> & oldAlertTrackerMap,const vector<sp<AnomalyTracker>> & oldAnomalyTrackers,const set<int64_t> & replacedMetrics,UpdateStatus & updateStatus)1079 optional<InvalidConfigReason> determineAlertUpdateStatus(
1080         const Alert& alert, const unordered_map<int64_t, int>& oldAlertTrackerMap,
1081         const vector<sp<AnomalyTracker>>& oldAnomalyTrackers, const set<int64_t>& replacedMetrics,
1082         UpdateStatus& updateStatus) {
1083     // Check if new alert.
1084     const auto& oldAnomalyTrackerIt = oldAlertTrackerMap.find(alert.id());
1085     if (oldAnomalyTrackerIt == oldAlertTrackerMap.end()) {
1086         updateStatus = UPDATE_NEW;
1087         return nullopt;
1088     }
1089 
1090     // This is an existing alert, check if it has changed.
1091     string serializedAlert;
1092     if (!alert.SerializeToString(&serializedAlert)) {
1093         ALOGW("Unable to serialize alert %lld", (long long)alert.id());
1094         return createInvalidConfigReasonWithAlert(INVALID_CONFIG_REASON_ALERT_SERIALIZATION_FAILED,
1095                                                   alert.id());
1096     }
1097     uint64_t newProtoHash = Hash64(serializedAlert);
1098     const auto [invalidConfigReason, oldProtoHash] =
1099             oldAnomalyTrackers[oldAnomalyTrackerIt->second]->getProtoHash();
1100     if (invalidConfigReason.has_value()) {
1101         return invalidConfigReason;
1102     }
1103     if (newProtoHash != oldProtoHash) {
1104         updateStatus = UPDATE_REPLACE;
1105         return nullopt;
1106     }
1107 
1108     // Check if the metric this alert relies on has changed.
1109     if (replacedMetrics.find(alert.metric_id()) != replacedMetrics.end()) {
1110         updateStatus = UPDATE_REPLACE;
1111         return nullopt;
1112     }
1113 
1114     updateStatus = UPDATE_PRESERVE;
1115     return nullopt;
1116 }
1117 
updateAlerts(const StatsdConfig & config,const int64_t currentTimeNs,const unordered_map<int64_t,int> & metricProducerMap,const set<int64_t> & replacedMetrics,const unordered_map<int64_t,int> & oldAlertTrackerMap,const vector<sp<AnomalyTracker>> & oldAnomalyTrackers,const sp<AlarmMonitor> & anomalyAlarmMonitor,vector<sp<MetricProducer>> & allMetricProducers,unordered_map<int64_t,int> & newAlertTrackerMap,vector<sp<AnomalyTracker>> & newAnomalyTrackers)1118 optional<InvalidConfigReason> updateAlerts(const StatsdConfig& config, const int64_t currentTimeNs,
1119                                            const unordered_map<int64_t, int>& metricProducerMap,
1120                                            const set<int64_t>& replacedMetrics,
1121                                            const unordered_map<int64_t, int>& oldAlertTrackerMap,
1122                                            const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
1123                                            const sp<AlarmMonitor>& anomalyAlarmMonitor,
1124                                            vector<sp<MetricProducer>>& allMetricProducers,
1125                                            unordered_map<int64_t, int>& newAlertTrackerMap,
1126                                            vector<sp<AnomalyTracker>>& newAnomalyTrackers) {
1127     int alertCount = config.alert_size();
1128     vector<UpdateStatus> alertUpdateStatuses(alertCount);
1129     optional<InvalidConfigReason> invalidConfigReason;
1130     for (int i = 0; i < alertCount; i++) {
1131         invalidConfigReason =
1132                 determineAlertUpdateStatus(config.alert(i), oldAlertTrackerMap, oldAnomalyTrackers,
1133                                            replacedMetrics, alertUpdateStatuses[i]);
1134         if (invalidConfigReason.has_value()) {
1135             return invalidConfigReason;
1136         }
1137     }
1138 
1139     for (int i = 0; i < alertCount; i++) {
1140         const Alert& alert = config.alert(i);
1141         newAlertTrackerMap[alert.id()] = newAnomalyTrackers.size();
1142         switch (alertUpdateStatuses[i]) {
1143             case UPDATE_PRESERVE: {
1144                 // Find the alert and update it.
1145                 const auto& oldAnomalyTrackerIt = oldAlertTrackerMap.find(alert.id());
1146                 if (oldAnomalyTrackerIt == oldAlertTrackerMap.end()) {
1147                     ALOGW("Could not find AnomalyTracker %lld in the previous config, but "
1148                           "expected it to be there",
1149                           (long long)alert.id());
1150                     return createInvalidConfigReasonWithAlert(
1151                             INVALID_CONFIG_REASON_ALERT_NOT_IN_PREV_CONFIG, alert.id());
1152                 }
1153                 sp<AnomalyTracker> anomalyTracker = oldAnomalyTrackers[oldAnomalyTrackerIt->second];
1154                 anomalyTracker->onConfigUpdated();
1155                 // Add the alert to the relevant metric.
1156                 const auto& metricProducerIt = metricProducerMap.find(alert.metric_id());
1157                 if (metricProducerIt == metricProducerMap.end()) {
1158                     ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
1159                           (long long)alert.metric_id());
1160                     return createInvalidConfigReasonWithAlert(
1161                             INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND, alert.metric_id(),
1162                             alert.id());
1163                 }
1164                 allMetricProducers[metricProducerIt->second]->addAnomalyTracker(anomalyTracker,
1165                                                                                 currentTimeNs);
1166                 newAnomalyTrackers.push_back(anomalyTracker);
1167                 break;
1168             }
1169             case UPDATE_REPLACE:
1170             case UPDATE_NEW: {
1171                 optional<sp<AnomalyTracker>> anomalyTracker = createAnomalyTracker(
1172                         alert, anomalyAlarmMonitor, alertUpdateStatuses[i], currentTimeNs,
1173                         metricProducerMap, allMetricProducers, invalidConfigReason);
1174                 if (!anomalyTracker) {
1175                     return invalidConfigReason;
1176                 }
1177                 newAnomalyTrackers.push_back(anomalyTracker.value());
1178                 break;
1179             }
1180             default: {
1181                 ALOGE("Alert \"%lld\" update state is unknown. This should never happen",
1182                       (long long)alert.id());
1183                 return createInvalidConfigReasonWithAlert(
1184                         INVALID_CONFIG_REASON_ALERT_UPDATE_STATUS_UNKNOWN, alert.id());
1185             }
1186         }
1187     }
1188     invalidConfigReason = initSubscribersForSubscriptionType(
1189             config, Subscription::ALERT, newAlertTrackerMap, newAnomalyTrackers);
1190     if (invalidConfigReason.has_value()) {
1191         return invalidConfigReason;
1192     }
1193     return nullopt;
1194 }
1195 
updateStatsdConfig(const ConfigKey & key,const StatsdConfig & config,const sp<UidMap> & uidMap,const sp<StatsPullerManager> & pullerManager,const sp<AlarmMonitor> & anomalyAlarmMonitor,const sp<AlarmMonitor> & periodicAlarmMonitor,const int64_t timeBaseNs,const int64_t currentTimeNs,const vector<sp<AtomMatchingTracker>> & oldAtomMatchingTrackers,const unordered_map<int64_t,int> & oldAtomMatchingTrackerMap,const vector<sp<ConditionTracker>> & oldConditionTrackers,const unordered_map<int64_t,int> & oldConditionTrackerMap,const vector<sp<MetricProducer>> & oldMetricProducers,const unordered_map<int64_t,int> & oldMetricProducerMap,const vector<sp<AnomalyTracker>> & oldAnomalyTrackers,const unordered_map<int64_t,int> & oldAlertTrackerMap,const map<int64_t,uint64_t> & oldStateProtoHashes,std::unordered_map<int,std::vector<int>> & allTagIdsToMatchersMap,vector<sp<AtomMatchingTracker>> & newAtomMatchingTrackers,unordered_map<int64_t,int> & newAtomMatchingTrackerMap,vector<sp<ConditionTracker>> & newConditionTrackers,unordered_map<int64_t,int> & newConditionTrackerMap,vector<sp<MetricProducer>> & newMetricProducers,unordered_map<int64_t,int> & newMetricProducerMap,vector<sp<AnomalyTracker>> & newAnomalyTrackers,unordered_map<int64_t,int> & newAlertTrackerMap,vector<sp<AlarmTracker>> & newPeriodicAlarmTrackers,unordered_map<int,vector<int>> & conditionToMetricMap,unordered_map<int,vector<int>> & trackerToMetricMap,unordered_map<int,vector<int>> & trackerToConditionMap,unordered_map<int,vector<int>> & activationTrackerToMetricMap,unordered_map<int,vector<int>> & deactivationTrackerToMetricMap,vector<int> & metricsWithActivation,map<int64_t,uint64_t> & newStateProtoHashes,set<int64_t> & noReportMetricIds)1196 optional<InvalidConfigReason> updateStatsdConfig(
1197         const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
1198         const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor,
1199         const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
1200         const int64_t currentTimeNs, const vector<sp<AtomMatchingTracker>>& oldAtomMatchingTrackers,
1201         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
1202         const vector<sp<ConditionTracker>>& oldConditionTrackers,
1203         const unordered_map<int64_t, int>& oldConditionTrackerMap,
1204         const vector<sp<MetricProducer>>& oldMetricProducers,
1205         const unordered_map<int64_t, int>& oldMetricProducerMap,
1206         const vector<sp<AnomalyTracker>>& oldAnomalyTrackers,
1207         const unordered_map<int64_t, int>& oldAlertTrackerMap,
1208         const map<int64_t, uint64_t>& oldStateProtoHashes,
1209         std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
1210         vector<sp<AtomMatchingTracker>>& newAtomMatchingTrackers,
1211         unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
1212         vector<sp<ConditionTracker>>& newConditionTrackers,
1213         unordered_map<int64_t, int>& newConditionTrackerMap,
1214         vector<sp<MetricProducer>>& newMetricProducers,
1215         unordered_map<int64_t, int>& newMetricProducerMap,
1216         vector<sp<AnomalyTracker>>& newAnomalyTrackers,
1217         unordered_map<int64_t, int>& newAlertTrackerMap,
1218         vector<sp<AlarmTracker>>& newPeriodicAlarmTrackers,
1219         unordered_map<int, vector<int>>& conditionToMetricMap,
1220         unordered_map<int, vector<int>>& trackerToMetricMap,
1221         unordered_map<int, vector<int>>& trackerToConditionMap,
1222         unordered_map<int, vector<int>>& activationTrackerToMetricMap,
1223         unordered_map<int, vector<int>>& deactivationTrackerToMetricMap,
1224         vector<int>& metricsWithActivation, map<int64_t, uint64_t>& newStateProtoHashes,
1225         set<int64_t>& noReportMetricIds) {
1226     set<int64_t> replacedMatchers;
1227     set<int64_t> replacedConditions;
1228     set<int64_t> replacedStates;
1229     set<int64_t> replacedMetrics;
1230     vector<ConditionState> conditionCache;
1231     unordered_map<int64_t, int> stateAtomIdMap;
1232     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
1233 
1234     if (config.package_certificate_hash_size_bytes() > UINT8_MAX) {
1235         ALOGE("Invalid value for package_certificate_hash_size_bytes: %d",
1236               config.package_certificate_hash_size_bytes());
1237         return InvalidConfigReason(INVALID_CONFIG_REASON_PACKAGE_CERT_HASH_SIZE_TOO_LARGE);
1238     }
1239 
1240     optional<InvalidConfigReason> invalidConfigReason = updateAtomMatchingTrackers(
1241             config, uidMap, oldAtomMatchingTrackerMap, oldAtomMatchingTrackers,
1242             allTagIdsToMatchersMap, newAtomMatchingTrackerMap, newAtomMatchingTrackers,
1243             replacedMatchers);
1244     if (invalidConfigReason.has_value()) {
1245         ALOGE("updateAtomMatchingTrackers failed");
1246         return invalidConfigReason;
1247     }
1248 
1249     invalidConfigReason = updateConditions(
1250             key, config, newAtomMatchingTrackerMap, replacedMatchers, oldConditionTrackerMap,
1251             oldConditionTrackers, newConditionTrackerMap, newConditionTrackers,
1252             trackerToConditionMap, conditionCache, replacedConditions);
1253     if (invalidConfigReason.has_value()) {
1254         ALOGE("updateConditions failed");
1255         return invalidConfigReason;
1256     }
1257 
1258     invalidConfigReason = updateStates(config, oldStateProtoHashes, stateAtomIdMap,
1259                                        allStateGroupMaps, newStateProtoHashes, replacedStates);
1260     if (invalidConfigReason.has_value()) {
1261         ALOGE("updateStates failed");
1262         return invalidConfigReason;
1263     }
1264 
1265     invalidConfigReason = updateMetrics(
1266             key, config, timeBaseNs, currentTimeNs, pullerManager, oldAtomMatchingTrackerMap,
1267             newAtomMatchingTrackerMap, replacedMatchers, newAtomMatchingTrackers,
1268             newConditionTrackerMap, replacedConditions, newConditionTrackers, conditionCache,
1269             stateAtomIdMap, allStateGroupMaps, replacedStates, oldMetricProducerMap,
1270             oldMetricProducers, newMetricProducerMap, newMetricProducers, conditionToMetricMap,
1271             trackerToMetricMap, noReportMetricIds, activationTrackerToMetricMap,
1272             deactivationTrackerToMetricMap, metricsWithActivation, replacedMetrics);
1273     if (invalidConfigReason.has_value()) {
1274         ALOGE("updateMetrics failed");
1275         return invalidConfigReason;
1276     }
1277 
1278     invalidConfigReason = updateAlerts(config, currentTimeNs, newMetricProducerMap, replacedMetrics,
1279                                        oldAlertTrackerMap, oldAnomalyTrackers, anomalyAlarmMonitor,
1280                                        newMetricProducers, newAlertTrackerMap, newAnomalyTrackers);
1281     if (invalidConfigReason.has_value()) {
1282         ALOGE("updateAlerts failed");
1283         return invalidConfigReason;
1284     }
1285 
1286     invalidConfigReason = initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
1287                                      newPeriodicAlarmTrackers);
1288     // Alarms do not have any state, so we can reuse the initialization logic.
1289     if (invalidConfigReason.has_value()) {
1290         ALOGE("initAlarms failed");
1291         return invalidConfigReason;
1292     }
1293     return nullopt;
1294 }
1295 
1296 }  // namespace statsd
1297 }  // namespace os
1298 }  // namespace android
1299