• 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 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 "hash.h"
29 #include "matchers/CombinationAtomMatchingTracker.h"
30 #include "matchers/EventMatcherWizard.h"
31 #include "matchers/SimpleAtomMatchingTracker.h"
32 #include "metrics/CountMetricProducer.h"
33 #include "metrics/DurationMetricProducer.h"
34 #include "metrics/EventMetricProducer.h"
35 #include "metrics/GaugeMetricProducer.h"
36 #include "metrics/MetricProducer.h"
37 #include "metrics/ValueMetricProducer.h"
38 #include "state/StateManager.h"
39 #include "stats_util.h"
40 
41 using google::protobuf::MessageLite;
42 using std::set;
43 using std::unordered_map;
44 using std::vector;
45 
46 namespace android {
47 namespace os {
48 namespace statsd {
49 
50 namespace {
51 
hasLeafNode(const FieldMatcher & matcher)52 bool hasLeafNode(const FieldMatcher& matcher) {
53     if (!matcher.has_field()) {
54         return false;
55     }
56     for (int i = 0; i < matcher.child_size(); ++i) {
57         if (hasLeafNode(matcher.child(i))) {
58             return true;
59         }
60     }
61     return true;
62 }
63 
64 }  // namespace
65 
createAtomMatchingTracker(const AtomMatcher & logMatcher,const int index,const sp<UidMap> & uidMap)66 sp<AtomMatchingTracker> createAtomMatchingTracker(const AtomMatcher& logMatcher, const int index,
67                                                   const sp<UidMap>& uidMap) {
68     string serializedMatcher;
69     if (!logMatcher.SerializeToString(&serializedMatcher)) {
70         ALOGE("Unable to serialize matcher %lld", (long long)logMatcher.id());
71         return nullptr;
72     }
73     uint64_t protoHash = Hash64(serializedMatcher);
74     switch (logMatcher.contents_case()) {
75         case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
76             return new SimpleAtomMatchingTracker(logMatcher.id(), index, protoHash,
77                                                  logMatcher.simple_atom_matcher(), uidMap);
78         case AtomMatcher::ContentsCase::kCombination:
79             return new CombinationAtomMatchingTracker(logMatcher.id(), index, protoHash);
80         default:
81             ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
82             return nullptr;
83     }
84 }
85 
createConditionTracker(const ConfigKey & key,const Predicate & predicate,const int index,const unordered_map<int64_t,int> & atomMatchingTrackerMap)86 sp<ConditionTracker> createConditionTracker(
87         const ConfigKey& key, const Predicate& predicate, const int index,
88         const unordered_map<int64_t, int>& atomMatchingTrackerMap) {
89     string serializedPredicate;
90     if (!predicate.SerializeToString(&serializedPredicate)) {
91         ALOGE("Unable to serialize predicate %lld", (long long)predicate.id());
92         return nullptr;
93     }
94     uint64_t protoHash = Hash64(serializedPredicate);
95     switch (predicate.contents_case()) {
96         case Predicate::ContentsCase::kSimplePredicate: {
97             return new SimpleConditionTracker(key, predicate.id(), protoHash, index,
98                                               predicate.simple_predicate(), atomMatchingTrackerMap);
99         }
100         case Predicate::ContentsCase::kCombination: {
101             return new CombinationConditionTracker(predicate.id(), index, protoHash);
102         }
103         default:
104             ALOGE("Predicate \"%lld\" malformed", (long long)predicate.id());
105             return nullptr;
106     }
107 }
108 
getMetricProtoHash(const StatsdConfig & config,const MessageLite & metric,const int64_t id,const unordered_map<int64_t,int> & metricToActivationMap,uint64_t & metricHash)109 bool getMetricProtoHash(const StatsdConfig& config, const MessageLite& metric, const int64_t id,
110                         const unordered_map<int64_t, int>& metricToActivationMap,
111                         uint64_t& metricHash) {
112     string serializedMetric;
113     if (!metric.SerializeToString(&serializedMetric)) {
114         ALOGE("Unable to serialize metric %lld", (long long)id);
115         return false;
116     }
117     metricHash = Hash64(serializedMetric);
118 
119     // Combine with activation hash, if applicable
120     const auto& metricActivationIt = metricToActivationMap.find(id);
121     if (metricActivationIt != metricToActivationMap.end()) {
122         string serializedActivation;
123         const MetricActivation& activation = config.metric_activation(metricActivationIt->second);
124         if (!activation.SerializeToString(&serializedActivation)) {
125             ALOGE("Unable to serialize metric activation for metric %lld", (long long)id);
126             return false;
127         }
128         metricHash = Hash64(to_string(metricHash).append(to_string(Hash64(serializedActivation))));
129     }
130     return true;
131 }
132 
handleMetricWithAtomMatchingTrackers(const int64_t matcherId,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)133 bool handleMetricWithAtomMatchingTrackers(
134         const int64_t matcherId, const int metricIndex, const bool enforceOneAtom,
135         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
136         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
137         unordered_map<int, vector<int>>& trackerToMetricMap, int& logTrackerIndex) {
138     auto logTrackerIt = atomMatchingTrackerMap.find(matcherId);
139     if (logTrackerIt == atomMatchingTrackerMap.end()) {
140         ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)matcherId);
141         return false;
142     }
143     if (enforceOneAtom && allAtomMatchingTrackers[logTrackerIt->second]->getAtomIds().size() > 1) {
144         ALOGE("AtomMatcher \"%lld\" has more than one tag ids. When a metric has dimension, "
145               "the \"what\" can only be about one atom type. trigger_event matchers can also only "
146               "be about one atom type.",
147               (long long)matcherId);
148         return false;
149     }
150     logTrackerIndex = logTrackerIt->second;
151     auto& metric_list = trackerToMetricMap[logTrackerIndex];
152     metric_list.push_back(metricIndex);
153     return true;
154 }
155 
handleMetricWithConditions(const int64_t condition,const int metricIndex,const unordered_map<int64_t,int> & conditionTrackerMap,const::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink> & links,const vector<sp<ConditionTracker>> & allConditionTrackers,int & conditionIndex,unordered_map<int,vector<int>> & conditionToMetricMap)156 bool handleMetricWithConditions(
157         const int64_t condition, const int metricIndex,
158         const unordered_map<int64_t, int>& conditionTrackerMap,
159         const ::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink>&
160                 links,
161         const vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex,
162         unordered_map<int, vector<int>>& conditionToMetricMap) {
163     auto condition_it = conditionTrackerMap.find(condition);
164     if (condition_it == conditionTrackerMap.end()) {
165         ALOGW("cannot find Predicate \"%lld\" in the config", (long long)condition);
166         return false;
167     }
168 
169     for (const auto& link : links) {
170         auto it = conditionTrackerMap.find(link.condition());
171         if (it == conditionTrackerMap.end()) {
172             ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
173             return false;
174         }
175     }
176     conditionIndex = condition_it->second;
177 
178     // will create new vector if not exist before.
179     auto& metricList = conditionToMetricMap[condition_it->second];
180     metricList.push_back(metricIndex);
181     return true;
182 }
183 
184 // Initializes state data structures for a metric.
185 // input:
186 // [config]: the input config
187 // [stateIds]: the slice_by_state ids for this metric
188 // [stateAtomIdMap]: this map contains the mapping from all state ids to atom ids
189 // [allStateGroupMaps]: this map contains the mapping from state ids and state
190 //                      values to state group ids for all states
191 // output:
192 // [slicedStateAtoms]: a vector of atom ids of all the slice_by_states
193 // [stateGroupMap]: this map should contain the mapping from states ids and state
194 //                      values to state group ids for all states that this metric
195 //                      is interested in
handleMetricWithStates(const StatsdConfig & config,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)196 bool handleMetricWithStates(
197         const StatsdConfig& config, const ::google::protobuf::RepeatedField<int64_t>& stateIds,
198         const unordered_map<int64_t, int>& stateAtomIdMap,
199         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
200         vector<int>& slicedStateAtoms,
201         unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap) {
202     for (const auto& stateId : stateIds) {
203         auto it = stateAtomIdMap.find(stateId);
204         if (it == stateAtomIdMap.end()) {
205             ALOGW("cannot find State %" PRId64 " in the config", stateId);
206             return false;
207         }
208         int atomId = it->second;
209         slicedStateAtoms.push_back(atomId);
210 
211         auto stateIt = allStateGroupMaps.find(stateId);
212         if (stateIt != allStateGroupMaps.end()) {
213             stateGroupMap[atomId] = stateIt->second;
214         }
215     }
216     return true;
217 }
218 
handleMetricWithStateLink(const FieldMatcher & stateMatcher,const vector<Matcher> & dimensionsInWhat)219 bool handleMetricWithStateLink(const FieldMatcher& stateMatcher,
220                                const vector<Matcher>& dimensionsInWhat) {
221     vector<Matcher> stateMatchers;
222     translateFieldMatcher(stateMatcher, &stateMatchers);
223 
224     return subsetDimensions(stateMatchers, dimensionsInWhat);
225 }
226 
227 // Validates a metricActivation and populates state.
228 // EventActivationMap and EventDeactivationMap are supplied to a MetricProducer
229 //      to provide the producer with state about its activators and deactivators.
230 // 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)231 bool handleMetricActivation(
232         const StatsdConfig& config, const int64_t metricId, const int metricIndex,
233         const unordered_map<int64_t, int>& metricToActivationMap,
234         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
235         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
236         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
237         vector<int>& metricsWithActivation,
238         unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
239         unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap) {
240     // Check if metric has an associated activation
241     auto itr = metricToActivationMap.find(metricId);
242     if (itr == metricToActivationMap.end()) {
243         return true;
244     }
245 
246     int activationIndex = itr->second;
247     const MetricActivation& metricActivation = config.metric_activation(activationIndex);
248 
249     for (int i = 0; i < metricActivation.event_activation_size(); i++) {
250         const EventActivation& activation = metricActivation.event_activation(i);
251 
252         auto itr = atomMatchingTrackerMap.find(activation.atom_matcher_id());
253         if (itr == atomMatchingTrackerMap.end()) {
254             ALOGE("Atom matcher not found for event activation.");
255             return false;
256         }
257 
258         ActivationType activationType = (activation.has_activation_type())
259                                                 ? activation.activation_type()
260                                                 : metricActivation.activation_type();
261         std::shared_ptr<Activation> activationWrapper =
262                 std::make_shared<Activation>(activationType, activation.ttl_seconds() * NS_PER_SEC);
263 
264         int atomMatcherIndex = itr->second;
265         activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex);
266         eventActivationMap.emplace(atomMatcherIndex, activationWrapper);
267 
268         if (activation.has_deactivation_atom_matcher_id()) {
269             itr = atomMatchingTrackerMap.find(activation.deactivation_atom_matcher_id());
270             if (itr == atomMatchingTrackerMap.end()) {
271                 ALOGE("Atom matcher not found for event deactivation.");
272                 return false;
273             }
274             int deactivationAtomMatcherIndex = itr->second;
275             deactivationAtomTrackerToMetricMap[deactivationAtomMatcherIndex].push_back(metricIndex);
276             eventDeactivationMap[deactivationAtomMatcherIndex].push_back(activationWrapper);
277         }
278     }
279 
280     metricsWithActivation.push_back(metricIndex);
281     return true;
282 }
283 
284 // Validates a metricActivation and populates state.
285 // Fills the new event activation/deactivation maps, preserving the existing activations
286 // 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)287 bool handleMetricActivationOnConfigUpdate(
288         const StatsdConfig& config, const int64_t metricId, const int metricIndex,
289         const unordered_map<int64_t, int>& metricToActivationMap,
290         const unordered_map<int64_t, int>& oldAtomMatchingTrackerMap,
291         const unordered_map<int64_t, int>& newAtomMatchingTrackerMap,
292         const unordered_map<int, shared_ptr<Activation>>& oldEventActivationMap,
293         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
294         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
295         vector<int>& metricsWithActivation,
296         unordered_map<int, shared_ptr<Activation>>& newEventActivationMap,
297         unordered_map<int, vector<shared_ptr<Activation>>>& newEventDeactivationMap) {
298     // Check if metric has an associated activation.
299     const auto& itr = metricToActivationMap.find(metricId);
300     if (itr == metricToActivationMap.end()) {
301         return true;
302     }
303 
304     int activationIndex = itr->second;
305     const MetricActivation& metricActivation = config.metric_activation(activationIndex);
306 
307     for (int i = 0; i < metricActivation.event_activation_size(); i++) {
308         const int64_t activationMatcherId = metricActivation.event_activation(i).atom_matcher_id();
309 
310         const auto& newActivationIt = newAtomMatchingTrackerMap.find(activationMatcherId);
311         if (newActivationIt == newAtomMatchingTrackerMap.end()) {
312             ALOGE("Atom matcher not found in new config for event activation.");
313             return false;
314         }
315         int newActivationMatcherIndex = newActivationIt->second;
316 
317         // Find the old activation struct and copy it over.
318         const auto& oldActivationIt = oldAtomMatchingTrackerMap.find(activationMatcherId);
319         if (oldActivationIt == oldAtomMatchingTrackerMap.end()) {
320             ALOGE("Atom matcher not found in existing config for event activation.");
321             return false;
322         }
323         int oldActivationMatcherIndex = oldActivationIt->second;
324         const auto& oldEventActivationIt = oldEventActivationMap.find(oldActivationMatcherIndex);
325         if (oldEventActivationIt == oldEventActivationMap.end()) {
326             ALOGE("Could not find existing event activation to update");
327             return false;
328         }
329         newEventActivationMap.emplace(newActivationMatcherIndex, oldEventActivationIt->second);
330         activationAtomTrackerToMetricMap[newActivationMatcherIndex].push_back(metricIndex);
331 
332         if (metricActivation.event_activation(i).has_deactivation_atom_matcher_id()) {
333             const int64_t deactivationMatcherId =
334                     metricActivation.event_activation(i).deactivation_atom_matcher_id();
335             const auto& newDeactivationIt = newAtomMatchingTrackerMap.find(deactivationMatcherId);
336             if (newDeactivationIt == newAtomMatchingTrackerMap.end()) {
337                 ALOGE("Deactivation atom matcher not found in new config for event activation.");
338                 return false;
339             }
340             int newDeactivationMatcherIndex = newDeactivationIt->second;
341             newEventDeactivationMap[newDeactivationMatcherIndex].push_back(
342                     oldEventActivationIt->second);
343             deactivationAtomTrackerToMetricMap[newDeactivationMatcherIndex].push_back(metricIndex);
344         }
345     }
346 
347     metricsWithActivation.push_back(metricIndex);
348     return true;
349 }
350 
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)351 optional<sp<MetricProducer>> createCountMetricProducerAndUpdateMetadata(
352         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
353         const int64_t currentTimeNs, const CountMetric& metric, const int metricIndex,
354         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
355         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
356         vector<sp<ConditionTracker>>& allConditionTrackers,
357         const unordered_map<int64_t, int>& conditionTrackerMap,
358         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
359         const unordered_map<int64_t, int>& stateAtomIdMap,
360         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
361         const unordered_map<int64_t, int>& metricToActivationMap,
362         unordered_map<int, vector<int>>& trackerToMetricMap,
363         unordered_map<int, vector<int>>& conditionToMetricMap,
364         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
365         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
366         vector<int>& metricsWithActivation) {
367     if (!metric.has_id() || !metric.has_what()) {
368         ALOGE("cannot find metric id or \"what\" in CountMetric \"%lld\"", (long long)metric.id());
369         return nullopt;
370     }
371     int trackerIndex;
372     if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
373                                               metric.has_dimensions_in_what(),
374                                               allAtomMatchingTrackers, atomMatchingTrackerMap,
375                                               trackerToMetricMap, trackerIndex)) {
376         return nullopt;
377     }
378 
379     int conditionIndex = -1;
380     if (metric.has_condition()) {
381         if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
382                                         metric.links(), allConditionTrackers, conditionIndex,
383                                         conditionToMetricMap)) {
384             return nullopt;
385         }
386     } else {
387         if (metric.links_size() > 0) {
388             ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
389             return nullopt;
390         }
391     }
392 
393     std::vector<int> slicedStateAtoms;
394     unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
395     if (metric.slice_by_state_size() > 0) {
396         if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
397                                     allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
398             return nullopt;
399         }
400     } else {
401         if (metric.state_link_size() > 0) {
402             ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
403             return nullopt;
404         }
405     }
406 
407     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
408     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
409     if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
410                                 atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
411                                 deactivationAtomTrackerToMetricMap, metricsWithActivation,
412                                 eventActivationMap, eventDeactivationMap)) {
413         return nullopt;
414     }
415 
416     uint64_t metricHash;
417     if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
418         return nullopt;
419     }
420 
421     if (metric.has_threshold() &&
422         (metric.threshold().value_comparison_case() == UploadThreshold::kLtFloat ||
423          metric.threshold().value_comparison_case() == UploadThreshold::kGtFloat)) {
424         ALOGW("Count metric incorrect upload threshold type or no type used");
425         return nullopt;
426     }
427 
428     return {new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
429                                     metricHash, timeBaseNs, currentTimeNs, eventActivationMap,
430                                     eventDeactivationMap, slicedStateAtoms, stateGroupMap)};
431 }
432 
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)433 optional<sp<MetricProducer>> createDurationMetricProducerAndUpdateMetadata(
434         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
435         const int64_t currentTimeNs, const DurationMetric& metric, const int metricIndex,
436         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
437         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
438         vector<sp<ConditionTracker>>& allConditionTrackers,
439         const unordered_map<int64_t, int>& conditionTrackerMap,
440         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
441         const unordered_map<int64_t, int>& stateAtomIdMap,
442         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
443         const unordered_map<int64_t, int>& metricToActivationMap,
444         unordered_map<int, vector<int>>& trackerToMetricMap,
445         unordered_map<int, vector<int>>& conditionToMetricMap,
446         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
447         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
448         vector<int>& metricsWithActivation) {
449     if (!metric.has_id() || !metric.has_what()) {
450         ALOGE("cannot find metric id or \"what\" in DurationMetric \"%lld\"",
451               (long long)metric.id());
452         return nullopt;
453     }
454     const auto& what_it = conditionTrackerMap.find(metric.what());
455     if (what_it == conditionTrackerMap.end()) {
456         ALOGE("DurationMetric's \"what\" is not present in the condition trackers");
457         return nullopt;
458     }
459 
460     const int whatIndex = what_it->second;
461     const Predicate& durationWhat = config.predicate(whatIndex);
462     if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
463         ALOGE("DurationMetric's \"what\" must be a simple condition");
464         return nullopt;
465     }
466 
467     const SimplePredicate& simplePredicate = durationWhat.simple_predicate();
468     bool nesting = simplePredicate.count_nesting();
469 
470     int startIndex = -1, stopIndex = -1, stopAllIndex = -1;
471     if (!simplePredicate.has_start() ||
472         !handleMetricWithAtomMatchingTrackers(
473                 simplePredicate.start(), metricIndex, metric.has_dimensions_in_what(),
474                 allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, startIndex)) {
475         ALOGE("Duration metrics must specify a valid start event matcher");
476         return nullopt;
477     }
478 
479     if (simplePredicate.has_stop() &&
480         !handleMetricWithAtomMatchingTrackers(
481                 simplePredicate.stop(), metricIndex, metric.has_dimensions_in_what(),
482                 allAtomMatchingTrackers, atomMatchingTrackerMap, trackerToMetricMap, stopIndex)) {
483         return nullopt;
484     }
485 
486     if (simplePredicate.has_stop_all() &&
487         !handleMetricWithAtomMatchingTrackers(simplePredicate.stop_all(), metricIndex,
488                                               metric.has_dimensions_in_what(),
489                                               allAtomMatchingTrackers, atomMatchingTrackerMap,
490                                               trackerToMetricMap, stopAllIndex)) {
491         return nullopt;
492     }
493 
494     FieldMatcher internalDimensions = simplePredicate.dimensions();
495 
496     int conditionIndex = -1;
497     if (metric.has_condition()) {
498         if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
499                                         metric.links(), allConditionTrackers, conditionIndex,
500                                         conditionToMetricMap)) {
501             return nullopt;
502         }
503     } else if (metric.links_size() > 0) {
504         ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
505         return nullopt;
506     }
507 
508     std::vector<int> slicedStateAtoms;
509     unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
510     if (metric.slice_by_state_size() > 0) {
511         if (metric.aggregation_type() == DurationMetric::MAX_SPARSE) {
512             ALOGE("DurationMetric with aggregation type MAX_SPARSE cannot be sliced by state");
513             return nullopt;
514         }
515         if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
516                                     allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
517             return nullopt;
518         }
519     } else if (metric.state_link_size() > 0) {
520         ALOGW("DurationMetric has a MetricStateLink but doesn't have a sliced state");
521         return nullopt;
522     }
523 
524     // Check that all metric state links are a subset of dimensions_in_what fields.
525     std::vector<Matcher> dimensionsInWhat;
526     translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
527     for (const auto& stateLink : metric.state_link()) {
528         if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
529             ALOGW("DurationMetric's MetricStateLinks must be a subset of dimensions in what");
530             return nullopt;
531         }
532     }
533 
534     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
535     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
536     if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
537                                 atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
538                                 deactivationAtomTrackerToMetricMap, metricsWithActivation,
539                                 eventActivationMap, eventDeactivationMap)) {
540         return nullopt;
541     }
542 
543     uint64_t metricHash;
544     if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
545         return nullopt;
546     }
547 
548     if (metric.has_threshold()) {
549         switch (metric.threshold().value_comparison_case()) {
550             case UploadThreshold::kLtInt:
551             case UploadThreshold::kGtInt:
552             case UploadThreshold::kLteInt:
553             case UploadThreshold::kGteInt:
554                 break;
555             default:
556                 ALOGE("Duration metric incorrect upload threshold type or no type used");
557                 return nullopt;
558                 break;
559         }
560     }
561 
562     sp<MetricProducer> producer = new DurationMetricProducer(
563             key, metric, conditionIndex, initialConditionCache, whatIndex, startIndex, stopIndex,
564             stopAllIndex, nesting, wizard, metricHash, internalDimensions, timeBaseNs,
565             currentTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
566             stateGroupMap);
567     if (!producer->isValid()) {
568         return nullopt;
569     }
570     return {producer};
571 }
572 
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)573 optional<sp<MetricProducer>> createEventMetricProducerAndUpdateMetadata(
574         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
575         const EventMetric& metric, const int metricIndex,
576         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
577         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
578         vector<sp<ConditionTracker>>& allConditionTrackers,
579         const unordered_map<int64_t, int>& conditionTrackerMap,
580         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
581         const unordered_map<int64_t, int>& metricToActivationMap,
582         unordered_map<int, vector<int>>& trackerToMetricMap,
583         unordered_map<int, vector<int>>& conditionToMetricMap,
584         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
585         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
586         vector<int>& metricsWithActivation) {
587     if (!metric.has_id() || !metric.has_what()) {
588         ALOGE("cannot find the metric name or what in config");
589         return nullopt;
590     }
591     int trackerIndex;
592     if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex, false,
593                                               allAtomMatchingTrackers, atomMatchingTrackerMap,
594                                               trackerToMetricMap, trackerIndex)) {
595         return nullopt;
596     }
597 
598     int conditionIndex = -1;
599     if (metric.has_condition()) {
600         if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
601                                         metric.links(), allConditionTrackers, conditionIndex,
602                                         conditionToMetricMap)) {
603             return nullopt;
604         }
605     } else {
606         if (metric.links_size() > 0) {
607             ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
608             return nullopt;
609         }
610     }
611 
612     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
613     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
614     bool success = handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
615                                           atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
616                                           deactivationAtomTrackerToMetricMap, metricsWithActivation,
617                                           eventActivationMap, eventDeactivationMap);
618     if (!success) return nullptr;
619 
620     uint64_t metricHash;
621     if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
622         return nullopt;
623     }
624 
625     return {new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
626                                     metricHash, timeBaseNs, eventActivationMap,
627                                     eventDeactivationMap)};
628 }
629 
createValueMetricProducerAndUpdateMetadata(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)630 optional<sp<MetricProducer>> createValueMetricProducerAndUpdateMetadata(
631         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
632         const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
633         const ValueMetric& metric, const int metricIndex,
634         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
635         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
636         vector<sp<ConditionTracker>>& allConditionTrackers,
637         const unordered_map<int64_t, int>& conditionTrackerMap,
638         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
639         const sp<EventMatcherWizard>& matcherWizard,
640         const unordered_map<int64_t, int>& stateAtomIdMap,
641         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
642         const unordered_map<int64_t, int>& metricToActivationMap,
643         unordered_map<int, vector<int>>& trackerToMetricMap,
644         unordered_map<int, vector<int>>& conditionToMetricMap,
645         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
646         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
647         vector<int>& metricsWithActivation) {
648     if (!metric.has_id() || !metric.has_what()) {
649         ALOGE("cannot find metric id or \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
650         return nullopt;
651     }
652     if (!metric.has_value_field()) {
653         ALOGE("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
654         return nullopt;
655     }
656     std::vector<Matcher> fieldMatchers;
657     translateFieldMatcher(metric.value_field(), &fieldMatchers);
658     if (fieldMatchers.size() < 1) {
659         ALOGE("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
660         return nullopt;
661     }
662 
663     int trackerIndex;
664     if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
665                                               metric.has_dimensions_in_what(),
666                                               allAtomMatchingTrackers, atomMatchingTrackerMap,
667                                               trackerToMetricMap, trackerIndex)) {
668         return nullopt;
669     }
670 
671     sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
672     // If it is pulled atom, it should be simple matcher with one tagId.
673     if (atomMatcher->getAtomIds().size() != 1) {
674         return nullopt;
675     }
676     int atomTagId = *(atomMatcher->getAtomIds().begin());
677     int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
678 
679     int conditionIndex = -1;
680     if (metric.has_condition()) {
681         if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
682                                         metric.links(), allConditionTrackers, conditionIndex,
683                                         conditionToMetricMap)) {
684             return nullopt;
685         }
686     } else if (metric.links_size() > 0) {
687         ALOGE("metrics has a MetricConditionLink but doesn't have a condition");
688         return nullopt;
689     }
690 
691     std::vector<int> slicedStateAtoms;
692     unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
693     if (metric.slice_by_state_size() > 0) {
694         if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
695                                     allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
696             return nullopt;
697         }
698     } else if (metric.state_link_size() > 0) {
699         ALOGE("ValueMetric has a MetricStateLink but doesn't have a sliced state");
700         return nullopt;
701     }
702 
703     // Check that all metric state links are a subset of dimensions_in_what fields.
704     std::vector<Matcher> dimensionsInWhat;
705     translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
706     for (const auto& stateLink : metric.state_link()) {
707         if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
708             ALOGW("ValueMetric's MetricStateLinks must be a subset of the dimensions in what");
709             return nullopt;
710         }
711     }
712 
713     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
714     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
715     if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
716                                           atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
717                                           deactivationAtomTrackerToMetricMap, metricsWithActivation,
718                                           eventActivationMap, eventDeactivationMap)) {
719         return nullopt;
720     }
721 
722     uint64_t metricHash;
723     if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
724         return nullopt;
725     }
726 
727     return {new ValueMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
728                                     metricHash, trackerIndex, matcherWizard, pullTagId, timeBaseNs,
729                                     currentTimeNs, pullerManager, eventActivationMap,
730                                     eventDeactivationMap, slicedStateAtoms, stateGroupMap)};
731 }
732 
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)733 optional<sp<MetricProducer>> createGaugeMetricProducerAndUpdateMetadata(
734         const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseNs,
735         const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
736         const GaugeMetric& metric, const int metricIndex,
737         const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
738         const unordered_map<int64_t, int>& atomMatchingTrackerMap,
739         vector<sp<ConditionTracker>>& allConditionTrackers,
740         const unordered_map<int64_t, int>& conditionTrackerMap,
741         const vector<ConditionState>& initialConditionCache, const sp<ConditionWizard>& wizard,
742         const sp<EventMatcherWizard>& matcherWizard,
743         const unordered_map<int64_t, int>& metricToActivationMap,
744         unordered_map<int, vector<int>>& trackerToMetricMap,
745         unordered_map<int, vector<int>>& conditionToMetricMap,
746         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
747         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
748         vector<int>& metricsWithActivation) {
749     if (!metric.has_id() || !metric.has_what()) {
750         ALOGE("cannot find metric id or \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
751         return nullopt;
752     }
753 
754     if ((!metric.gauge_fields_filter().has_include_all() ||
755          (metric.gauge_fields_filter().include_all() == false)) &&
756         !hasLeafNode(metric.gauge_fields_filter().fields())) {
757         ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
758         return nullopt;
759     }
760     if ((metric.gauge_fields_filter().has_include_all() &&
761          metric.gauge_fields_filter().include_all() == true) &&
762         hasLeafNode(metric.gauge_fields_filter().fields())) {
763         ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
764         return nullopt;
765     }
766 
767     int trackerIndex;
768     if (!handleMetricWithAtomMatchingTrackers(metric.what(), metricIndex,
769                                               metric.has_dimensions_in_what(),
770                                               allAtomMatchingTrackers, atomMatchingTrackerMap,
771                                               trackerToMetricMap, trackerIndex)) {
772         return nullopt;
773     }
774 
775     sp<AtomMatchingTracker> atomMatcher = allAtomMatchingTrackers.at(trackerIndex);
776     // For GaugeMetric atom, it should be simple matcher with one tagId.
777     if (atomMatcher->getAtomIds().size() != 1) {
778         return nullopt;
779     }
780     int atomTagId = *(atomMatcher->getAtomIds().begin());
781     int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
782 
783     int triggerTrackerIndex;
784     int triggerAtomId = -1;
785     if (metric.has_trigger_event()) {
786         if (pullTagId == -1) {
787             ALOGW("Pull atom not specified for trigger");
788             return nullopt;
789         }
790         // trigger_event should be used with FIRST_N_SAMPLES
791         if (metric.sampling_type() != GaugeMetric::FIRST_N_SAMPLES) {
792             ALOGW("Gauge Metric with trigger event must have sampling type FIRST_N_SAMPLES");
793             return nullopt;
794         }
795         if (!handleMetricWithAtomMatchingTrackers(metric.trigger_event(), metricIndex,
796                                                   /*enforceOneAtom=*/true, allAtomMatchingTrackers,
797                                                   atomMatchingTrackerMap, trackerToMetricMap,
798                                                   triggerTrackerIndex)) {
799             return nullopt;
800         }
801         sp<AtomMatchingTracker> triggerAtomMatcher =
802                 allAtomMatchingTrackers.at(triggerTrackerIndex);
803         triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
804     }
805 
806     if (!metric.has_trigger_event() && pullTagId != -1 &&
807         metric.sampling_type() == GaugeMetric::FIRST_N_SAMPLES) {
808         ALOGW("FIRST_N_SAMPLES is only for pushed event or pull_on_trigger");
809         return nullopt;
810     }
811 
812     int conditionIndex = -1;
813     if (metric.has_condition()) {
814         if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
815                                         metric.links(), allConditionTrackers, conditionIndex,
816                                         conditionToMetricMap)) {
817             return nullopt;
818         }
819     } else {
820         if (metric.links_size() > 0) {
821             ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
822             return nullopt;
823         }
824     }
825 
826     unordered_map<int, shared_ptr<Activation>> eventActivationMap;
827     unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
828     if (!handleMetricActivation(config, metric.id(), metricIndex, metricToActivationMap,
829                                 atomMatchingTrackerMap, activationAtomTrackerToMetricMap,
830                                 deactivationAtomTrackerToMetricMap, metricsWithActivation,
831                                 eventActivationMap, eventDeactivationMap)) {
832         return nullopt;
833     }
834 
835     uint64_t metricHash;
836     if (!getMetricProtoHash(config, metric, metric.id(), metricToActivationMap, metricHash)) {
837         return nullopt;
838     }
839 
840     return {new GaugeMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
841                                     metricHash, trackerIndex, matcherWizard, pullTagId,
842                                     triggerAtomId, atomTagId, timeBaseNs, currentTimeNs,
843                                     pullerManager, eventActivationMap, eventDeactivationMap)};
844 }
845 
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)846 optional<sp<AnomalyTracker>> createAnomalyTracker(
847         const Alert& alert, const sp<AlarmMonitor>& anomalyAlarmMonitor,
848         const UpdateStatus& updateStatus, const int64_t currentTimeNs,
849         const unordered_map<int64_t, int>& metricProducerMap,
850         vector<sp<MetricProducer>>& allMetricProducers) {
851     const auto& itr = metricProducerMap.find(alert.metric_id());
852     if (itr == metricProducerMap.end()) {
853         ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
854               (long long)alert.metric_id());
855         return nullopt;
856     }
857     if (!alert.has_trigger_if_sum_gt()) {
858         ALOGW("invalid alert: missing threshold");
859         return nullopt;
860     }
861     if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
862         ALOGW("invalid alert: threshold=%f num_buckets= %d", alert.trigger_if_sum_gt(),
863               alert.num_buckets());
864         return nullopt;
865     }
866     const int metricIndex = itr->second;
867     sp<MetricProducer> metric = allMetricProducers[metricIndex];
868     sp<AnomalyTracker> anomalyTracker =
869             metric->addAnomalyTracker(alert, anomalyAlarmMonitor, updateStatus, currentTimeNs);
870     if (anomalyTracker == nullptr) {
871         // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
872         return nullopt;
873     }
874     return {anomalyTracker};
875 }
876 
initAtomMatchingTrackers(const StatsdConfig & config,const sp<UidMap> & uidMap,unordered_map<int64_t,int> & atomMatchingTrackerMap,vector<sp<AtomMatchingTracker>> & allAtomMatchingTrackers,set<int> & allTagIds)877 bool initAtomMatchingTrackers(const StatsdConfig& config, const sp<UidMap>& uidMap,
878                               unordered_map<int64_t, int>& atomMatchingTrackerMap,
879                               vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
880                               set<int>& allTagIds) {
881     vector<AtomMatcher> matcherConfigs;
882     const int atomMatcherCount = config.atom_matcher_size();
883     matcherConfigs.reserve(atomMatcherCount);
884     allAtomMatchingTrackers.reserve(atomMatcherCount);
885 
886     for (int i = 0; i < atomMatcherCount; i++) {
887         const AtomMatcher& logMatcher = config.atom_matcher(i);
888         sp<AtomMatchingTracker> tracker = createAtomMatchingTracker(logMatcher, i, uidMap);
889         if (tracker == nullptr) {
890             return false;
891         }
892         allAtomMatchingTrackers.push_back(tracker);
893         if (atomMatchingTrackerMap.find(logMatcher.id()) != atomMatchingTrackerMap.end()) {
894             ALOGE("Duplicate AtomMatcher found!");
895             return false;
896         }
897         atomMatchingTrackerMap[logMatcher.id()] = i;
898         matcherConfigs.push_back(logMatcher);
899     }
900 
901     vector<bool> stackTracker2(allAtomMatchingTrackers.size(), false);
902     for (auto& matcher : allAtomMatchingTrackers) {
903         if (!matcher->init(matcherConfigs, allAtomMatchingTrackers, atomMatchingTrackerMap,
904                            stackTracker2)) {
905             return false;
906         }
907         // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
908         const set<int>& tagIds = matcher->getAtomIds();
909         allTagIds.insert(tagIds.begin(), tagIds.end());
910     }
911     return true;
912 }
913 
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)914 bool initConditions(const ConfigKey& key, const StatsdConfig& config,
915                     const unordered_map<int64_t, int>& atomMatchingTrackerMap,
916                     unordered_map<int64_t, int>& conditionTrackerMap,
917                     vector<sp<ConditionTracker>>& allConditionTrackers,
918                     unordered_map<int, std::vector<int>>& trackerToConditionMap,
919                     vector<ConditionState>& initialConditionCache) {
920     vector<Predicate> conditionConfigs;
921     const int conditionTrackerCount = config.predicate_size();
922     conditionConfigs.reserve(conditionTrackerCount);
923     allConditionTrackers.reserve(conditionTrackerCount);
924     initialConditionCache.assign(conditionTrackerCount, ConditionState::kNotEvaluated);
925 
926     for (int i = 0; i < conditionTrackerCount; i++) {
927         const Predicate& condition = config.predicate(i);
928         sp<ConditionTracker> tracker =
929                 createConditionTracker(key, condition, i, atomMatchingTrackerMap);
930         if (tracker == nullptr) {
931             return false;
932         }
933         allConditionTrackers.push_back(tracker);
934         if (conditionTrackerMap.find(condition.id()) != conditionTrackerMap.end()) {
935             ALOGE("Duplicate Predicate found!");
936             return false;
937         }
938         conditionTrackerMap[condition.id()] = i;
939         conditionConfigs.push_back(condition);
940     }
941 
942     vector<bool> stackTracker(allConditionTrackers.size(), false);
943     for (size_t i = 0; i < allConditionTrackers.size(); i++) {
944         auto& conditionTracker = allConditionTrackers[i];
945         if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
946                                     stackTracker, initialConditionCache)) {
947             return false;
948         }
949         for (const int trackerIndex : conditionTracker->getAtomMatchingTrackerIndex()) {
950             auto& conditionList = trackerToConditionMap[trackerIndex];
951             conditionList.push_back(i);
952         }
953     }
954     return true;
955 }
956 
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)957 bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
958                 unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
959                 map<int64_t, uint64_t>& stateProtoHashes) {
960     for (int i = 0; i < config.state_size(); i++) {
961         const State& state = config.state(i);
962         const int64_t stateId = state.id();
963         stateAtomIdMap[stateId] = state.atom_id();
964 
965         string serializedState;
966         if (!state.SerializeToString(&serializedState)) {
967             ALOGE("Unable to serialize state %lld", (long long)stateId);
968             return false;
969         }
970         stateProtoHashes[stateId] = Hash64(serializedState);
971 
972         const StateMap& stateMap = state.map();
973         for (auto group : stateMap.group()) {
974             for (auto value : group.value()) {
975                 allStateGroupMaps[stateId][value] = group.group_id();
976             }
977         }
978     }
979 
980     return true;
981 }
982 
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)983 bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
984                  const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
985                  const unordered_map<int64_t, int>& atomMatchingTrackerMap,
986                  const unordered_map<int64_t, int>& conditionTrackerMap,
987                  const vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
988                  const unordered_map<int64_t, int>& stateAtomIdMap,
989                  const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
990                  vector<sp<ConditionTracker>>& allConditionTrackers,
991                  const vector<ConditionState>& initialConditionCache,
992                  vector<sp<MetricProducer>>& allMetricProducers,
993                  unordered_map<int, vector<int>>& conditionToMetricMap,
994                  unordered_map<int, vector<int>>& trackerToMetricMap,
995                  unordered_map<int64_t, int>& metricMap, std::set<int64_t>& noReportMetricIds,
996                  unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
997                  unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
998                  vector<int>& metricsWithActivation) {
999     sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
1000     sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchingTrackers);
1001     const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
1002                                 config.event_metric_size() + config.gauge_metric_size() +
1003                                 config.value_metric_size();
1004     allMetricProducers.reserve(allMetricsCount);
1005 
1006     // Construct map from metric id to metric activation index. The map will be used to determine
1007     // the metric activation corresponding to a metric.
1008     unordered_map<int64_t, int> metricToActivationMap;
1009     for (int i = 0; i < config.metric_activation_size(); i++) {
1010         const MetricActivation& metricActivation = config.metric_activation(i);
1011         int64_t metricId = metricActivation.metric_id();
1012         if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
1013             ALOGE("Metric %lld has multiple MetricActivations", (long long)metricId);
1014             return false;
1015         }
1016         metricToActivationMap.insert({metricId, i});
1017     }
1018 
1019     // Build MetricProducers for each metric defined in config.
1020     // build CountMetricProducer
1021     for (int i = 0; i < config.count_metric_size(); i++) {
1022         int metricIndex = allMetricProducers.size();
1023         const CountMetric& metric = config.count_metric(i);
1024         metricMap.insert({metric.id(), metricIndex});
1025         optional<sp<MetricProducer>> producer = createCountMetricProducerAndUpdateMetadata(
1026                 key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
1027                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1028                 conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
1029                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1030                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1031                 metricsWithActivation);
1032         if (!producer) {
1033             return false;
1034         }
1035         allMetricProducers.push_back(producer.value());
1036     }
1037 
1038     // build DurationMetricProducer
1039     for (int i = 0; i < config.duration_metric_size(); i++) {
1040         int metricIndex = allMetricProducers.size();
1041         const DurationMetric& metric = config.duration_metric(i);
1042         metricMap.insert({metric.id(), metricIndex});
1043 
1044         optional<sp<MetricProducer>> producer = createDurationMetricProducerAndUpdateMetadata(
1045                 key, config, timeBaseTimeNs, currentTimeNs, metric, metricIndex,
1046                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1047                 conditionTrackerMap, initialConditionCache, wizard, stateAtomIdMap,
1048                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1049                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1050                 metricsWithActivation);
1051         if (!producer) {
1052             return false;
1053         }
1054         allMetricProducers.push_back(producer.value());
1055     }
1056 
1057     // build EventMetricProducer
1058     for (int i = 0; i < config.event_metric_size(); i++) {
1059         int metricIndex = allMetricProducers.size();
1060         const EventMetric& metric = config.event_metric(i);
1061         metricMap.insert({metric.id(), metricIndex});
1062         optional<sp<MetricProducer>> producer = createEventMetricProducerAndUpdateMetadata(
1063                 key, config, timeBaseTimeNs, metric, metricIndex, allAtomMatchingTrackers,
1064                 atomMatchingTrackerMap, allConditionTrackers, conditionTrackerMap,
1065                 initialConditionCache, wizard, metricToActivationMap, trackerToMetricMap,
1066                 conditionToMetricMap, activationAtomTrackerToMetricMap,
1067                 deactivationAtomTrackerToMetricMap, metricsWithActivation);
1068         if (!producer) {
1069             return false;
1070         }
1071         allMetricProducers.push_back(producer.value());
1072     }
1073 
1074     // build ValueMetricProducer
1075     for (int i = 0; i < config.value_metric_size(); i++) {
1076         int metricIndex = allMetricProducers.size();
1077         const ValueMetric& metric = config.value_metric(i);
1078         metricMap.insert({metric.id(), metricIndex});
1079         optional<sp<MetricProducer>> producer = createValueMetricProducerAndUpdateMetadata(
1080                 key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex,
1081                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1082                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard, stateAtomIdMap,
1083                 allStateGroupMaps, metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1084                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1085                 metricsWithActivation);
1086         if (!producer) {
1087             return false;
1088         }
1089         allMetricProducers.push_back(producer.value());
1090     }
1091 
1092     // Gauge metrics.
1093     for (int i = 0; i < config.gauge_metric_size(); i++) {
1094         int metricIndex = allMetricProducers.size();
1095         const GaugeMetric& metric = config.gauge_metric(i);
1096         metricMap.insert({metric.id(), metricIndex});
1097         optional<sp<MetricProducer>> producer = createGaugeMetricProducerAndUpdateMetadata(
1098                 key, config, timeBaseTimeNs, currentTimeNs, pullerManager, metric, metricIndex,
1099                 allAtomMatchingTrackers, atomMatchingTrackerMap, allConditionTrackers,
1100                 conditionTrackerMap, initialConditionCache, wizard, matcherWizard,
1101                 metricToActivationMap, trackerToMetricMap, conditionToMetricMap,
1102                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
1103                 metricsWithActivation);
1104         if (!producer) {
1105             return false;
1106         }
1107         allMetricProducers.push_back(producer.value());
1108     }
1109     for (int i = 0; i < config.no_report_metric_size(); ++i) {
1110         const auto no_report_metric = config.no_report_metric(i);
1111         if (metricMap.find(no_report_metric) == metricMap.end()) {
1112             ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
1113             return false;
1114         }
1115         noReportMetricIds.insert(no_report_metric);
1116     }
1117 
1118     const set<int> whitelistedAtomIds(config.whitelisted_atom_ids().begin(),
1119                                       config.whitelisted_atom_ids().end());
1120     for (const auto& it : allMetricProducers) {
1121         // Register metrics to StateTrackers
1122         for (int atomId : it->getSlicedStateAtoms()) {
1123             // Register listener for non-whitelisted atoms only. Using whitelisted atom as a sliced
1124             // state atom is not allowed.
1125             if (whitelistedAtomIds.find(atomId) == whitelistedAtomIds.end()) {
1126                 StateManager::getInstance().registerListener(atomId, it);
1127             } else {
1128                 return false;
1129             }
1130         }
1131     }
1132     return true;
1133 }
1134 
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)1135 bool initAlerts(const StatsdConfig& config, const int64_t currentTimeNs,
1136                 const unordered_map<int64_t, int>& metricProducerMap,
1137                 unordered_map<int64_t, int>& alertTrackerMap,
1138                 const sp<AlarmMonitor>& anomalyAlarmMonitor,
1139                 vector<sp<MetricProducer>>& allMetricProducers,
1140                 vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
1141     for (int i = 0; i < config.alert_size(); i++) {
1142         const Alert& alert = config.alert(i);
1143         alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
1144         optional<sp<AnomalyTracker>> anomalyTracker =
1145                 createAnomalyTracker(alert, anomalyAlarmMonitor, UpdateStatus::UPDATE_NEW,
1146                                      currentTimeNs, metricProducerMap, allMetricProducers);
1147         if (!anomalyTracker) {
1148             return false;
1149         }
1150         allAnomalyTrackers.push_back(anomalyTracker.value());
1151     }
1152     if (!initSubscribersForSubscriptionType(config, Subscription::ALERT, alertTrackerMap,
1153                                             allAnomalyTrackers)) {
1154         return false;
1155     }
1156     return true;
1157 }
1158 
initAlarms(const StatsdConfig & config,const ConfigKey & key,const sp<AlarmMonitor> & periodicAlarmMonitor,const int64_t timeBaseNs,const int64_t currentTimeNs,vector<sp<AlarmTracker>> & allAlarmTrackers)1159 bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
1160                 const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
1161                 const int64_t currentTimeNs, vector<sp<AlarmTracker>>& allAlarmTrackers) {
1162     unordered_map<int64_t, int> alarmTrackerMap;
1163     int64_t startMillis = timeBaseNs / 1000 / 1000;
1164     int64_t currentTimeMillis = currentTimeNs / 1000 / 1000;
1165     for (int i = 0; i < config.alarm_size(); i++) {
1166         const Alarm& alarm = config.alarm(i);
1167         if (alarm.offset_millis() <= 0) {
1168             ALOGW("Alarm offset_millis should be larger than 0.");
1169             return false;
1170         }
1171         if (alarm.period_millis() <= 0) {
1172             ALOGW("Alarm period_millis should be larger than 0.");
1173             return false;
1174         }
1175         alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
1176         allAlarmTrackers.push_back(
1177                 new AlarmTracker(startMillis, currentTimeMillis, alarm, key, periodicAlarmMonitor));
1178     }
1179     if (!initSubscribersForSubscriptionType(config, Subscription::ALARM, alarmTrackerMap,
1180                                             allAlarmTrackers)) {
1181         return false;
1182     }
1183     return true;
1184 }
1185 
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,set<int> & allTagIds,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)1186 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, const sp<UidMap>& uidMap,
1187                       const sp<StatsPullerManager>& pullerManager,
1188                       const sp<AlarmMonitor>& anomalyAlarmMonitor,
1189                       const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
1190                       const int64_t currentTimeNs, set<int>& allTagIds,
1191                       vector<sp<AtomMatchingTracker>>& allAtomMatchingTrackers,
1192                       unordered_map<int64_t, int>& atomMatchingTrackerMap,
1193                       vector<sp<ConditionTracker>>& allConditionTrackers,
1194                       unordered_map<int64_t, int>& conditionTrackerMap,
1195                       vector<sp<MetricProducer>>& allMetricProducers,
1196                       unordered_map<int64_t, int>& metricProducerMap,
1197                       vector<sp<AnomalyTracker>>& allAnomalyTrackers,
1198                       vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
1199                       unordered_map<int, std::vector<int>>& conditionToMetricMap,
1200                       unordered_map<int, std::vector<int>>& trackerToMetricMap,
1201                       unordered_map<int, std::vector<int>>& trackerToConditionMap,
1202                       unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
1203                       unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
1204                       unordered_map<int64_t, int>& alertTrackerMap,
1205                       vector<int>& metricsWithActivation, map<int64_t, uint64_t>& stateProtoHashes,
1206                       set<int64_t>& noReportMetricIds) {
1207     vector<ConditionState> initialConditionCache;
1208     unordered_map<int64_t, int> stateAtomIdMap;
1209     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
1210 
1211     if (!initAtomMatchingTrackers(config, uidMap, atomMatchingTrackerMap, allAtomMatchingTrackers,
1212                                   allTagIds)) {
1213         ALOGE("initAtomMatchingTrackers failed");
1214         return false;
1215     }
1216     VLOG("initAtomMatchingTrackers succeed...");
1217 
1218     if (!initConditions(key, config, atomMatchingTrackerMap, conditionTrackerMap,
1219                         allConditionTrackers, trackerToConditionMap, initialConditionCache)) {
1220         ALOGE("initConditionTrackers failed");
1221         return false;
1222     }
1223 
1224     if (!initStates(config, stateAtomIdMap, allStateGroupMaps, stateProtoHashes)) {
1225         ALOGE("initStates failed");
1226         return false;
1227     }
1228     if (!initMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager, atomMatchingTrackerMap,
1229                      conditionTrackerMap, allAtomMatchingTrackers, stateAtomIdMap,
1230                      allStateGroupMaps, allConditionTrackers, initialConditionCache,
1231                      allMetricProducers, conditionToMetricMap, trackerToMetricMap,
1232                      metricProducerMap, noReportMetricIds, activationAtomTrackerToMetricMap,
1233                      deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
1234         ALOGE("initMetricProducers failed");
1235         return false;
1236     }
1237     if (!initAlerts(config, currentTimeNs, metricProducerMap, alertTrackerMap, anomalyAlarmMonitor,
1238                     allMetricProducers, allAnomalyTrackers)) {
1239         ALOGE("initAlerts failed");
1240         return false;
1241     }
1242     if (!initAlarms(config, key, periodicAlarmMonitor, timeBaseNs, currentTimeNs,
1243                     allPeriodicAlarmTrackers)) {
1244         ALOGE("initAlarms failed");
1245         return false;
1246     }
1247 
1248     return true;
1249 }
1250 
1251 }  // namespace statsd
1252 }  // namespace os
1253 }  // namespace android
1254