• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 "metrics_manager_util.h"
21 
22 #include <inttypes.h>
23 
24 #include "FieldValue.h"
25 #include "condition/CombinationConditionTracker.h"
26 #include "condition/SimpleConditionTracker.h"
27 #include "external/StatsPullerManager.h"
28 #include "guardrail/StatsdStats.h"
29 #include "hash.h"
30 #include "matchers/CombinationAtomMatchingTracker.h"
31 #include "matchers/EventMatcherWizard.h"
32 #include "matchers/SimpleAtomMatchingTracker.h"
33 #include "metrics/CountMetricProducer.h"
34 #include "metrics/DurationMetricProducer.h"
35 #include "metrics/EventMetricProducer.h"
36 #include "metrics/GaugeMetricProducer.h"
37 #include "metrics/KllMetricProducer.h"
38 #include "metrics/MetricProducer.h"
39 #include "metrics/NumericValueMetricProducer.h"
40 #include "metrics/RestrictedEventMetricProducer.h"
41 #include "state/StateManager.h"
42 #include "stats_util.h"
43 
44 using google::protobuf::MessageLite;
45 using std::set;
46 using std::unordered_map;
47 using std::vector;
48 
49 namespace android {
50 namespace os {
51 namespace statsd {
52 
53 namespace {
54 
hasLeafNode(const FieldMatcher & matcher)55 bool hasLeafNode(const FieldMatcher& matcher) {
56     if (!matcher.has_field()) {
57         return false;
58     }
59     for (int i = 0; i < matcher.child_size(); ++i) {
60         if (hasLeafNode(matcher.child(i))) {
61             return true;
62         }
63     }
64     return true;
65 }
66 
67 }  // namespace
68 
createAtomMatchingTracker(const AtomMatcher & logMatcher,const int index,const sp<UidMap> & uidMap,optional<InvalidConfigReason> & invalidConfigReason)69 sp<AtomMatchingTracker> createAtomMatchingTracker(
70         const AtomMatcher& logMatcher, const int index, const sp<UidMap>& uidMap,
71         optional<InvalidConfigReason>& invalidConfigReason) {
72     string serializedMatcher;
73     if (!logMatcher.SerializeToString(&serializedMatcher)) {
74         ALOGE("Unable to serialize matcher %lld", (long long)logMatcher.id());
75         invalidConfigReason = createInvalidConfigReasonWithMatcher(
76                 INVALID_CONFIG_REASON_MATCHER_SERIALIZATION_FAILED, logMatcher.id());
77         return nullptr;
78     }
79     uint64_t protoHash = Hash64(serializedMatcher);
80     switch (logMatcher.contents_case()) {
81         case AtomMatcher::ContentsCase::kSimpleAtomMatcher: {
82             sp<AtomMatchingTracker> simpleAtomMatcher = new SimpleAtomMatchingTracker(
83                     logMatcher.id(), index, protoHash, logMatcher.simple_atom_matcher(), uidMap);
84             return simpleAtomMatcher;
85         }
86         case AtomMatcher::ContentsCase::kCombination:
87             return new CombinationAtomMatchingTracker(logMatcher.id(), index, protoHash);
88         default:
89             ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
90             invalidConfigReason = createInvalidConfigReasonWithMatcher(
91                     INVALID_CONFIG_REASON_MATCHER_MALFORMED_CONTENTS_CASE, logMatcher.id());
92             return nullptr;
93     }
94 }
95 
createConditionTracker(const ConfigKey & key,const Predicate & predicate,const int index,const unordered_map<int64_t,int> & atomMatchingTrackerMap,optional<InvalidConfigReason> & invalidConfigReason)96 sp<ConditionTracker> createConditionTracker(
97         const ConfigKey& key, const Predicate& predicate, const int index,
98         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
99         optional<InvalidConfigReason>& invalidConfigReason) {
100     string serializedPredicate;
101     if (!predicate.SerializeToString(&serializedPredicate)) {
102         ALOGE("Unable to serialize predicate %lld", (long long)predicate.id());
103         invalidConfigReason = createInvalidConfigReasonWithPredicate(
104                 INVALID_CONFIG_REASON_CONDITION_SERIALIZATION_FAILED, predicate.id());
105         return nullptr;
106     }
107     uint64_t protoHash = Hash64(serializedPredicate);
108     switch (predicate.contents_case()) {
109         case Predicate::ContentsCase::kSimplePredicate: {
110             return new SimpleConditionTracker(key, predicate.id(), protoHash, index,
111                                               predicate.simple_predicate(), atomMatchingTrackerMap);
112         }
113         case Predicate::ContentsCase::kCombination: {
114             return new CombinationConditionTracker(predicate.id(), index, protoHash);
115         }
116         default:
117             ALOGE("Predicate \"%lld\" malformed", (long long)predicate.id());
118             invalidConfigReason = createInvalidConfigReasonWithPredicate(
119                     INVALID_CONFIG_REASON_CONDITION_MALFORMED_CONTENTS_CASE, predicate.id());
120             return nullptr;
121     }
122 }
123 
getMetricProtoHash(const StatsdConfig & config,const MessageLite & metric,const int64_t id,const unordered_map<int64_t,int> & metricToActivationMap,uint64_t & metricHash)124 optional<InvalidConfigReason> getMetricProtoHash(
125         const StatsdConfig& config, const MessageLite& metric, const int64_t id,
126         const unordered_map<int64_t, int>& metricToActivationMap, uint64_t& metricHash) {
127     string serializedMetric;
128     if (!metric.SerializeToString(&serializedMetric)) {
129         ALOGE("Unable to serialize metric %lld", (long long)id);
130         return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SERIALIZATION_FAILED, id);
131     }
132     metricHash = Hash64(serializedMetric);
133 
134     // Combine with activation hash, if applicable
135     const auto& metricActivationIt = metricToActivationMap.find(id);
136     if (metricActivationIt != metricToActivationMap.end()) {
137         string serializedActivation;
138         const MetricActivation& activation = config.metric_activation(metricActivationIt->second);
139         if (!activation.SerializeToString(&serializedActivation)) {
140             ALOGE("Unable to serialize metric activation for metric %lld", (long long)id);
141             return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_ACTIVATION_SERIALIZATION_FAILED,
142                                        id);
143         }
144         metricHash = Hash64(to_string(metricHash).append(to_string(Hash64(serializedActivation))));
145     }
146     return nullopt;
147 }
148 
handleMetricWithAtomMatchingTrackers(const int64_t matcherId,const int64_t metricId,const int metricIndex,const bool enforceOneAtom,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & atomMatchingTrackerMap,unordered_map<int,vector<int>> & trackerToMetricMap,int & logTrackerIndex)149 optional<InvalidConfigReason> handleMetricWithAtomMatchingTrackers(
150         const int64_t matcherId, const int64_t metricId, const int metricIndex,
151         const bool enforceOneAtom, const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
152         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
153         unordered_map<int, vector<int>>& trackerToMetricMap, int& logTrackerIndex) {
154     auto logTrackerIt = atomMatchingTrackerMap.find(matcherId);
155     if (logTrackerIt == atomMatchingTrackerMap.end()) {
156         ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)matcherId);
157         return createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_METRIC_MATCHER_NOT_FOUND,
158                                                     metricId, matcherId);
159     }
160     if (enforceOneAtom && allAtomMatchingTrackers[logTrackerIt->second]->getAtomIds().size() > 1) {
161         ALOGE("AtomMatcher \"%lld\" has more than one tag ids. When a metric has dimension, "
162               "the \"what\" can only be about one atom type. trigger_event matchers can also only "
163               "be about one atom type.",
164               (long long)matcherId);
165         return createInvalidConfigReasonWithMatcher(
166                 INVALID_CONFIG_REASON_METRIC_MATCHER_MORE_THAN_ONE_ATOM, metricId, matcherId);
167     }
168     logTrackerIndex = logTrackerIt->second;
169     auto& metric_list = trackerToMetricMap[logTrackerIndex];
170     metric_list.push_back(metricIndex);
171     return nullopt;
172 }
173 
handleMetricWithConditions(const int64_t condition,const int64_t metricId,const int metricIndex,const unordered_map<int64_t,int> & conditionTrackerMap,const::google::protobuf::RepeatedPtrField<MetricConditionLink> & links,const vector<sp<ConditionTracker>> & allConditionTrackers,int & conditionIndex,unordered_map<int,vector<int>> & conditionToMetricMap)174 optional<InvalidConfigReason> handleMetricWithConditions(
175         const int64_t condition, const int64_t metricId, const int metricIndex,
176         const unordered_map<int64_t, int>& conditionTrackerMap,
177         const ::google::protobuf::RepeatedPtrField<MetricConditionLink>& links,
178         const vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex,
179         unordered_map<int, vector<int>>& conditionToMetricMap) {
180     auto condition_it = conditionTrackerMap.find(condition);
181     if (condition_it == conditionTrackerMap.end()) {
182         ALOGW("cannot find Predicate \"%lld\" in the config", (long long)condition);
183         return createInvalidConfigReasonWithPredicate(
184                 INVALID_CONFIG_REASON_METRIC_CONDITION_NOT_FOUND, metricId, condition);
185     }
186     for (const auto& link : links) {
187         auto it = conditionTrackerMap.find(link.condition());
188         if (it == conditionTrackerMap.end()) {
189             ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
190             return createInvalidConfigReasonWithPredicate(
191                     INVALID_CONFIG_REASON_METRIC_CONDITION_LINK_NOT_FOUND, metricId,
192                     link.condition());
193         }
194     }
195     conditionIndex = condition_it->second;
196 
197     // will create new vector if not exist before.
198     auto& metricList = conditionToMetricMap[condition_it->second];
199     metricList.push_back(metricIndex);
200     return nullopt;
201 }
202 
203 // Initializes state data structures for a metric.
204 // input:
205 // [config]: the input config
206 // [stateIds]: the slice_by_state ids for this metric
207 // [stateAtomIdMap]: this map contains the mapping from all state ids to atom ids
208 // [allStateGroupMaps]: this map contains the mapping from state ids and state
209 //                      values to state group ids for all states
210 // output:
211 // [slicedStateAtoms]: a vector of atom ids of all the slice_by_states
212 // [stateGroupMap]: this map should contain the mapping from states ids and state
213 //                      values to state group ids for all states that this metric
214 //                      is interested in
handleMetricWithStates(const StatsdConfig & config,const int64_t metricId,const::google::protobuf::RepeatedField<int64_t> & stateIds,const unordered_map<int64_t,int> & stateAtomIdMap,const unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,vector<int> & slicedStateAtoms,unordered_map<int,unordered_map<int,int64_t>> & stateGroupMap)215 optional<InvalidConfigReason> handleMetricWithStates(
216         const StatsdConfig& config, const int64_t metricId,
217         const ::google::protobuf::RepeatedField<int64_t>& stateIds,
218         const unordered_map<int64_t, int>& stateAtomIdMap,
219         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
220         vector<int>& slicedStateAtoms,
221         unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap) {
222     for (const auto& stateId : stateIds) {
223         auto it = stateAtomIdMap.find(stateId);
224         if (it == stateAtomIdMap.end()) {
225             ALOGW("cannot find State %" PRId64 " in the config", stateId);
226             return createInvalidConfigReasonWithState(INVALID_CONFIG_REASON_METRIC_STATE_NOT_FOUND,
227                                                       metricId, stateId);
228         }
229         int atomId = it->second;
230         slicedStateAtoms.push_back(atomId);
231 
232         auto stateIt = allStateGroupMaps.find(stateId);
233         if (stateIt != allStateGroupMaps.end()) {
234             stateGroupMap[atomId] = stateIt->second;
235         }
236     }
237     return nullopt;
238 }
239 
handleMetricWithStateLink(const int64_t metricId,const FieldMatcher & stateMatcher,const vector<Matcher> & dimensionsInWhat)240 optional<InvalidConfigReason> handleMetricWithStateLink(const int64_t metricId,
241                                                         const FieldMatcher& stateMatcher,
242                                                         const vector<Matcher>& dimensionsInWhat) {
243     vector<Matcher> stateMatchers;
244     translateFieldMatcher(stateMatcher, &stateMatchers);
245     if (!subsetDimensions(stateMatchers, dimensionsInWhat)) {
246         return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_STATELINKS_NOT_SUBSET_DIM_IN_WHAT,
247                                    metricId);
248     }
249     return nullopt;
250 }
251 
handleMetricWithSampling(const int64_t metricId,const DimensionalSamplingInfo & dimSamplingInfo,const vector<Matcher> & dimensionsInWhat,SamplingInfo & samplingInfo)252 optional<InvalidConfigReason> handleMetricWithSampling(
253         const int64_t metricId, const DimensionalSamplingInfo& dimSamplingInfo,
254         const vector<Matcher>& dimensionsInWhat, SamplingInfo& samplingInfo) {
255     if (!dimSamplingInfo.has_sampled_what_field()) {
256         ALOGE("metric DimensionalSamplingInfo missing sampledWhatField");
257         return InvalidConfigReason(
258                 INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_MISSING_SAMPLED_FIELD,
259                 metricId);
260     }
261 
262     if (dimSamplingInfo.shard_count() <= 1) {
263         ALOGE("metric shardCount must be > 1");
264         return InvalidConfigReason(
265                 INVALID_CONFIG_REASON_METRIC_DIMENSIONAL_SAMPLING_INFO_INCORRECT_SHARD_COUNT,
266                 metricId);
267     }
268     samplingInfo.shardCount = dimSamplingInfo.shard_count();
269 
270     if (HasPositionALL(dimSamplingInfo.sampled_what_field()) ||
271         HasPositionANY(dimSamplingInfo.sampled_what_field())) {
272         ALOGE("metric has repeated field with position ALL or ANY as the sampled dimension");
273         return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
274                                    metricId);
275     }
276 
277     translateFieldMatcher(dimSamplingInfo.sampled_what_field(), &samplingInfo.sampledWhatFields);
278     if (samplingInfo.sampledWhatFields.size() != 1) {
279         ALOGE("metric has incorrect number of sampled dimension fields");
280         return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELD_INCORRECT_SIZE,
281                                    metricId);
282     }
283     if (!subsetDimensions(samplingInfo.sampledWhatFields, dimensionsInWhat)) {
284         return InvalidConfigReason(
285                 INVALID_CONFIG_REASON_METRIC_SAMPLED_FIELDS_NOT_SUBSET_DIM_IN_WHAT, metricId);
286     }
287     return nullopt;
288 }
289 
290 // Validates a metricActivation and populates state.
291 // EventActivationMap and EventDeactivationMap are supplied to a MetricProducer
292 //      to provide the producer with state about its activators and deactivators.
293 // Returns false if there are errors.
handleMetricActivation(const StatsdConfig & config,const int64_t metricId,const int metricIndex,const unordered_map<int64_t,int> & metricToActivationMap,const unordered_map<int64_t,int> & atomMatchingTrackerMap,unordered_map<int,vector<int>> & activationAtomTrackerToMetricMap,unordered_map<int,vector<int>> & deactivationAtomTrackerToMetricMap,vector<int> & metricsWithActivation,unordered_map<int,shared_ptr<Activation>> & eventActivationMap,unordered_map<int,vector<shared_ptr<Activation>>> & eventDeactivationMap)294 optional<InvalidConfigReason> handleMetricActivation(
295         const StatsdConfig& config, const int64_t metricId, const int metricIndex,
296         const unordered_map<int64_t, int>& metricToActivationMap,
297         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
298         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
299         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
300         vector<int>& metricsWithActivation,
301         unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
302         unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap) {
303     // Check if metric has an associated activation
304     auto itr = metricToActivationMap.find(metricId);
305     if (itr == metricToActivationMap.end()) {
306         return nullopt;
307     }
308 
309     int activationIndex = itr->second;
310     const MetricActivation& metricActivation = config.metric_activation(activationIndex);
311 
312     for (int i = 0; i < metricActivation.event_activation_size(); i++) {
313         const EventActivation& activation = metricActivation.event_activation(i);
314 
315         auto itr = atomMatchingTrackerMap.find(activation.atom_matcher_id());
316         if (itr == atomMatchingTrackerMap.end()) {
317             ALOGE("Atom matcher not found for event activation.");
318             return createInvalidConfigReasonWithMatcher(
319                     INVALID_CONFIG_REASON_METRIC_ACTIVATION_MATCHER_NOT_FOUND, metricId,
320                     activation.atom_matcher_id());
321         }
322 
323         ActivationType activationType = (activation.has_activation_type())
324                                                 ? activation.activation_type()
325                                                 : metricActivation.activation_type();
326         std::shared_ptr<Activation> activationWrapper =
327                 std::make_shared<Activation>(activationType, activation.ttl_seconds() * NS_PER_SEC);
328 
329         int atomMatcherIndex = itr->second;
330         activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex);
331         eventActivationMap.emplace(atomMatcherIndex, activationWrapper);
332 
333         if (activation.has_deactivation_atom_matcher_id()) {
334             itr = atomMatchingTrackerMap.find(activation.deactivation_atom_matcher_id());
335             if (itr == atomMatchingTrackerMap.end()) {
336                 ALOGE("Atom matcher not found for event deactivation.");
337                 return createInvalidConfigReasonWithMatcher(
338                         INVALID_CONFIG_REASON_METRIC_DEACTIVATION_MATCHER_NOT_FOUND, metricId,
339                         activation.deactivation_atom_matcher_id());
340             }
341             int deactivationAtomMatcherIndex = itr->second;
342             deactivationAtomTrackerToMetricMap[deactivationAtomMatcherIndex].push_back(metricIndex);
343             eventDeactivationMap[deactivationAtomMatcherIndex].push_back(activationWrapper);
344         }
345     }
346 
347     metricsWithActivation.push_back(metricIndex);
348     return nullopt;
349 }
350 
351 // Validates a metricActivation and populates state.
352 // Fills the new event activation/deactivation maps, preserving the existing activations
353 // Returns false if there are errors.
handleMetricActivationOnConfigUpdate(const StatsdConfig & config,const int64_t metricId,const int metricIndex,const unordered_map<int64_t,int> & metricToActivationMap,const unordered_map<int64_t,int> & oldAtomMatchingTrackerMap,const unordered_map<int64_t,int> & newAtomMatchingTrackerMap,const unordered_map<int,shared_ptr<Activation>> & oldEventActivationMap,unordered_map<int,vector<int>> & activationAtomTrackerToMetricMap,unordered_map<int,vector<int>> & deactivationAtomTrackerToMetricMap,vector<int> & metricsWithActivation,unordered_map<int,shared_ptr<Activation>> & newEventActivationMap,unordered_map<int,vector<shared_ptr<Activation>>> & newEventDeactivationMap)354 optional<InvalidConfigReason> handleMetricActivationOnConfigUpdate(
355         const StatsdConfig& config, const int64_t metricId, const int metricIndex,
356         const unordered_map<int64_t, int>& metricToActivationMap,
357         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
358         const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
359         const unordered_map<int, shared_ptr<Activation>>& oldEventActivationMap,
360         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
361         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
362         vector<int>& metricsWithActivation,
363         unordered_map<int, shared_ptr<Activation>>& newEventActivationMap,
364         unordered_map<int, vector<shared_ptr<Activation>>>& newEventDeactivationMap) {
365     // Check if metric has an associated activation.
366     const auto& itr = metricToActivationMap.find(metricId);
367     if (itr == metricToActivationMap.end()) {
368         return nullopt;
369     }
370 
371     int activationIndex = itr->second;
372     const MetricActivation& metricActivation = config.metric_activation(activationIndex);
373 
374     for (int i = 0; i < metricActivation.event_activation_size(); i++) {
375         const int64_t activationMatcherId = metricActivation.event_activation(i).atom_matcher_id();
376 
377         const auto& newActivationIt = newAtomMatchingTrackerMap.find(activationMatcherId);
378         if (newActivationIt == newAtomMatchingTrackerMap.end()) {
379             ALOGE("Atom matcher not found in new config for event activation.");
380             return createInvalidConfigReasonWithMatcher(
381                     INVALID_CONFIG_REASON_METRIC_ACTIVATION_MATCHER_NOT_FOUND_NEW, metricId,
382                     activationMatcherId);
383         }
384         int newActivationMatcherIndex = newActivationIt->second;
385 
386         // Find the old activation struct and copy it over.
387         const auto& oldActivationIt = oldAtomMatchingTrackerMap.find(activationMatcherId);
388         if (oldActivationIt == oldAtomMatchingTrackerMap.end()) {
389             ALOGE("Atom matcher not found in existing config for event activation.");
390             return createInvalidConfigReasonWithMatcher(
391                     INVALID_CONFIG_REASON_METRIC_ACTIVATION_MATCHER_NOT_FOUND_EXISTING, metricId,
392                     activationMatcherId);
393         }
394         int oldActivationMatcherIndex = oldActivationIt->second;
395         const auto& oldEventActivationIt = oldEventActivationMap.find(oldActivationMatcherIndex);
396         if (oldEventActivationIt == oldEventActivationMap.end()) {
397             ALOGE("Could not find existing event activation to update");
398             return createInvalidConfigReasonWithMatcher(
399                     INVALID_CONFIG_REASON_METRIC_ACTIVATION_NOT_FOUND_EXISTING, metricId,
400                     activationMatcherId);
401         }
402         newEventActivationMap.emplace(newActivationMatcherIndex, oldEventActivationIt->second);
403         activationAtomTrackerToMetricMap[newActivationMatcherIndex].push_back(metricIndex);
404 
405         if (metricActivation.event_activation(i).has_deactivation_atom_matcher_id()) {
406             const int64_t deactivationMatcherId =
407                     metricActivation.event_activation(i).deactivation_atom_matcher_id();
408             const auto& newDeactivationIt = newAtomMatchingTrackerMap.find(deactivationMatcherId);
409             if (newDeactivationIt == newAtomMatchingTrackerMap.end()) {
410                 ALOGE("Deactivation atom matcher not found in new config for event activation.");
411                 return createInvalidConfigReasonWithMatcher(
412                         INVALID_CONFIG_REASON_METRIC_DEACTIVATION_MATCHER_NOT_FOUND_NEW, metricId,
413                         deactivationMatcherId);
414             }
415             int newDeactivationMatcherIndex = newDeactivationIt->second;
416             newEventDeactivationMap[newDeactivationMatcherIndex].push_back(
417                     oldEventActivationIt->second);
418             deactivationAtomTrackerToMetricMap[newDeactivationMatcherIndex].push_back(metricIndex);
419         }
420     }
421 
422     metricsWithActivation.push_back(metricIndex);
423     return nullopt;
424 }
425 
createCountMetricProducerAndUpdateMetadata(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseNs,const int64_t currentTimeNs,const CountMetric & metric,const int metricIndex,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<ConditionState> & initialConditionCache,const sp<ConditionWizard> & wizard,const unordered_map<int64_t,int> & stateAtomIdMap,const unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,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)426 optional<sp<MetricProducer>> createCountMetricProducerAndUpdateMetadata(
427         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
428         const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex,
429         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
430         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
431         vector<sp<ConditionTracker>>& allConditionTrackers,
432         const unordered_map<int64_t, int>& conditionTrackerMap,
433         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
434         const unordered_map<int64_t, int>& stateAtomIdMap,
435         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
436         const unordered_map<int64_t, int>& metricToActivationMap,
437         unordered_map<int, vector<int>>& trackerToMetricMap,
438         unordered_map<int, vector<int>>& conditionToMetricMap,
439         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
440         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
441         vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
442     if (!metric.has_id() || !metric.has_what()) {
443         ALOGE("cannot find metric id or \"what\" in CountMetric \"%lld\"", (long long)metric.id());
444         invalidConfigReason =
445                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metric.id());
446         return nullopt;
447     }
448     int trackerIndex;
449     invalidConfigReason = handleMetricWithAtomMatchingTrackers(
450             metric.what(), metric.id(), metricIndex, metric.has_dimensions_in_what(),
451             allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, trackerIndex);
452     if (invalidConfigReason.has_value()) {
453         return nullopt;
454     }
455 
456     int conditionIndex = -1;
457     if (metric.has_condition()) {
458         invalidConfigReason = handleMetricWithConditions(
459                 metric.condition(), metric.id(), metricIndex, conditionTrackerMap, metric.links(),
460                 allConditionTrackers, conditionIndex, conditionToMetricMap);
461         if (invalidConfigReason.has_value()) {
462             return nullopt;
463         }
464     } else {
465         if (metric.links_size() > 0) {
466             ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
467             invalidConfigReason = InvalidConfigReason(
468                     INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION, metric.id());
469             return nullopt;
470         }
471     }
472 
473     std::vector<int> slicedStateAtoms;
474     unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
475     if (metric.slice_by_state_size() > 0) {
476         invalidConfigReason =
477                 handleMetricWithStates(config, metric.id(), metric.slice_by_state(), stateAtomIdMap,
478                                        allStateGroupMaps, slicedStateAtoms, stateGroupMap);
479         if (invalidConfigReason.has_value()) {
480             return nullopt;
481         }
482     } else {
483         if (metric.state_link_size() > 0) {
484             ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
485             invalidConfigReason = InvalidConfigReason(
486                     INVALID_CONFIG_REASON_METRIC_STATELINK_NO_STATE, metric.id());
487             return nullopt;
488         }
489     }
490 
491     // Check that all metric state links are a subset of dimensions_in_what fields.
492     std::vector<Matcher> dimensionsInWhat;
493     translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
494     for (const auto& stateLink : metric.state_link()) {
495         invalidConfigReason = handleMetricWithStateLink(metric.id(), stateLink.fields_in_what(),
496                                                         dimensionsInWhat);
497         if (invalidConfigReason.has_value()) {
498             ALOGW("CountMetric's MetricStateLinks must be a subset of dimensions in what");
499             return nullopt;
500         }
501     }
502 
503     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
504     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
505     invalidConfigReason = handleMetricActivation(
506             config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
507             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
508             metricsWithActivation, eventActivationMap, eventDeactivationMap);
509     if (invalidConfigReason.has_value()) {
510         return nullopt;
511     }
512 
513     uint64_t metricHash;
514     invalidConfigReason =
515             getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash);
516     if (invalidConfigReason.has_value()) {
517         return nullopt;
518     }
519 
520     if (metric.has_threshold() &&
521         (metric.threshold().value_comparison_case() == UploadThreshold::kLtFloat ||
522          metric.threshold().value_comparison_case() == UploadThreshold::kGtFloat)) {
523         ALOGW("Count metric incorrect upload threshold type or no type used");
524         invalidConfigReason =
525                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_BAD_THRESHOLD, metric.id());
526         return nullopt;
527     }
528 
529     sp<MetricProducer> metricProducer =
530             new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
531                                     metricHash, timeBaseNs, currentTimeNs, eventActivationMap,
532                                     eventDeactivationMap, slicedStateAtoms, stateGroupMap);
533 
534     SamplingInfo samplingInfo;
535     if (metric.has_dimensional_sampling_info()) {
536         invalidConfigReason = handleMetricWithSampling(
537                 metric.id(), metric.dimensional_sampling_info(), dimensionsInWhat, samplingInfo);
538         if (invalidConfigReason.has_value()) {
539             return nullopt;
540         }
541         metricProducer->setSamplingInfo(samplingInfo);
542     }
543 
544     return metricProducer;
545 }
546 
createDurationMetricProducerAndUpdateMetadata(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseNs,const int64_t currentTimeNs,const DurationMetric & metric,const int metricIndex,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<ConditionState> & initialConditionCache,const sp<ConditionWizard> & wizard,const unordered_map<int64_t,int> & stateAtomIdMap,const unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,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)547 optional<sp<MetricProducer>> createDurationMetricProducerAndUpdateMetadata(
548         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
549         const int64_t currentTimeNs, const DurationMetric& metric, const int metricIndex,
550         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
551         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
552         vector<sp<ConditionTracker>>& allConditionTrackers,
553         const unordered_map<int64_t, int>& conditionTrackerMap,
554         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
555         const unordered_map<int64_t, int>& stateAtomIdMap,
556         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
557         const unordered_map<int64_t, int>& metricToActivationMap,
558         unordered_map<int, vector<int>>& trackerToMetricMap,
559         unordered_map<int, vector<int>>& conditionToMetricMap,
560         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
561         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
562         vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
563     if (!metric.has_id() || !metric.has_what()) {
564         ALOGE("cannot find metric id or \"what\" in DurationMetric \"%lld\"",
565               (long long)metric.id());
566         invalidConfigReason =
567                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metric.id());
568         return nullopt;
569     }
570     const auto& what_it = conditionTrackerMap.find(metric.what());
571     if (what_it == conditionTrackerMap.end()) {
572         ALOGE("DurationMetric's \"what\" is not present in the condition trackers");
573         invalidConfigReason = createInvalidConfigReasonWithPredicate(
574                 INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_FOUND, metric.id(), metric.what());
575         return nullopt;
576     }
577 
578     const int whatIndex = what_it->second;
579     const Predicate& durationWhat = config.predicate(whatIndex);
580     if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
581         ALOGE("DurationMetric's \"what\" must be a simple condition");
582         invalidConfigReason = createInvalidConfigReasonWithPredicate(
583                 INVALID_CONFIG_REASON_DURATION_METRIC_WHAT_NOT_SIMPLE, metric.id(), metric.what());
584         return nullopt;
585     }
586 
587     const SimplePredicate& simplePredicate = durationWhat.simple_predicate();
588     bool nesting = simplePredicate.count_nesting();
589 
590     int startIndex = -1, stopIndex = -1, stopAllIndex = -1;
591     if (!simplePredicate.has_start()) {
592         ALOGE("Duration metrics must specify a valid start event matcher");
593         invalidConfigReason = createInvalidConfigReasonWithPredicate(
594                 INVALID_CONFIG_REASON_DURATION_METRIC_MISSING_START, metric.id(), metric.what());
595         return nullopt;
596     }
597     invalidConfigReason = handleMetricWithAtomMatchingTrackers(
598             simplePredicate.start(), metric.id(), metricIndex, metric.has_dimensions_in_what(),
599             allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, startIndex);
600     if (invalidConfigReason.has_value()) {
601         return nullopt;
602     }
603 
604     if (simplePredicate.has_stop()) {
605         invalidConfigReason = handleMetricWithAtomMatchingTrackers(
606                 simplePredicate.stop(), metric.id(), metricIndex, metric.has_dimensions_in_what(),
607                 allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, stopIndex);
608         if (invalidConfigReason.has_value()) {
609             return nullopt;
610         }
611     }
612 
613     if (simplePredicate.has_stop_all()) {
614         invalidConfigReason = handleMetricWithAtomMatchingTrackers(
615                 simplePredicate.stop_all(), metric.id(), metricIndex,
616                 metric.has_dimensions_in_what(), allAtomMatchingTrackers, atomMatchingTrackerMap,
617                 trackerToMetricMap, stopAllIndex);
618         if (invalidConfigReason.has_value()) {
619             return nullopt;
620         }
621     }
622 
623     FieldMatcher internalDimensions = simplePredicate.dimensions();
624 
625     int conditionIndex = -1;
626     if (metric.has_condition()) {
627         invalidConfigReason = handleMetricWithConditions(
628                 metric.condition(), metric.id(), metricIndex, conditionTrackerMap, metric.links(),
629                 allConditionTrackers, conditionIndex, conditionToMetricMap);
630         if (invalidConfigReason.has_value()) {
631             return nullopt;
632         }
633     } else if (metric.links_size() > 0) {
634         ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
635         invalidConfigReason = InvalidConfigReason(
636                 INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION, metric.id());
637         return nullopt;
638     }
639 
640     std::vector<int> slicedStateAtoms;
641     unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
642     if (metric.slice_by_state_size() > 0) {
643         if (metric.aggregation_type() == DurationMetric::MAX_SPARSE) {
644             ALOGE("DurationMetric with aggregation type MAX_SPARSE cannot be sliced by state");
645             invalidConfigReason = InvalidConfigReason(
646                     INVALID_CONFIG_REASON_DURATION_METRIC_MAX_SPARSE_HAS_SLICE_BY_STATE,
647                     metric.id());
648             return nullopt;
649         }
650         invalidConfigReason =
651                 handleMetricWithStates(config, metric.id(), metric.slice_by_state(), stateAtomIdMap,
652                                        allStateGroupMaps, slicedStateAtoms, stateGroupMap);
653         if (invalidConfigReason.has_value()) {
654             return nullopt;
655         }
656     } else if (metric.state_link_size() > 0) {
657         ALOGW("DurationMetric has a MetricStateLink but doesn't have a sliced state");
658         invalidConfigReason =
659                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_STATELINK_NO_STATE, metric.id());
660         return nullopt;
661     }
662 
663     // Check that all metric state links are a subset of dimensions_in_what fields.
664     std::vector<Matcher> dimensionsInWhat;
665     translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
666     for (const auto& stateLink : metric.state_link()) {
667         invalidConfigReason = handleMetricWithStateLink(metric.id(), stateLink.fields_in_what(),
668                                                         dimensionsInWhat);
669         if (invalidConfigReason.has_value()) {
670             ALOGW("DurationMetric's MetricStateLinks must be a subset of dimensions in what");
671             return nullopt;
672         }
673     }
674 
675     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
676     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
677     invalidConfigReason = handleMetricActivation(
678             config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
679             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
680             metricsWithActivation, eventActivationMap, eventDeactivationMap);
681     if (invalidConfigReason.has_value()) {
682         return nullopt;
683     }
684 
685     uint64_t metricHash;
686     invalidConfigReason =
687             getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash);
688     if (invalidConfigReason.has_value()) {
689         return nullopt;
690     }
691 
692     if (metric.has_threshold()) {
693         switch (metric.threshold().value_comparison_case()) {
694             case UploadThreshold::kLtInt:
695             case UploadThreshold::kGtInt:
696             case UploadThreshold::kLteInt:
697             case UploadThreshold::kGteInt:
698                 break;
699             default:
700                 ALOGE("Duration metric incorrect upload threshold type or no type used");
701                 invalidConfigReason = InvalidConfigReason(
702                         INVALID_CONFIG_REASON_METRIC_BAD_THRESHOLD, metric.id());
703                 return nullopt;
704         }
705     }
706 
707     sp<MetricProducer> metricProducer = new DurationMetricProducer(
708             key, metric, conditionIndex, initialConditionCache, whatIndex, startIndex, stopIndex,
709             stopAllIndex, nesting, wizard, metricHash, internalDimensions, timeBaseNs,
710             currentTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
711             stateGroupMap);
712     if (!metricProducer->isValid()) {
713         // TODO: Remove once invalidConfigReason is added to the DurationMetricProducer constructor
714         invalidConfigReason = InvalidConfigReason(
715                 INVALID_CONFIG_REASON_DURATION_METRIC_PRODUCER_INVALID, metric.id());
716         return nullopt;
717     }
718 
719     SamplingInfo samplingInfo;
720     if (metric.has_dimensional_sampling_info()) {
721         invalidConfigReason = handleMetricWithSampling(
722                 metric.id(), metric.dimensional_sampling_info(), dimensionsInWhat, samplingInfo);
723         if (invalidConfigReason.has_value()) {
724             return nullopt;
725         }
726         metricProducer->setSamplingInfo(samplingInfo);
727     }
728 
729     return metricProducer;
730 }
731 
createEventMetricProducerAndUpdateMetadata(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseNs,const EventMetric & metric,const int metricIndex,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<ConditionState> & initialConditionCache,const sp<ConditionWizard> & wizard,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)732 optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata(
733         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
734         const EventMetric& metric, const int metricIndex,
735         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
736         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
737         vector<sp<ConditionTracker>>& allConditionTrackers,
738         const unordered_map<int64_t, int>& conditionTrackerMap,
739         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
740         const unordered_map<int64_t, int>& metricToActivationMap,
741         unordered_map<int, vector<int>>& trackerToMetricMap,
742         unordered_map<int, vector<int>>& conditionToMetricMap,
743         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
744         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
745         vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
746     if (!metric.has_id() || !metric.has_what()) {
747         ALOGE("cannot find the metric name or what in config");
748         invalidConfigReason =
749                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metric.id());
750         return nullopt;
751     }
752     int trackerIndex;
753     invalidConfigReason = handleMetricWithAtomMatchingTrackers(
754             metric.what(), metric.id(), metricIndex, false, allAtomMatchingTrackers,
755             atomMatchingTrackerMap, trackerToMetricMap, trackerIndex);
756     if (invalidConfigReason.has_value()) {
757         return nullopt;
758     }
759 
760     int conditionIndex = -1;
761     if (metric.has_condition()) {
762         invalidConfigReason = handleMetricWithConditions(
763                 metric.condition(), metric.id(), metricIndex, conditionTrackerMap, metric.links(),
764                 allConditionTrackers, conditionIndex, conditionToMetricMap);
765         if (invalidConfigReason.has_value()) {
766             return nullopt;
767         }
768     } else {
769         if (metric.links_size() > 0) {
770             ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
771             invalidConfigReason = InvalidConfigReason(
772                     INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION, metric.id());
773             return nullopt;
774         }
775     }
776 
777     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
778     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
779     invalidConfigReason = handleMetricActivation(
780             config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
781             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
782             metricsWithActivation, eventActivationMap, eventDeactivationMap);
783     if (invalidConfigReason.has_value()) return nullptr;
784 
785     uint64_t metricHash;
786     invalidConfigReason =
787             getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash);
788     if (invalidConfigReason.has_value()) {
789         return nullopt;
790     }
791 
792     if (config.has_restricted_metrics_delegate_package_name()) {
793         return {new RestrictedEventMetricProducer(
794                 key, metric, conditionIndex, initialConditionCache, wizard, metricHash, timeBaseNs,
795                 eventActivationMap, eventDeactivationMap)};
796     }
797     return {new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
798                                     metricHash, timeBaseNs, eventActivationMap,
799                                     eventDeactivationMap)};
800 }
801 
createNumericValueMetricProducerAndUpdateMetadata(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseNs,const int64_t currentTimeNs,const sp<StatsPullerManager> & pullerManager,const ValueMetric & metric,const int metricIndex,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<ConditionState> & initialConditionCache,const sp<ConditionWizard> & wizard,const sp<EventMatcherWizard> & matcherWizard,const unordered_map<int64_t,int> & stateAtomIdMap,const unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,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)802 optional<sp<MetricProducer>> createNumericValueMetricProducerAndUpdateMetadata(
803         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
804         const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
805         const ValueMetric& metric, const int metricIndex,
806         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
807         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
808         vector<sp<ConditionTracker>>& allConditionTrackers,
809         const unordered_map<int64_t, int>& conditionTrackerMap,
810         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
811         const sp<EventMatcherWizard>& matcherWizard,
812         const unordered_map<int64_t, int>& stateAtomIdMap,
813         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
814         const unordered_map<int64_t, int>& metricToActivationMap,
815         unordered_map<int, vector<int>>& trackerToMetricMap,
816         unordered_map<int, vector<int>>& conditionToMetricMap,
817         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
818         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
819         vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
820     if (!metric.has_id() || !metric.has_what()) {
821         ALOGE("cannot find metric id or \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
822         invalidConfigReason =
823                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metric.id());
824         return nullopt;
825     }
826     if (!metric.has_value_field()) {
827         ALOGE("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
828         invalidConfigReason = InvalidConfigReason(
829                 INVALID_CONFIG_REASON_VALUE_METRIC_MISSING_VALUE_FIELD, metric.id());
830         return nullopt;
831     }
832     if (HasPositionALL(metric.value_field())) {
833         ALOGE("value field with position ALL is not supported. ValueMetric \"%lld\"",
834               (long long)metric.id());
835         invalidConfigReason = InvalidConfigReason(
836                 INVALID_CONFIG_REASON_VALUE_METRIC_VALUE_FIELD_HAS_POSITION_ALL, metric.id());
837         return nullopt;
838     }
839     std::vector<Matcher> fieldMatchers;
840     translateFieldMatcher(metric.value_field(), &fieldMatchers);
841     if (fieldMatchers.size() < 1) {
842         ALOGE("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
843         invalidConfigReason = InvalidConfigReason(
844                 INVALID_CONFIG_REASON_VALUE_METRIC_HAS_INCORRECT_VALUE_FIELD, metric.id());
845         return nullopt;
846     }
847 
848     int trackerIndex;
849     invalidConfigReason = handleMetricWithAtomMatchingTrackers(
850             metric.what(), metric.id(), metricIndex,
851             /*enforceOneAtom=*/true, allAtomMatchingTrackers, atomMatchingTrackerMap,
852             trackerToMetricMap, trackerIndex);
853     if (invalidConfigReason.has_value()) {
854         return nullopt;
855     }
856 
857     sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
858     int atomTagId = *(atomMatcher->getAtomIds().begin());
859     int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
860 
861     int conditionIndex = -1;
862     if (metric.has_condition()) {
863         invalidConfigReason = handleMetricWithConditions(
864                 metric.condition(), metric.id(), metricIndex, conditionTrackerMap, metric.links(),
865                 allConditionTrackers, conditionIndex, conditionToMetricMap);
866         if (invalidConfigReason.has_value()) {
867             return nullopt;
868         }
869     } else if (metric.links_size() > 0) {
870         ALOGE("metrics has a MetricConditionLink but doesn't have a condition");
871         invalidConfigReason = InvalidConfigReason(
872                 INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION, metric.id());
873         return nullopt;
874     }
875 
876     std::vector<int> slicedStateAtoms;
877     unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
878     if (metric.slice_by_state_size() > 0) {
879         invalidConfigReason =
880                 handleMetricWithStates(config, metric.id(), metric.slice_by_state(), stateAtomIdMap,
881                                        allStateGroupMaps, slicedStateAtoms, stateGroupMap);
882         if (invalidConfigReason.has_value()) {
883             return nullopt;
884         }
885     } else if (metric.state_link_size() > 0) {
886         ALOGE("ValueMetric has a MetricStateLink but doesn't have a sliced state");
887         invalidConfigReason =
888                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_STATELINK_NO_STATE, metric.id());
889         return nullopt;
890     }
891 
892     // Check that all metric state links are a subset of dimensions_in_what fields.
893     std::vector<Matcher> dimensionsInWhat;
894     translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
895     for (const auto& stateLink : metric.state_link()) {
896         invalidConfigReason = handleMetricWithStateLink(metric.id(), stateLink.fields_in_what(),
897                                                         dimensionsInWhat);
898         if (invalidConfigReason.has_value()) {
899             ALOGW("ValueMetric's MetricStateLinks must be a subset of the dimensions in what");
900             return nullopt;
901         }
902     }
903 
904     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
905     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
906     invalidConfigReason = handleMetricActivation(
907             config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
908             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
909             metricsWithActivation, eventActivationMap, eventDeactivationMap);
910     if (invalidConfigReason.has_value()) {
911         return nullopt;
912     }
913 
914     uint64_t metricHash;
915     invalidConfigReason =
916             getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash);
917     if (invalidConfigReason.has_value()) {
918         return nullopt;
919     }
920 
921     const TimeUnit bucketSizeTimeUnit =
922             metric.bucket() == TIME_UNIT_UNSPECIFIED ? ONE_HOUR : metric.bucket();
923     const int64_t bucketSizeNs =
924             MillisToNano(TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), bucketSizeTimeUnit));
925 
926     const bool containsAnyPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
927     const bool shouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
928 
929     const auto [dimensionSoftLimit, dimensionHardLimit] =
930             StatsdStats::getAtomDimensionKeySizeLimits(pullTagId);
931 
932     // get the condition_correction_threshold_nanos value
933     const optional<int64_t> conditionCorrectionThresholdNs =
934             metric.has_condition_correction_threshold_nanos()
935                     ? optional<int64_t>(metric.condition_correction_threshold_nanos())
936                     : nullopt;
937 
938     sp<MetricProducer> metricProducer = new NumericValueMetricProducer(
939             key, metric, metricHash, {pullTagId, pullerManager},
940             {timeBaseNs, currentTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
941              conditionCorrectionThresholdNs, getAppUpgradeBucketSplit(metric)},
942             {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions, trackerIndex,
943              matcherWizard, metric.dimensions_in_what(), fieldMatchers},
944             {conditionIndex, metric.links(), initialConditionCache, wizard},
945             {metric.state_link(), slicedStateAtoms, stateGroupMap},
946             {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit});
947 
948     SamplingInfo samplingInfo;
949     if (metric.has_dimensional_sampling_info()) {
950         invalidConfigReason = handleMetricWithSampling(
951                 metric.id(), metric.dimensional_sampling_info(), dimensionsInWhat, samplingInfo);
952         if (invalidConfigReason.has_value()) {
953             return nullopt;
954         }
955         metricProducer->setSamplingInfo(samplingInfo);
956     }
957 
958     return metricProducer;
959 }
960 
createKllMetricProducerAndUpdateMetadata(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseNs,const int64_t currentTimeNs,const sp<StatsPullerManager> & pullerManager,const KllMetric & metric,const int metricIndex,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<ConditionState> & initialConditionCache,const sp<ConditionWizard> & wizard,const sp<EventMatcherWizard> & matcherWizard,const unordered_map<int64_t,int> & stateAtomIdMap,const unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,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)961 optional<sp<MetricProducer>> createKllMetricProducerAndUpdateMetadata(
962         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
963         const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
964         const KllMetric& metric, const int metricIndex,
965         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
966         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
967         vector<sp<ConditionTracker>>& allConditionTrackers,
968         const unordered_map<int64_t, int>& conditionTrackerMap,
969         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
970         const sp<EventMatcherWizard>& matcherWizard,
971         const unordered_map<int64_t, int>& stateAtomIdMap,
972         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
973         const unordered_map<int64_t, int>& metricToActivationMap,
974         unordered_map<int, vector<int>>& trackerToMetricMap,
975         unordered_map<int, vector<int>>& conditionToMetricMap,
976         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
977         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
978         vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
979     if (!metric.has_id() || !metric.has_what()) {
980         ALOGE("cannot find metric id or \"what\" in KllMetric \"%lld\"", (long long)metric.id());
981         invalidConfigReason =
982                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metric.id());
983         return nullopt;
984     }
985     if (!metric.has_kll_field()) {
986         ALOGE("cannot find \"kll_field\" in KllMetric \"%lld\"", (long long)metric.id());
987         invalidConfigReason = InvalidConfigReason(
988                 INVALID_CONFIG_REASON_KLL_METRIC_MISSING_KLL_FIELD, metric.id());
989         return nullopt;
990     }
991     if (HasPositionALL(metric.kll_field())) {
992         ALOGE("kll field with position ALL is not supported. KllMetric \"%lld\"",
993               (long long)metric.id());
994         invalidConfigReason = InvalidConfigReason(
995                 INVALID_CONFIG_REASON_KLL_METRIC_KLL_FIELD_HAS_POSITION_ALL, metric.id());
996         return nullopt;
997     }
998     std::vector<Matcher> fieldMatchers;
999     translateFieldMatcher(metric.kll_field(), &fieldMatchers);
1000     if (fieldMatchers.empty()) {
1001         ALOGE("incorrect \"kll_field\" in KllMetric \"%lld\"", (long long)metric.id());
1002         invalidConfigReason = InvalidConfigReason(
1003                 INVALID_CONFIG_REASON_KLL_METRIC_HAS_INCORRECT_KLL_FIELD, metric.id());
1004         return nullopt;
1005     }
1006 
1007     int trackerIndex;
1008     invalidConfigReason = handleMetricWithAtomMatchingTrackers(
1009             metric.what(), metric.id(), metricIndex,
1010             /*enforceOneAtom=*/true, allAtomMatchingTrackers, atomMatchingTrackerMap,
1011             trackerToMetricMap, trackerIndex);
1012     if (invalidConfigReason.has_value()) {
1013         return nullopt;
1014     }
1015 
1016     int conditionIndex = -1;
1017     if (metric.has_condition()) {
1018         invalidConfigReason = handleMetricWithConditions(
1019                 metric.condition(), metric.id(), metricIndex, conditionTrackerMap, metric.links(),
1020                 allConditionTrackers, conditionIndex, conditionToMetricMap);
1021         if (invalidConfigReason.has_value()) {
1022             return nullopt;
1023         }
1024     } else if (metric.links_size() > 0) {
1025         ALOGE("metrics has a MetricConditionLink but doesn't have a condition");
1026         invalidConfigReason = InvalidConfigReason(
1027                 INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION, metric.id());
1028         return nullopt;
1029     }
1030 
1031     std::vector<int> slicedStateAtoms;
1032     unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
1033     if (metric.slice_by_state_size() > 0) {
1034         invalidConfigReason =
1035                 handleMetricWithStates(config, metric.id(), metric.slice_by_state(), stateAtomIdMap,
1036                                        allStateGroupMaps, slicedStateAtoms, stateGroupMap);
1037         if (invalidConfigReason.has_value()) {
1038             return nullopt;
1039         }
1040     } else if (metric.state_link_size() > 0) {
1041         ALOGE("KllMetric has a MetricStateLink but doesn't have a sliced state");
1042         invalidConfigReason =
1043                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_STATELINK_NO_STATE, metric.id());
1044         return nullopt;
1045     }
1046 
1047     // Check that all metric state links are a subset of dimensions_in_what fields.
1048     std::vector<Matcher> dimensionsInWhat;
1049     translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
1050     for (const auto& stateLink : metric.state_link()) {
1051         invalidConfigReason = handleMetricWithStateLink(metric.id(), stateLink.fields_in_what(),
1052                                                         dimensionsInWhat);
1053         if (invalidConfigReason.has_value()) {
1054             ALOGW("KllMetric's MetricStateLinks must be a subset of the dimensions in what");
1055             return nullopt;
1056         }
1057     }
1058 
1059     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
1060     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
1061     invalidConfigReason = handleMetricActivation(
1062             config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
1063             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1064             metricsWithActivation, eventActivationMap, eventDeactivationMap);
1065     if (invalidConfigReason.has_value()) {
1066         return nullopt;
1067     }
1068 
1069     uint64_t metricHash;
1070     invalidConfigReason =
1071             getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash);
1072     if (invalidConfigReason.has_value()) {
1073         return nullopt;
1074     }
1075 
1076     const TimeUnit bucketSizeTimeUnit =
1077             metric.bucket() == TIME_UNIT_UNSPECIFIED ? ONE_HOUR : metric.bucket();
1078     const int64_t bucketSizeNs =
1079             MillisToNano(TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), bucketSizeTimeUnit));
1080 
1081     const bool containsAnyPositionInDimensionsInWhat = HasPositionANY(metric.dimensions_in_what());
1082     const bool shouldUseNestedDimensions = ShouldUseNestedDimensions(metric.dimensions_in_what());
1083 
1084     sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
1085     const int atomTagId = *(atomMatcher->getAtomIds().begin());
1086     const auto [dimensionSoftLimit, dimensionHardLimit] =
1087             StatsdStats::getAtomDimensionKeySizeLimits(atomTagId);
1088 
1089     sp<MetricProducer> metricProducer = new KllMetricProducer(
1090             key, metric, metricHash, {/*pullTagId=*/-1, pullerManager},
1091             {timeBaseNs, currentTimeNs, bucketSizeNs, metric.min_bucket_size_nanos(),
1092              /*conditionCorrectionThresholdNs=*/nullopt, getAppUpgradeBucketSplit(metric)},
1093             {containsAnyPositionInDimensionsInWhat, shouldUseNestedDimensions, trackerIndex,
1094              matcherWizard, metric.dimensions_in_what(), fieldMatchers},
1095             {conditionIndex, metric.links(), initialConditionCache, wizard},
1096             {metric.state_link(), slicedStateAtoms, stateGroupMap},
1097             {eventActivationMap, eventDeactivationMap}, {dimensionSoftLimit, dimensionHardLimit});
1098 
1099     SamplingInfo samplingInfo;
1100     if (metric.has_dimensional_sampling_info()) {
1101         invalidConfigReason = handleMetricWithSampling(
1102                 metric.id(), metric.dimensional_sampling_info(), dimensionsInWhat, samplingInfo);
1103         if (invalidConfigReason.has_value()) {
1104             return nullopt;
1105         }
1106         metricProducer->setSamplingInfo(samplingInfo);
1107     }
1108 
1109     return metricProducer;
1110 }
1111 
createGaugeMetricProducerAndUpdateMetadata(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseNs,const int64_t currentTimeNs,const sp<StatsPullerManager> & pullerManager,const GaugeMetric & metric,const int metricIndex,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<ConditionState> & initialConditionCache,const sp<ConditionWizard> & wizard,const sp<EventMatcherWizard> & matcherWizard,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)1112 optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata(
1113         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
1114         const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
1115         const GaugeMetric& metric, const int metricIndex,
1116         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
1117         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
1118         vector<sp<ConditionTracker>>& allConditionTrackers,
1119         const unordered_map<int64_t, int>& conditionTrackerMap,
1120         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
1121         const sp<EventMatcherWizard>& matcherWizard,
1122         const unordered_map<int64_t, int>& metricToActivationMap,
1123         unordered_map<int, vector<int>>& trackerToMetricMap,
1124         unordered_map<int, vector<int>>& conditionToMetricMap,
1125         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
1126         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
1127         vector<int>& metricsWithActivation, optional<InvalidConfigReason>& invalidConfigReason) {
1128     if (!metric.has_id() || !metric.has_what()) {
1129         ALOGE("cannot find metric id or \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
1130         invalidConfigReason =
1131                 InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_MISSING_ID_OR_WHAT, metric.id());
1132         return nullopt;
1133     }
1134 
1135     if ((!metric.gauge_fields_filter().has_include_all() ||
1136          (metric.gauge_fields_filter().include_all() == false)) &&
1137         !hasLeafNode(metric.gauge_fields_filter().fields())) {
1138         ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
1139         invalidConfigReason = InvalidConfigReason(
1140                 INVALID_CONFIG_REASON_GAUGE_METRIC_INCORRECT_FIELD_FILTER, metric.id());
1141         return nullopt;
1142     }
1143     if ((metric.gauge_fields_filter().has_include_all() &&
1144          metric.gauge_fields_filter().include_all() == true) &&
1145         hasLeafNode(metric.gauge_fields_filter().fields())) {
1146         ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
1147         invalidConfigReason = InvalidConfigReason(
1148                 INVALID_CONFIG_REASON_GAUGE_METRIC_INCORRECT_FIELD_FILTER, metric.id());
1149         return nullopt;
1150     }
1151 
1152     int trackerIndex;
1153     invalidConfigReason = handleMetricWithAtomMatchingTrackers(
1154             metric.what(), metric.id(), metricIndex, true, allAtomMatchingTrackers,
1155             atomMatchingTrackerMap, trackerToMetricMap, trackerIndex);
1156     if (invalidConfigReason.has_value()) {
1157         return nullopt;
1158     }
1159 
1160     sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
1161     int atomTagId = *(atomMatcher->getAtomIds().begin());
1162     int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
1163 
1164     int triggerTrackerIndex;
1165     int triggerAtomId = -1;
1166     if (metric.has_trigger_event()) {
1167         if (pullTagId == -1) {
1168             ALOGW("Pull atom not specified for trigger");
1169             invalidConfigReason = InvalidConfigReason(
1170                     INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_PULL_ATOM, metric.id());
1171             return nullopt;
1172         }
1173         // trigger_event should be used with FIRST_N_SAMPLES
1174         if (metric.sampling_type() != GaugeMetric::FIRST_N_SAMPLES) {
1175             ALOGW("Gauge Metric with trigger event must have sampling type FIRST_N_SAMPLES");
1176             invalidConfigReason = InvalidConfigReason(
1177                     INVALID_CONFIG_REASON_GAUGE_METRIC_TRIGGER_NO_FIRST_N_SAMPLES, metric.id());
1178             return nullopt;
1179         }
1180         invalidConfigReason = handleMetricWithAtomMatchingTrackers(
1181                 metric.trigger_event(), metric.id(), metricIndex,
1182                 /*enforceOneAtom=*/true, allAtomMatchingTrackers, atomMatchingTrackerMap,
1183                 trackerToMetricMap, triggerTrackerIndex);
1184         if (invalidConfigReason.has_value()) {
1185             return nullopt;
1186         }
1187         sp<AtomMatchingTracker> triggerAtomMatcher =
1188                 allAtomMatchingTrackers.at(triggerTrackerIndex);
1189         triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
1190     }
1191 
1192     int conditionIndex = -1;
1193     if (metric.has_condition()) {
1194         invalidConfigReason = handleMetricWithConditions(
1195                 metric.condition(), metric.id(), metricIndex, conditionTrackerMap, metric.links(),
1196                 allConditionTrackers, conditionIndex, conditionToMetricMap);
1197         if (invalidConfigReason.has_value()) {
1198             return nullopt;
1199         }
1200     } else {
1201         if (metric.links_size() > 0) {
1202             ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
1203             invalidConfigReason = InvalidConfigReason(
1204                     INVALID_CONFIG_REASON_METRIC_CONDITIONLINK_NO_CONDITION, metric.id());
1205             return nullopt;
1206         }
1207     }
1208 
1209     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
1210     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
1211     invalidConfigReason = handleMetricActivation(
1212             config, metric.id(), metricIndex, metricToActivationMap, atomMatchingTrackerMap,
1213             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1214             metricsWithActivation, eventActivationMap, eventDeactivationMap);
1215     if (invalidConfigReason.has_value()) {
1216         return nullopt;
1217     }
1218 
1219     uint64_t metricHash;
1220     invalidConfigReason =
1221             getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash);
1222     if (invalidConfigReason.has_value()) {
1223         return nullopt;
1224     }
1225 
1226     const auto [dimensionSoftLimit, dimensionHardLimit] =
1227             StatsdStats::getAtomDimensionKeySizeLimits(pullTagId);
1228 
1229     sp<MetricProducer> metricProducer = new GaugeMetricProducer(
1230             key, metric, conditionIndex, initialConditionCache, wizard, metricHash, trackerIndex,
1231             matcherWizard, pullTagId, triggerAtomId, atomTagId, timeBaseNs, currentTimeNs,
1232             pullerManager, eventActivationMap, eventDeactivationMap, dimensionSoftLimit,
1233             dimensionHardLimit);
1234 
1235     SamplingInfo samplingInfo;
1236     std::vector<Matcher> dimensionsInWhat;
1237     translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
1238     if (metric.has_dimensional_sampling_info()) {
1239         invalidConfigReason = handleMetricWithSampling(
1240                 metric.id(), metric.dimensional_sampling_info(), dimensionsInWhat, samplingInfo);
1241         if (invalidConfigReason.has_value()) {
1242             return nullopt;
1243         }
1244         metricProducer->setSamplingInfo(samplingInfo);
1245     }
1246 
1247     return metricProducer;
1248 }
1249 
createAnomalyTracker(const Alert & alert,const sp<AlarmMonitor> & anomalyAlarmMonitor,const UpdateStatus & updateStatus,const int64_t currentTimeNs,const unordered_map<int64_t,int> & metricProducerMap,vector<sp<MetricProducer>> & allMetricProducers,optional<InvalidConfigReason> & invalidConfigReason)1250 optional<sp<AnomalyTracker>> createAnomalyTracker(
1251         const Alert& alert, const sp<AlarmMonitor>& anomalyAlarmMonitor,
1252         const UpdateStatus& updateStatus, const int64_t currentTimeNs,
1253         const unordered_map<int64_t, int>& metricProducerMap,
1254         vector<sp<MetricProducer>>& allMetricProducers,
1255         optional<InvalidConfigReason>& invalidConfigReason) {
1256     const auto& itr = metricProducerMap.find(alert.metric_id());
1257     if (itr == metricProducerMap.end()) {
1258         ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
1259               (long long)alert.metric_id());
1260         invalidConfigReason = createInvalidConfigReasonWithAlert(
1261                 INVALID_CONFIG_REASON_ALERT_METRIC_NOT_FOUND, alert.metric_id(), alert.id());
1262         return nullopt;
1263     }
1264     if (!alert.has_trigger_if_sum_gt()) {
1265         ALOGW("invalid alert: missing threshold");
1266         invalidConfigReason = createInvalidConfigReasonWithAlert(
1267                 INVALID_CONFIG_REASON_ALERT_THRESHOLD_MISSING, alert.id());
1268         return nullopt;
1269     }
1270     if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
1271         ALOGW("invalid alert: threshold=%f num_buckets= %d", alert.trigger_if_sum_gt(),
1272               alert.num_buckets());
1273         invalidConfigReason = createInvalidConfigReasonWithAlert(
1274                 INVALID_CONFIG_REASON_ALERT_INVALID_TRIGGER_OR_NUM_BUCKETS, alert.id());
1275         return nullopt;
1276     }
1277     const int metricIndex = itr->second;
1278     sp<MetricProducer> metric = allMetricProducers[metricIndex];
1279     sp<AnomalyTracker> anomalyTracker =
1280             metric->addAnomalyTracker(alert, anomalyAlarmMonitor, updateStatus, currentTimeNs);
1281     if (anomalyTracker == nullptr) {
1282         // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
1283         invalidConfigReason = createInvalidConfigReasonWithAlert(
1284                 INVALID_CONFIG_REASON_ALERT_CANNOT_ADD_ANOMALY, alert.metric_id(), alert.id());
1285         return nullopt;
1286     }
1287     return {anomalyTracker};
1288 }
1289 
initAtomMatchingTrackers(const StatsdConfig & config,const sp<UidMap> & uidMap,unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,unordered_map<int,vector<int>> & allTagIdsToMatchersMap)1290 optional<InvalidConfigReason> initAtomMatchingTrackers(
1291         const StatsdConfig& config, const sp<UidMap>& uidMap,
1292         unordered_map<int64_t, int>& atomMatchingTrackerMap,
1293         vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
1294         unordered_map<int, vector<int>>& allTagIdsToMatchersMap) {
1295     vector<AtomMatcher> matcherConfigs;
1296     const int atomMatcherCount = config.atom_matcher_size();
1297     matcherConfigs.reserve(atomMatcherCount);
1298     allAtomMatchingTrackers.reserve(atomMatcherCount);
1299     optional<InvalidConfigReason> invalidConfigReason;
1300 
1301     for (int i = 0; i < atomMatcherCount; i++) {
1302         const AtomMatcher& logMatcher = config.atom_matcher(i);
1303         sp<AtomMatchingTracker> tracker =
1304                 createAtomMatchingTracker(logMatcher, i, uidMap, invalidConfigReason);
1305         if (tracker == nullptr) {
1306             return invalidConfigReason;
1307         }
1308         allAtomMatchingTrackers.push_back(tracker);
1309         if (atomMatchingTrackerMap.find(logMatcher.id()) != atomMatchingTrackerMap.end()) {
1310             ALOGE("Duplicate AtomMatcher found!");
1311             return createInvalidConfigReasonWithMatcher(INVALID_CONFIG_REASON_MATCHER_DUPLICATE,
1312                                                         logMatcher.id());
1313         }
1314         atomMatchingTrackerMap[logMatcher.id()] = i;
1315         matcherConfigs.push_back(logMatcher);
1316     }
1317 
1318     vector<bool> stackTracker2(allAtomMatchingTrackers.size(), false);
1319     for (size_t matcherIndex = 0; matcherIndex < allAtomMatchingTrackers.size(); matcherIndex++) {
1320         auto& matcher = allAtomMatchingTrackers[matcherIndex];
1321         invalidConfigReason = matcher->init(matcherConfigs, allAtomMatchingTrackers,
1322                                             atomMatchingTrackerMap, stackTracker2);
1323         if (invalidConfigReason.has_value()) {
1324             return invalidConfigReason;
1325         }
1326 
1327         // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
1328         const set<int>& tagIds = matcher->getAtomIds();
1329         for (int atomId : tagIds) {
1330             auto& matchers = allTagIdsToMatchersMap[atomId];
1331             // Performance note:
1332             // For small amount of elements linear search in vector will be
1333             // faster then look up in a set:
1334             // - we do not expect matchers vector per atom id will have significant size (< 10)
1335             // - iteration via vector is the fastest way compared to other containers (set, etc.)
1336             //   in the hot path MetricsManager::onLogEvent()
1337             // - vector<T> will have the smallest memory footprint compared to any other
1338             //   std containers implementation
1339             if (find(matchers.begin(), matchers.end(), matcherIndex) == matchers.end()) {
1340                 matchers.push_back(matcherIndex);
1341             }
1342         }
1343     }
1344 
1345     return nullopt;
1346 }
1347 
initConditions(const ConfigKey & key,const StatsdConfig & config,const unordered_map<int64_t,int> & atomMatchingTrackerMap,unordered_map<int64_t,int> & conditionTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,unordered_map<int,std::vector<int>> & trackerToConditionMap,vector<ConditionState> & initialConditionCache)1348 optional<InvalidConfigReason> initConditions(
1349         const ConfigKey& key, const StatsdConfig& config,
1350         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
1351         unordered_map<int64_t, int>& conditionTrackerMap,
1352         vector<sp<ConditionTracker>>& allConditionTrackers,
1353         unordered_map<int, std::vector<int>>& trackerToConditionMap,
1354         vector<ConditionState>& initialConditionCache) {
1355     vector<Predicate> conditionConfigs;
1356     const int conditionTrackerCount = config.predicate_size();
1357     conditionConfigs.reserve(conditionTrackerCount);
1358     allConditionTrackers.reserve(conditionTrackerCount);
1359     initialConditionCache.assign(conditionTrackerCount, ConditionState::kNotEvaluated);
1360     optional<InvalidConfigReason> invalidConfigReason;
1361 
1362     for (int i = 0; i < conditionTrackerCount; i++) {
1363         const Predicate& condition = config.predicate(i);
1364         sp<ConditionTracker> tracker = createConditionTracker(
1365                 key, condition, i, atomMatchingTrackerMap, invalidConfigReason);
1366         if (tracker == nullptr) {
1367             return invalidConfigReason;
1368         }
1369         allConditionTrackers.push_back(tracker);
1370         if (conditionTrackerMap.find(condition.id()) != conditionTrackerMap.end()) {
1371             ALOGE("Duplicate Predicate found!");
1372             return createInvalidConfigReasonWithPredicate(INVALID_CONFIG_REASON_CONDITION_DUPLICATE,
1373                                                           condition.id());
1374         }
1375         conditionTrackerMap[condition.id()] = i;
1376         conditionConfigs.push_back(condition);
1377     }
1378 
1379     vector<bool> stackTracker(allConditionTrackers.size(), false);
1380     for (size_t i = 0; i < allConditionTrackers.size(); i++) {
1381         auto& conditionTracker = allConditionTrackers[i];
1382         invalidConfigReason =
1383                 conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
1384                                        stackTracker, initialConditionCache);
1385         if (invalidConfigReason.has_value()) {
1386             return invalidConfigReason;
1387         }
1388         for (const int trackerIndex : conditionTracker->getAtomMatchingTrackerIndex()) {
1389             auto& conditionList = trackerToConditionMap[trackerIndex];
1390             conditionList.push_back(i);
1391         }
1392     }
1393     return nullopt;
1394 }
1395 
initStates(const StatsdConfig & config,unordered_map<int64_t,int> & stateAtomIdMap,unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,map<int64_t,uint64_t> & stateProtoHashes)1396 optional<InvalidConfigReason> initStates(
1397         const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
1398         unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
1399         map<int64_t, uint64_t>& stateProtoHashes) {
1400     for (int i = 0; i < config.state_size(); i++) {
1401         const State& state = config.state(i);
1402         const int64_t stateId = state.id();
1403         stateAtomIdMap[stateId] = state.atom_id();
1404 
1405         string serializedState;
1406         if (!state.SerializeToString(&serializedState)) {
1407             ALOGE("Unable to serialize state %lld", (long long)stateId);
1408             return createInvalidConfigReasonWithState(
1409                     INVALID_CONFIG_REASON_STATE_SERIALIZATION_FAILED, state.id(), state.atom_id());
1410         }
1411         stateProtoHashes[stateId] = Hash64(serializedState);
1412 
1413         const StateMap& stateMap = state.map();
1414         for (auto group : stateMap.group()) {
1415             for (auto value : group.value()) {
1416                 allStateGroupMaps[stateId][value] = group.group_id();
1417             }
1418         }
1419     }
1420 
1421     return nullopt;
1422 }
1423 
initMetrics(const ConfigKey & key,const StatsdConfig & config,const int64_t timeBaseTimeNs,const int64_t currentTimeNs,const sp<StatsPullerManager> & pullerManager,const unordered_map<int64_t,int> & atomMatchingTrackerMap,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,const unordered_map<int64_t,int> & stateAtomIdMap,const unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps,vector<sp<ConditionTracker>> & allConditionTrackers,const vector<ConditionState> & initialConditionCache,vector<sp<MetricProducer>> & allMetricProducers,unordered_map<int,vector<int>> & conditionToMetricMap,unordered_map<int,vector<int>> & trackerToMetricMap,unordered_map<int64_t,int> & metricMap,std::set<int64_t> & noReportMetricIds,unordered_map<int,vector<int>> & activationAtomTrackerToMetricMap,unordered_map<int,vector<int>> & deactivationAtomTrackerToMetricMap,vector<int> & metricsWithActivation)1424 optional<InvalidConfigReason> initMetrics(
1425         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
1426         const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
1427         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
1428         const unordered_map<int64_t, int>& conditionTrackerMap,
1429         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
1430         const unordered_map<int64_t, int>& stateAtomIdMap,
1431         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
1432         vector<sp<ConditionTracker>>& allConditionTrackers,
1433         const vector<ConditionState>& initialConditionCache,
1434         vector<sp<MetricProducer>>& allMetricProducers,
1435         unordered_map<int, vector<int>>& conditionToMetricMap,
1436         unordered_map<int, vector<int>>& trackerToMetricMap, unordered_map<int64_t, int>& metricMap,
1437         std::set<int64_t>& noReportMetricIds,
1438         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
1439         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
1440         vector<int>& metricsWithActivation) {
1441     sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
1442     sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchingTrackers);
1443     const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
1444                                 config.event_metric_size() + config.gauge_metric_size() +
1445                                 config.value_metric_size() + config.kll_metric_size();
1446     allMetricProducers.reserve(allMetricsCount);
1447     optional<InvalidConfigReason> invalidConfigReason;
1448 
1449     if (config.has_restricted_metrics_delegate_package_name() &&
1450         allMetricsCount != config.event_metric_size()) {
1451         ALOGE("Restricted metrics only support event metric");
1452         return InvalidConfigReason(INVALID_CONFIG_REASON_RESTRICTED_METRIC_NOT_SUPPORTED);
1453     }
1454 
1455     // Construct map from metric id to metric activation index. The map will be used to determine
1456     // the metric activation corresponding to a metric.
1457     unordered_map<int64_t, int> metricToActivationMap;
1458     for (int i = 0; i < config.metric_activation_size(); i++) {
1459         const MetricActivation& metricActivation = config.metric_activation(i);
1460         int64_t metricId = metricActivation.metric_id();
1461         if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
1462             ALOGE("Metric %lld has multiple MetricActivations", (long long)metricId);
1463             return InvalidConfigReason(INVALID_CONFIG_REASON_METRIC_HAS_MULTIPLE_ACTIVATIONS,
1464                                        metricId);
1465         }
1466         metricToActivationMap.insert({metricId, i});
1467     }
1468 
1469     // Build MetricProducers for each metric defined in config.
1470     // build CountMetricProducer
1471     for (int i = 0; i < config.count_metric_size(); i++) {
1472         int metricIndex = allMetricProducers.size();
1473         const CountMetric& metric = config.count_metric(i);
1474         metricMap.insert({metric.id(), metricIndex});
1475         optional<sp<MetricProducer>> producer = createCountMetricProducerAndUpdateMetadata(
1476                 key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
1477                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1478                 conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
1479                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1480                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1481                 metricsWithActivation, invalidConfigReason);
1482         if (!producer) {
1483             return invalidConfigReason;
1484         }
1485         allMetricProducers.push_back(producer.value());
1486     }
1487 
1488     // build DurationMetricProducer
1489     for (int i = 0; i < config.duration_metric_size(); i++) {
1490         int metricIndex = allMetricProducers.size();
1491         const DurationMetric& metric = config.duration_metric(i);
1492         metricMap.insert({metric.id(), metricIndex});
1493 
1494         optional<sp<MetricProducer>> producer = createDurationMetricProducerAndUpdateMetadata(
1495                 key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
1496                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1497                 conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
1498                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1499                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1500                 metricsWithActivation, invalidConfigReason);
1501         if (!producer) {
1502             return invalidConfigReason;
1503         }
1504         allMetricProducers.push_back(producer.value());
1505     }
1506 
1507     // build EventMetricProducer
1508     for (int i = 0; i < config.event_metric_size(); i++) {
1509         int metricIndex = allMetricProducers.size();
1510         const EventMetric& metric = config.event_metric(i);
1511         metricMap.insert({metric.id(), metricIndex});
1512         optional<sp<MetricProducer>> producer = createEventMetricProducerAndUpdateMetadata(
1513                 key, config, timeBaseTimeNs, metric, metricIndex, allAtomMatchingTrackers,
1514                 atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap,
1515                 initialConditionCache, wizard, metricToActivationMap, trackerToMetricMap,
1516                 conditionToMetricMap, activationAtomTrackerToMetricMap,
1517                 deactivationAtomTrackerToMetricMap, metricsWithActivation, invalidConfigReason);
1518         if (!producer) {
1519             return invalidConfigReason;
1520         }
1521         allMetricProducers.push_back(producer.value());
1522     }
1523 
1524     // build NumericValueMetricProducer
1525     for (int i = 0; i < config.value_metric_size(); i++) {
1526         int metricIndex = allMetricProducers.size();
1527         const ValueMetric& metric = config.value_metric(i);
1528         metricMap.insert({metric.id(), metricIndex});
1529         optional<sp<MetricProducer>> producer = createNumericValueMetricProducerAndUpdateMetadata(
1530                 key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex,
1531                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1532                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap,
1533                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1534                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1535                 metricsWithActivation, invalidConfigReason);
1536         if (!producer) {
1537             return invalidConfigReason;
1538         }
1539         allMetricProducers.push_back(producer.value());
1540     }
1541 
1542     // build KllMetricProducer
1543     for (int i = 0; i < config.kll_metric_size(); i++) {
1544         int metricIndex = allMetricProducers.size();
1545         const KllMetric& metric = config.kll_metric(i);
1546         metricMap.insert({metric.id(), metricIndex});
1547         optional<sp<MetricProducer>> producer = createKllMetricProducerAndUpdateMetadata(
1548                 key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex,
1549                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1550                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap,
1551                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1552                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1553                 metricsWithActivation, invalidConfigReason);
1554         if (!producer) {
1555             return invalidConfigReason;
1556         }
1557         allMetricProducers.push_back(producer.value());
1558     }
1559 
1560     // Gauge metrics.
1561     for (int i = 0; i < config.gauge_metric_size(); i++) {
1562         int metricIndex = allMetricProducers.size();
1563         const GaugeMetric& metric = config.gauge_metric(i);
1564         metricMap.insert({metric.id(), metricIndex});
1565         optional<sp<MetricProducer>> producer = createGaugeMetricProducerAndUpdateMetadata(
1566                 key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex,
1567                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1568                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
1569                 metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1570                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1571                 metricsWithActivation, invalidConfigReason);
1572         if (!producer) {
1573             return invalidConfigReason;
1574         }
1575         allMetricProducers.push_back(producer.value());
1576     }
1577     for (int i = 0; i < config.no_report_metric_size(); ++i) {
1578         const auto no_report_metric = config.no_report_metric(i);
1579         if (metricMap.find(no_report_metric) == metricMap.end()) {
1580             ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
1581             return InvalidConfigReason(INVALID_CONFIG_REASON_NO_REPORT_METRIC_NOT_FOUND,
1582                                        no_report_metric);
1583         }
1584         noReportMetricIds.insert(no_report_metric);
1585     }
1586 
1587     const set<int> whitelistedAtomIds(config.whitelisted_atom_ids().begin(),
1588                                       config.whitelisted_atom_ids().end());
1589     for (const auto& it : allMetricProducers) {
1590         // Register metrics to StateTrackers
1591         for (int atomId : it->getSlicedStateAtoms()) {
1592             // Register listener for non-whitelisted atoms only. Using whitelisted atom as a sliced
1593             // state atom is not allowed.
1594             if (whitelistedAtomIds.find(atomId) == whitelistedAtomIds.end()) {
1595                 StateManager::getInstance().registerListener(atomId, it);
1596             } else {
1597                 return InvalidConfigReason(
1598                         INVALID_CONFIG_REASON_METRIC_SLICED_STATE_ATOM_ALLOWED_FROM_ANY_UID,
1599                         it->getMetricId());
1600             }
1601         }
1602     }
1603     return nullopt;
1604 }
1605 
initAlerts(const StatsdConfig & config,const int64_t currentTimeNs,const unordered_map<int64_t,int> & metricProducerMap,unordered_map<int64_t,int> & alertTrackerMap,const sp<AlarmMonitor> & anomalyAlarmMonitor,vector<sp<MetricProducer>> & allMetricProducers,vector<sp<AnomalyTracker>> & allAnomalyTrackers)1606 optional<InvalidConfigReason> initAlerts(const StatsdConfig& config, const int64_t currentTimeNs,
1607                                          const unordered_map<int64_t, int>& metricProducerMap,
1608                                          unordered_map<int64_t, int>& alertTrackerMap,
1609                                          const sp<AlarmMonitor>& anomalyAlarmMonitor,
1610                                          vector<sp<MetricProducer>>& allMetricProducers,
1611                                          vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
1612     optional<InvalidConfigReason> invalidConfigReason;
1613     for (int i = 0; i < config.alert_size(); i++) {
1614         const Alert& alert = config.alert(i);
1615         alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
1616         optional<sp<AnomalyTracker>> anomalyTracker = createAnomalyTracker(
1617                 alert, anomalyAlarmMonitor, UpdateStatus::UPDATE_NEW, currentTimeNs,
1618                 metricProducerMap, allMetricProducers, invalidConfigReason);
1619         if (!anomalyTracker) {
1620             return invalidConfigReason;
1621         }
1622         allAnomalyTrackers.push_back(anomalyTracker.value());
1623     }
1624     return initSubscribersForSubscriptionType(config, Subscription::ALERT, alertTrackerMap,
1625                                               allAnomalyTrackers);
1626 }
1627 
initAlarms(const StatsdConfig & config,const ConfigKey & key,const sp<AlarmMonitor> & periodicAlarmMonitor,const int64_t timeBaseNs,const int64_t currentTimeNs,vector<sp<AlarmTracker>> & allAlarmTrackers)1628 optional<InvalidConfigReason> initAlarms(const StatsdConfig& config, const ConfigKey& key,
1629                                          const sp<AlarmMonitor>& periodicAlarmMonitor,
1630                                          const int64_t timeBaseNs, const int64_t currentTimeNs,
1631                                          vector<sp<AlarmTracker>>& allAlarmTrackers) {
1632     unordered_map<int64_t, int> alarmTrackerMap;
1633     int64_t startMillis = timeBaseNs / 1000 / 1000;
1634     int64_t currentTimeMillis = currentTimeNs / 1000 / 1000;
1635     for (int i = 0; i < config.alarm_size(); i++) {
1636         const Alarm& alarm = config.alarm(i);
1637         if (alarm.offset_millis() <= 0) {
1638             ALOGW("Alarm offset_millis should be larger than 0.");
1639             return createInvalidConfigReasonWithAlarm(
1640                     INVALID_CONFIG_REASON_ALARM_OFFSET_LESS_THAN_OR_EQUAL_ZERO, alarm.id());
1641         }
1642         if (alarm.period_millis() <= 0) {
1643             ALOGW("Alarm period_millis should be larger than 0.");
1644             return createInvalidConfigReasonWithAlarm(
1645                     INVALID_CONFIG_REASON_ALARM_PERIOD_LESS_THAN_OR_EQUAL_ZERO, alarm.id());
1646         }
1647         alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
1648         allAlarmTrackers.push_back(
1649                 new AlarmTracker(startMillis, currentTimeMillis, alarm, key, periodicAlarmMonitor));
1650     }
1651     return initSubscribersForSubscriptionType(config, Subscription::ALARM, alarmTrackerMap,
1652                                               allAlarmTrackers);
1653 }
1654 
initStatsdConfig(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,std::unordered_map<int,std::vector<int>> & allTagIdsToMatchersMap,vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,unordered_map<int64_t,int> & conditionTrackerMap,vector<sp<MetricProducer>> & allMetricProducers,unordered_map<int64_t,int> & metricProducerMap,vector<sp<AnomalyTracker>> & allAnomalyTrackers,vector<sp<AlarmTracker>> & allPeriodicAlarmTrackers,unordered_map<int,std::vector<int>> & conditionToMetricMap,unordered_map<int,std::vector<int>> & trackerToMetricMap,unordered_map<int,std::vector<int>> & trackerToConditionMap,unordered_map<int,std::vector<int>> & activationAtomTrackerToMetricMap,unordered_map<int,std::vector<int>> & deactivationAtomTrackerToMetricMap,unordered_map<int64_t,int> & alertTrackerMap,vector<int> & metricsWithActivation,map<int64_t,uint64_t> & stateProtoHashes,set<int64_t> & noReportMetricIds)1655 optional<InvalidConfigReason> initStatsdConfig(
1656         const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
1657         const sp<StatsPullerManager>& pullerManager, const sp<AlarmMonitor>& anomalyAlarmMonitor,
1658         const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
1659         const int64_t currentTimeNs,
1660         std::unordered_map<int, std::vector<int>>& allTagIdsToMatchersMap,
1661         vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
1662         unordered_map<int64_t, int>& atomMatchingTrackerMap,
1663         vector<sp<ConditionTracker>>& allConditionTrackers,
1664         unordered_map<int64_t, int>& conditionTrackerMap,
1665         vector<sp<MetricProducer>>& allMetricProducers,
1666         unordered_map<int64_t, int>& metricProducerMap,
1667         vector<sp<AnomalyTracker>>& allAnomalyTrackers,
1668         vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
1669         unordered_map<int, std::vector<int>>& conditionToMetricMap,
1670         unordered_map<int, std::vector<int>>& trackerToMetricMap,
1671         unordered_map<int, std::vector<int>>& trackerToConditionMap,
1672         unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
1673         unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
1674         unordered_map<int64_t, int>& alertTrackerMap, vector<int>& metricsWithActivation,
1675         map<int64_t, uint64_t>& stateProtoHashes, set<int64_t>& noReportMetricIds) {
1676     vector<ConditionState> initialConditionCache;
1677     unordered_map<int64_t, int> stateAtomIdMap;
1678     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
1679 
1680     if (config.package_certificate_hash_size_bytes() > UINT8_MAX) {
1681         ALOGE("Invalid value for package_certificate_hash_size_bytes: %d",
1682               config.package_certificate_hash_size_bytes());
1683         return InvalidConfigReason(INVALID_CONFIG_REASON_PACKAGE_CERT_HASH_SIZE_TOO_LARGE);
1684     }
1685 
1686     optional<InvalidConfigReason> invalidConfigReason =
1687             initAtomMatchingTrackers(config, uidMap, atomMatchingTrackerMap,
1688                                      allAtomMatchingTrackers, allTagIdsToMatchersMap);
1689     if (invalidConfigReason.has_value()) {
1690         ALOGE("initAtomMatchingTrackers failed");
1691         return invalidConfigReason;
1692     }
1693     VLOG("initAtomMatchingTrackers succeed...");
1694 
1695     invalidConfigReason =
1696             initConditions(key, config, atomMatchingTrackerMap, conditionTrackerMap,
1697                            allConditionTrackers, trackerToConditionMap, initialConditionCache);
1698     if (invalidConfigReason.has_value()) {
1699         ALOGE("initConditionTrackers failed");
1700         return invalidConfigReason;
1701     }
1702 
1703     invalidConfigReason = initStates(config, stateAtomIdMap, allStateGroupMaps, stateProtoHashes);
1704     if (invalidConfigReason.has_value()) {
1705         ALOGE("initStates failed");
1706         return invalidConfigReason;
1707     }
1708 
1709     invalidConfigReason = initMetrics(
1710             key, config, timeBaseNs, currentTimeNs, pullerManager, atomMatchingTrackerMap,
1711             conditionTrackerMap, allAtomMatchingTrackers, stateAtomIdMap, allStateGroupMaps,
1712             allConditionTrackers, initialConditionCache, allMetricProducers, conditionToMetricMap,
1713             trackerToMetricMap, metricProducerMap, noReportMetricIds,
1714             activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1715             metricsWithActivation);
1716     if (invalidConfigReason.has_value()) {
1717         ALOGE("initMetricProducers failed");
1718         return invalidConfigReason;
1719     }
1720 
1721     invalidConfigReason = initAlerts(config, currentTimeNs, metricProducerMap, alertTrackerMap,
1722                                      anomalyAlarmMonitor, allMetricProducers, allAnomalyTrackers);
1723     if (invalidConfigReason.has_value()) {
1724         ALOGE("initAlerts failed");
1725         return invalidConfigReason;
1726     }
1727 
1728     invalidConfigReason = initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
1729                                      allPeriodicAlarmTrackers);
1730     if (invalidConfigReason.has_value()) {
1731         ALOGE("initAlarms failed");
1732         return invalidConfigReason;
1733     }
1734 
1735     return nullopt;
1736 }
1737 
1738 }  // namespace statsd
1739 }  // namespace os
1740 }  // namespace android
1741