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 "MetricProducer.h"
26 #include "condition/CombinationConditionTracker.h"
27 #include "condition/SimpleConditionTracker.h"
28 #include "external/StatsPullerManager.h"
29 #include "matchers/CombinationLogMatchingTracker.h"
30 #include "matchers/EventMatcherWizard.h"
31 #include "matchers/SimpleLogMatchingTracker.h"
32 #include "metrics/CountMetricProducer.h"
33 #include "metrics/DurationMetricProducer.h"
34 #include "metrics/EventMetricProducer.h"
35 #include "metrics/GaugeMetricProducer.h"
36 #include "metrics/ValueMetricProducer.h"
37 #include "state/StateManager.h"
38 #include "stats_util.h"
39 
40 using std::set;
41 using std::unordered_map;
42 using std::vector;
43 
44 namespace android {
45 namespace os {
46 namespace statsd {
47 
48 namespace {
49 
hasLeafNode(const FieldMatcher & matcher)50 bool hasLeafNode(const FieldMatcher& matcher) {
51     if (!matcher.has_field()) {
52         return false;
53     }
54     for (int i = 0; i < matcher.child_size(); ++i) {
55         if (hasLeafNode(matcher.child(i))) {
56             return true;
57         }
58     }
59     return true;
60 }
61 
62 }  // namespace
63 
handleMetricWithLogTrackers(const int64_t what,const int metricIndex,const bool usedForDimension,const vector<sp<LogMatchingTracker>> & allAtomMatchers,const unordered_map<int64_t,int> & logTrackerMap,unordered_map<int,std::vector<int>> & trackerToMetricMap,int & logTrackerIndex)64 bool handleMetricWithLogTrackers(const int64_t what, const int metricIndex,
65                                  const bool usedForDimension,
66                                  const vector<sp<LogMatchingTracker>>& allAtomMatchers,
67                                  const unordered_map<int64_t, int>& logTrackerMap,
68                                  unordered_map<int, std::vector<int>>& trackerToMetricMap,
69                                  int& logTrackerIndex) {
70     auto logTrackerIt = logTrackerMap.find(what);
71     if (logTrackerIt == logTrackerMap.end()) {
72         ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)what);
73         return false;
74     }
75     if (usedForDimension && allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
76         ALOGE("AtomMatcher \"%lld\" has more than one tag ids. When a metric has dimension, "
77               "the \"what\" can only about one atom type.",
78               (long long)what);
79         return false;
80     }
81     logTrackerIndex = logTrackerIt->second;
82     auto& metric_list = trackerToMetricMap[logTrackerIndex];
83     metric_list.push_back(metricIndex);
84     return true;
85 }
86 
handlePullMetricTriggerWithLogTrackers(const int64_t trigger,const int metricIndex,const vector<sp<LogMatchingTracker>> & allAtomMatchers,const unordered_map<int64_t,int> & logTrackerMap,unordered_map<int,std::vector<int>> & trackerToMetricMap,int & logTrackerIndex)87 bool handlePullMetricTriggerWithLogTrackers(
88         const int64_t trigger, const int metricIndex,
89         const vector<sp<LogMatchingTracker>>& allAtomMatchers,
90         const unordered_map<int64_t, int>& logTrackerMap,
91         unordered_map<int, std::vector<int>>& trackerToMetricMap, int& logTrackerIndex) {
92     auto logTrackerIt = logTrackerMap.find(trigger);
93     if (logTrackerIt == logTrackerMap.end()) {
94         ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)trigger);
95         return false;
96     }
97     if (allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
98         ALOGE("AtomMatcher \"%lld\" has more than one tag ids."
99               "Trigger can only be one atom type.",
100               (long long)trigger);
101         return false;
102     }
103     logTrackerIndex = logTrackerIt->second;
104     auto& metric_list = trackerToMetricMap[logTrackerIndex];
105     metric_list.push_back(metricIndex);
106     return true;
107 }
108 
handleMetricWithConditions(const int64_t condition,const int metricIndex,const unordered_map<int64_t,int> & conditionTrackerMap,const::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink> & links,vector<sp<ConditionTracker>> & allConditionTrackers,int & conditionIndex,unordered_map<int,std::vector<int>> & conditionToMetricMap)109 bool handleMetricWithConditions(
110         const int64_t condition, const int metricIndex,
111         const unordered_map<int64_t, int>& conditionTrackerMap,
112         const ::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink>&
113                 links,
114         vector<sp<ConditionTracker>>& allConditionTrackers, int& conditionIndex,
115         unordered_map<int, std::vector<int>>& conditionToMetricMap) {
116     auto condition_it = conditionTrackerMap.find(condition);
117     if (condition_it == conditionTrackerMap.end()) {
118         ALOGW("cannot find Predicate \"%lld\" in the config", (long long)condition);
119         return false;
120     }
121 
122     for (const auto& link : links) {
123         auto it = conditionTrackerMap.find(link.condition());
124         if (it == conditionTrackerMap.end()) {
125             ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
126             return false;
127         }
128         allConditionTrackers[condition_it->second]->setSliced(true);
129         allConditionTrackers[it->second]->setSliced(true);
130     }
131     conditionIndex = condition_it->second;
132 
133     // will create new vector if not exist before.
134     auto& metricList = conditionToMetricMap[condition_it->second];
135     metricList.push_back(metricIndex);
136     return true;
137 }
138 
139 // Initializes state data structures for a metric.
140 // input:
141 // [config]: the input config
142 // [stateIds]: the slice_by_state ids for this metric
143 // [stateAtomIdMap]: this map contains the mapping from all state ids to atom ids
144 // [allStateGroupMaps]: this map contains the mapping from state ids and state
145 //                      values to state group ids for all states
146 // output:
147 // [slicedStateAtoms]: a vector of atom ids of all the slice_by_states
148 // [stateGroupMap]: this map should contain the mapping from states ids and state
149 //                      values to state group ids for all states that this metric
150 //                      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)151 bool handleMetricWithStates(
152         const StatsdConfig& config, const ::google::protobuf::RepeatedField<int64_t>& stateIds,
153         const unordered_map<int64_t, int>& stateAtomIdMap,
154         const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
155         vector<int>& slicedStateAtoms,
156         unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap) {
157     for (const auto& stateId : stateIds) {
158         auto it = stateAtomIdMap.find(stateId);
159         if (it == stateAtomIdMap.end()) {
160             ALOGW("cannot find State %" PRId64 " in the config", stateId);
161             return false;
162         }
163         int atomId = it->second;
164         slicedStateAtoms.push_back(atomId);
165 
166         auto stateIt = allStateGroupMaps.find(stateId);
167         if (stateIt != allStateGroupMaps.end()) {
168             stateGroupMap[atomId] = stateIt->second;
169         }
170     }
171     return true;
172 }
173 
handleMetricWithStateLink(const FieldMatcher & stateMatcher,const vector<Matcher> & dimensionsInWhat)174 bool handleMetricWithStateLink(const FieldMatcher& stateMatcher,
175                                const vector<Matcher>& dimensionsInWhat) {
176     vector<Matcher> stateMatchers;
177     translateFieldMatcher(stateMatcher, &stateMatchers);
178 
179     return subsetDimensions(stateMatchers, dimensionsInWhat);
180 }
181 
182 // Validates a metricActivation and populates state.
183 // EventActivationMap and EventDeactivationMap are supplied to a MetricProducer
184 //      to provide the producer with state about its activators and deactivators.
185 // 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> & logTrackerMap,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)186 bool handleMetricActivation(
187         const StatsdConfig& config,
188         const int64_t metricId,
189         const int metricIndex,
190         const unordered_map<int64_t, int>& metricToActivationMap,
191         const unordered_map<int64_t, int>& logTrackerMap,
192         unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
193         unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
194         vector<int>& metricsWithActivation,
195         unordered_map<int, shared_ptr<Activation>>& eventActivationMap,
196         unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap) {
197     // Check if metric has an associated activation
198     auto itr = metricToActivationMap.find(metricId);
199     if (itr == metricToActivationMap.end()) return true;
200 
201     int activationIndex = itr->second;
202     const MetricActivation& metricActivation = config.metric_activation(activationIndex);
203 
204     for (int i = 0; i < metricActivation.event_activation_size(); i++) {
205         const EventActivation& activation = metricActivation.event_activation(i);
206 
207         auto itr = logTrackerMap.find(activation.atom_matcher_id());
208         if (itr == logTrackerMap.end()) {
209             ALOGE("Atom matcher not found for event activation.");
210             return false;
211         }
212 
213         ActivationType activationType = (activation.has_activation_type()) ?
214                 activation.activation_type() : metricActivation.activation_type();
215         std::shared_ptr<Activation> activationWrapper = std::make_shared<Activation>(
216                 activationType, activation.ttl_seconds() * NS_PER_SEC);
217 
218         int atomMatcherIndex = itr->second;
219         activationAtomTrackerToMetricMap[atomMatcherIndex].push_back(metricIndex);
220         eventActivationMap.emplace(atomMatcherIndex, activationWrapper);
221 
222         if (activation.has_deactivation_atom_matcher_id()) {
223             itr = logTrackerMap.find(activation.deactivation_atom_matcher_id());
224             if (itr == logTrackerMap.end()) {
225                 ALOGE("Atom matcher not found for event deactivation.");
226                 return false;
227             }
228             int deactivationAtomMatcherIndex = itr->second;
229             deactivationAtomTrackerToMetricMap[deactivationAtomMatcherIndex].push_back(metricIndex);
230             eventDeactivationMap[deactivationAtomMatcherIndex].push_back(activationWrapper);
231         }
232     }
233 
234     metricsWithActivation.push_back(metricIndex);
235     return true;
236 }
237 
initLogTrackers(const StatsdConfig & config,const UidMap & uidMap,unordered_map<int64_t,int> & logTrackerMap,vector<sp<LogMatchingTracker>> & allAtomMatchers,set<int> & allTagIds)238 bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap,
239                      unordered_map<int64_t, int>& logTrackerMap,
240                      vector<sp<LogMatchingTracker>>& allAtomMatchers, set<int>& allTagIds) {
241     vector<AtomMatcher> matcherConfigs;
242     const int atomMatcherCount = config.atom_matcher_size();
243     matcherConfigs.reserve(atomMatcherCount);
244     allAtomMatchers.reserve(atomMatcherCount);
245 
246     for (int i = 0; i < atomMatcherCount; i++) {
247         const AtomMatcher& logMatcher = config.atom_matcher(i);
248 
249         int index = allAtomMatchers.size();
250         switch (logMatcher.contents_case()) {
251             case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
252                 allAtomMatchers.push_back(new SimpleLogMatchingTracker(
253                         logMatcher.id(), index, logMatcher.simple_atom_matcher(), uidMap));
254                 break;
255             case AtomMatcher::ContentsCase::kCombination:
256                 allAtomMatchers.push_back(
257                         new CombinationLogMatchingTracker(logMatcher.id(), index));
258                 break;
259             default:
260                 ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
261                 return false;
262                 // continue;
263         }
264         if (logTrackerMap.find(logMatcher.id()) != logTrackerMap.end()) {
265             ALOGE("Duplicate AtomMatcher found!");
266             return false;
267         }
268         logTrackerMap[logMatcher.id()] = index;
269         matcherConfigs.push_back(logMatcher);
270     }
271 
272     vector<bool> stackTracker2(allAtomMatchers.size(), false);
273     for (auto& matcher : allAtomMatchers) {
274         if (!matcher->init(matcherConfigs, allAtomMatchers, logTrackerMap, stackTracker2)) {
275             return false;
276         }
277         // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
278         const set<int>& tagIds = matcher->getAtomIds();
279         allTagIds.insert(tagIds.begin(), tagIds.end());
280     }
281     return true;
282 }
283 
initConditions(const ConfigKey & key,const StatsdConfig & config,const unordered_map<int64_t,int> & logTrackerMap,unordered_map<int64_t,int> & conditionTrackerMap,vector<sp<ConditionTracker>> & allConditionTrackers,unordered_map<int,std::vector<int>> & trackerToConditionMap,vector<ConditionState> & initialConditionCache)284 bool initConditions(const ConfigKey& key, const StatsdConfig& config,
285                     const unordered_map<int64_t, int>& logTrackerMap,
286                     unordered_map<int64_t, int>& conditionTrackerMap,
287                     vector<sp<ConditionTracker>>& allConditionTrackers,
288                     unordered_map<int, std::vector<int>>& trackerToConditionMap,
289                     vector<ConditionState>& initialConditionCache) {
290     vector<Predicate> conditionConfigs;
291     const int conditionTrackerCount = config.predicate_size();
292     conditionConfigs.reserve(conditionTrackerCount);
293     allConditionTrackers.reserve(conditionTrackerCount);
294     initialConditionCache.reserve(conditionTrackerCount);
295     std::fill(initialConditionCache.begin(), initialConditionCache.end(), ConditionState::kUnknown);
296 
297     for (int i = 0; i < conditionTrackerCount; i++) {
298         const Predicate& condition = config.predicate(i);
299         int index = allConditionTrackers.size();
300         switch (condition.contents_case()) {
301             case Predicate::ContentsCase::kSimplePredicate: {
302                 allConditionTrackers.push_back(new SimpleConditionTracker(
303                         key, condition.id(), index, condition.simple_predicate(), logTrackerMap));
304                 break;
305             }
306             case Predicate::ContentsCase::kCombination: {
307                 allConditionTrackers.push_back(
308                         new CombinationConditionTracker(condition.id(), index));
309                 break;
310             }
311             default:
312                 ALOGE("Predicate \"%lld\" malformed", (long long)condition.id());
313                 return false;
314         }
315         if (conditionTrackerMap.find(condition.id()) != conditionTrackerMap.end()) {
316             ALOGE("Duplicate Predicate found!");
317             return false;
318         }
319         conditionTrackerMap[condition.id()] = index;
320         conditionConfigs.push_back(condition);
321     }
322 
323     vector<bool> stackTracker(allConditionTrackers.size(), false);
324     for (size_t i = 0; i < allConditionTrackers.size(); i++) {
325         auto& conditionTracker = allConditionTrackers[i];
326         if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
327                                     stackTracker, initialConditionCache)) {
328             return false;
329         }
330         for (const int trackerIndex : conditionTracker->getLogTrackerIndex()) {
331             auto& conditionList = trackerToConditionMap[trackerIndex];
332             conditionList.push_back(i);
333         }
334     }
335     return true;
336 }
337 
initStates(const StatsdConfig & config,unordered_map<int64_t,int> & stateAtomIdMap,unordered_map<int64_t,unordered_map<int,int64_t>> & allStateGroupMaps)338 bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
339                 unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps) {
340     for (int i = 0; i < config.state_size(); i++) {
341         const State& state = config.state(i);
342         const int64_t stateId = state.id();
343         stateAtomIdMap[stateId] = state.atom_id();
344 
345         const StateMap& stateMap = state.map();
346         for (auto group : stateMap.group()) {
347             for (auto value : group.value()) {
348                 allStateGroupMaps[stateId][value] = group.group_id();
349             }
350         }
351     }
352 
353     return true;
354 }
355 
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> & logTrackerMap,const unordered_map<int64_t,int> & conditionTrackerMap,const vector<sp<LogMatchingTracker>> & allAtomMatchers,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)356 bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
357                  const int64_t currentTimeNs, const sp<StatsPullerManager>& pullerManager,
358                  const unordered_map<int64_t, int>& logTrackerMap,
359                  const unordered_map<int64_t, int>& conditionTrackerMap,
360                  const vector<sp<LogMatchingTracker>>& allAtomMatchers,
361                  const unordered_map<int64_t, int>& stateAtomIdMap,
362                  const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
363                  vector<sp<ConditionTracker>>& allConditionTrackers,
364                  const vector<ConditionState>& initialConditionCache,
365                  vector<sp<MetricProducer>>& allMetricProducers,
366                  unordered_map<int, vector<int>>& conditionToMetricMap,
367                  unordered_map<int, vector<int>>& trackerToMetricMap,
368                  unordered_map<int64_t, int>& metricMap, std::set<int64_t>& noReportMetricIds,
369                  unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
370                  unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
371                  vector<int>& metricsWithActivation) {
372     sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
373     sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchers);
374     const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
375                                 config.event_metric_size() + config.gauge_metric_size() +
376                                 config.value_metric_size();
377     allMetricProducers.reserve(allMetricsCount);
378 
379     // Construct map from metric id to metric activation index. The map will be used to determine
380     // the metric activation corresponding to a metric.
381     unordered_map<int64_t, int> metricToActivationMap;
382     for (int i = 0; i < config.metric_activation_size(); i++) {
383         const MetricActivation& metricActivation = config.metric_activation(i);
384         int64_t metricId = metricActivation.metric_id();
385         if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
386             ALOGE("Metric %lld has multiple MetricActivations", (long long) metricId);
387             return false;
388         }
389         metricToActivationMap.insert({metricId, i});
390     }
391 
392     // Build MetricProducers for each metric defined in config.
393     // build CountMetricProducer
394     for (int i = 0; i < config.count_metric_size(); i++) {
395         const CountMetric& metric = config.count_metric(i);
396         if (!metric.has_what()) {
397             ALOGW("cannot find \"what\" in CountMetric \"%lld\"", (long long)metric.id());
398             return false;
399         }
400 
401         int metricIndex = allMetricProducers.size();
402         metricMap.insert({metric.id(), metricIndex});
403         int trackerIndex;
404         if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
405                                          metric.has_dimensions_in_what(),
406                                          allAtomMatchers, logTrackerMap, trackerToMetricMap,
407                                          trackerIndex)) {
408             return false;
409         }
410 
411         int conditionIndex = -1;
412         if (metric.has_condition()) {
413             if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
414                                             metric.links(), allConditionTrackers, conditionIndex,
415                                             conditionToMetricMap)) {
416                 return false;
417             }
418         } else {
419             if (metric.links_size() > 0) {
420                 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
421                 return false;
422             }
423         }
424 
425         std::vector<int> slicedStateAtoms;
426         unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
427         if (metric.slice_by_state_size() > 0) {
428             if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
429                                         allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
430                 return false;
431             }
432         } else {
433             if (metric.state_link_size() > 0) {
434                 ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
435                 return false;
436             }
437         }
438 
439         unordered_map<int, shared_ptr<Activation>> eventActivationMap;
440         unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
441         bool success = handleMetricActivation(config, metric.id(), metricIndex,
442                 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
443                 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
444                 eventDeactivationMap);
445         if (!success) return false;
446 
447         sp<MetricProducer> countProducer =
448                 new CountMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
449                                         timeBaseTimeNs, currentTimeNs, eventActivationMap,
450                                         eventDeactivationMap, slicedStateAtoms, stateGroupMap);
451         allMetricProducers.push_back(countProducer);
452     }
453 
454     // build DurationMetricProducer
455     for (int i = 0; i < config.duration_metric_size(); i++) {
456         int metricIndex = allMetricProducers.size();
457         const DurationMetric& metric = config.duration_metric(i);
458         metricMap.insert({metric.id(), metricIndex});
459 
460         auto what_it = conditionTrackerMap.find(metric.what());
461         if (what_it == conditionTrackerMap.end()) {
462             ALOGE("DurationMetric's \"what\" is invalid");
463             return false;
464         }
465 
466         const Predicate& durationWhat = config.predicate(what_it->second);
467 
468         if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
469             ALOGE("DurationMetric's \"what\" must be a simple condition");
470             return false;
471         }
472 
473         const auto& simplePredicate = durationWhat.simple_predicate();
474 
475         bool nesting = simplePredicate.count_nesting();
476 
477         int trackerIndices[3] = {-1, -1, -1};
478         if (!simplePredicate.has_start() ||
479             !handleMetricWithLogTrackers(simplePredicate.start(), metricIndex,
480                                          metric.has_dimensions_in_what(), allAtomMatchers,
481                                          logTrackerMap, trackerToMetricMap, trackerIndices[0])) {
482             ALOGE("Duration metrics must specify a valid the start event matcher");
483             return false;
484         }
485 
486         if (simplePredicate.has_stop() &&
487             !handleMetricWithLogTrackers(simplePredicate.stop(), metricIndex,
488                                          metric.has_dimensions_in_what(), allAtomMatchers,
489                                          logTrackerMap, trackerToMetricMap, trackerIndices[1])) {
490             return false;
491         }
492 
493         if (simplePredicate.has_stop_all() &&
494             !handleMetricWithLogTrackers(simplePredicate.stop_all(), metricIndex,
495                                          metric.has_dimensions_in_what(), allAtomMatchers,
496                                          logTrackerMap, trackerToMetricMap, trackerIndices[2])) {
497             return false;
498         }
499 
500         FieldMatcher internalDimensions = simplePredicate.dimensions();
501 
502         int conditionIndex = -1;
503 
504         if (metric.has_condition()) {
505             bool good = handleMetricWithConditions(
506                     metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
507                     allConditionTrackers, conditionIndex, conditionToMetricMap);
508             if (!good) {
509                 return false;
510             }
511         } else {
512             if (metric.links_size() > 0) {
513                 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
514                 return false;
515             }
516         }
517 
518         std::vector<int> slicedStateAtoms;
519         unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
520         if (metric.slice_by_state_size() > 0) {
521             if (metric.aggregation_type() == DurationMetric::MAX_SPARSE) {
522                 ALOGE("DurationMetric with aggregation type MAX_SPARSE cannot be sliced by state");
523                 return false;
524             }
525             if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
526                                         allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
527                 return false;
528             }
529         } else {
530             if (metric.state_link_size() > 0) {
531                 ALOGW("DurationMetric has a MetricStateLink but doesn't have a sliced state");
532                 return false;
533             }
534         }
535 
536         // Check that all metric state links are a subset of dimensions_in_what fields.
537         std::vector<Matcher> dimensionsInWhat;
538         translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
539         for (const auto& stateLink : metric.state_link()) {
540             if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
541                 return false;
542             }
543         }
544 
545         unordered_map<int, shared_ptr<Activation>> eventActivationMap;
546         unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
547         bool success = handleMetricActivation(config, metric.id(), metricIndex,
548                 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
549                 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
550                 eventDeactivationMap);
551         if (!success) return false;
552 
553         sp<MetricProducer> durationMetric = new DurationMetricProducer(
554                 key, metric, conditionIndex, initialConditionCache, trackerIndices[0],
555                 trackerIndices[1], trackerIndices[2], nesting, wizard, internalDimensions,
556                 timeBaseTimeNs, currentTimeNs, eventActivationMap, eventDeactivationMap,
557                 slicedStateAtoms, stateGroupMap);
558 
559         allMetricProducers.push_back(durationMetric);
560     }
561 
562     // build EventMetricProducer
563     for (int i = 0; i < config.event_metric_size(); i++) {
564         int metricIndex = allMetricProducers.size();
565         const EventMetric& metric = config.event_metric(i);
566         metricMap.insert({metric.id(), metricIndex});
567         if (!metric.has_id() || !metric.has_what()) {
568             ALOGW("cannot find the metric name or what in config");
569             return false;
570         }
571         int trackerIndex;
572         if (!handleMetricWithLogTrackers(metric.what(), metricIndex, false, allAtomMatchers,
573                                          logTrackerMap, trackerToMetricMap, trackerIndex)) {
574             return false;
575         }
576 
577         int conditionIndex = -1;
578         if (metric.has_condition()) {
579             bool good = handleMetricWithConditions(
580                     metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
581                     allConditionTrackers, conditionIndex, conditionToMetricMap);
582             if (!good) {
583                 return false;
584             }
585         } else {
586             if (metric.links_size() > 0) {
587                 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
588                 return false;
589             }
590         }
591 
592         unordered_map<int, shared_ptr<Activation>> eventActivationMap;
593         unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
594         bool success = handleMetricActivation(config, metric.id(), metricIndex,
595                 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
596                 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
597                 eventDeactivationMap);
598         if (!success) return false;
599 
600         sp<MetricProducer> eventMetric =
601                 new EventMetricProducer(key, metric, conditionIndex, initialConditionCache, wizard,
602                                         timeBaseTimeNs, eventActivationMap, eventDeactivationMap);
603 
604         allMetricProducers.push_back(eventMetric);
605     }
606 
607     // build ValueMetricProducer
608     for (int i = 0; i < config.value_metric_size(); i++) {
609         const ValueMetric& metric = config.value_metric(i);
610         if (!metric.has_what()) {
611             ALOGW("cannot find \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
612             return false;
613         }
614         if (!metric.has_value_field()) {
615             ALOGW("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
616             return false;
617         }
618         std::vector<Matcher> fieldMatchers;
619         translateFieldMatcher(metric.value_field(), &fieldMatchers);
620         if (fieldMatchers.size() < 1) {
621             ALOGW("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
622             return false;
623         }
624 
625         int metricIndex = allMetricProducers.size();
626         metricMap.insert({metric.id(), metricIndex});
627         int trackerIndex;
628         if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
629                                          metric.has_dimensions_in_what(),
630                                          allAtomMatchers, logTrackerMap, trackerToMetricMap,
631                                          trackerIndex)) {
632             return false;
633         }
634 
635         sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
636         // If it is pulled atom, it should be simple matcher with one tagId.
637         if (atomMatcher->getAtomIds().size() != 1) {
638             return false;
639         }
640         int atomTagId = *(atomMatcher->getAtomIds().begin());
641         int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
642 
643         int conditionIndex = -1;
644         if (metric.has_condition()) {
645             bool good = handleMetricWithConditions(
646                     metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
647                     allConditionTrackers, conditionIndex, conditionToMetricMap);
648             if (!good) {
649                 return false;
650             }
651         } else {
652             if (metric.links_size() > 0) {
653                 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
654                 return false;
655             }
656         }
657 
658         std::vector<int> slicedStateAtoms;
659         unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
660         if (metric.slice_by_state_size() > 0) {
661             if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
662                                         allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
663                 return false;
664             }
665         } else {
666             if (metric.state_link_size() > 0) {
667                 ALOGW("ValueMetric has a MetricStateLink but doesn't have a sliced state");
668                 return false;
669             }
670         }
671 
672         // Check that all metric state links are a subset of dimensions_in_what fields.
673         std::vector<Matcher> dimensionsInWhat;
674         translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
675         for (const auto& stateLink : metric.state_link()) {
676             if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
677                 return false;
678             }
679         }
680 
681         unordered_map<int, shared_ptr<Activation>> eventActivationMap;
682         unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
683         bool success = handleMetricActivation(
684                 config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
685                 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
686                 metricsWithActivation, eventActivationMap, eventDeactivationMap);
687         if (!success) return false;
688 
689         sp<MetricProducer> valueProducer = new ValueMetricProducer(
690                 key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
691                 matcherWizard, pullTagId, timeBaseTimeNs, currentTimeNs, pullerManager,
692                 eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap);
693         allMetricProducers.push_back(valueProducer);
694     }
695 
696     // Gauge metrics.
697     for (int i = 0; i < config.gauge_metric_size(); i++) {
698         const GaugeMetric& metric = config.gauge_metric(i);
699         if (!metric.has_what()) {
700             ALOGW("cannot find \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
701             return false;
702         }
703 
704         if ((!metric.gauge_fields_filter().has_include_all() ||
705              (metric.gauge_fields_filter().include_all() == false)) &&
706             !hasLeafNode(metric.gauge_fields_filter().fields())) {
707             ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
708             return false;
709         }
710         if ((metric.gauge_fields_filter().has_include_all() &&
711              metric.gauge_fields_filter().include_all() == true) &&
712             hasLeafNode(metric.gauge_fields_filter().fields())) {
713             ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
714             return false;
715         }
716 
717         int metricIndex = allMetricProducers.size();
718         metricMap.insert({metric.id(), metricIndex});
719         int trackerIndex;
720         if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
721                                          metric.has_dimensions_in_what(),
722                                          allAtomMatchers, logTrackerMap, trackerToMetricMap,
723                                          trackerIndex)) {
724             return false;
725         }
726 
727         sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
728         // For GaugeMetric atom, it should be simple matcher with one tagId.
729         if (atomMatcher->getAtomIds().size() != 1) {
730             return false;
731         }
732         int atomTagId = *(atomMatcher->getAtomIds().begin());
733         int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
734 
735         int triggerTrackerIndex;
736         int triggerAtomId = -1;
737         if (metric.has_trigger_event()) {
738             if (pullTagId == -1) {
739                 ALOGW("Pull atom not specified for trigger");
740                 return false;
741             }
742             // event_trigger should be used with FIRST_N_SAMPLES
743             if (metric.sampling_type() != GaugeMetric::FIRST_N_SAMPLES) {
744                 return false;
745             }
746             if (!handlePullMetricTriggerWithLogTrackers(metric.trigger_event(), metricIndex,
747                                                         allAtomMatchers, logTrackerMap,
748                                                         trackerToMetricMap, triggerTrackerIndex)) {
749                 return false;
750             }
751             sp<LogMatchingTracker> triggerAtomMatcher = allAtomMatchers.at(triggerTrackerIndex);
752             triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
753         }
754 
755         if (!metric.has_trigger_event() && pullTagId != -1 &&
756             metric.sampling_type() == GaugeMetric::FIRST_N_SAMPLES) {
757             ALOGW("FIRST_N_SAMPLES is only for pushed event or pull_on_trigger");
758             return false;
759         }
760 
761         int conditionIndex = -1;
762         if (metric.has_condition()) {
763             bool good = handleMetricWithConditions(
764                     metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
765                     allConditionTrackers, conditionIndex, conditionToMetricMap);
766             if (!good) {
767                 return false;
768             }
769         } else {
770             if (metric.links_size() > 0) {
771                 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
772                 return false;
773             }
774         }
775 
776         unordered_map<int, shared_ptr<Activation>> eventActivationMap;
777         unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
778         bool success = handleMetricActivation(config, metric.id(), metricIndex,
779                 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
780                 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
781                 eventDeactivationMap);
782         if (!success) return false;
783 
784         sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
785                 key, metric, conditionIndex, initialConditionCache, wizard, trackerIndex,
786                 matcherWizard, pullTagId, triggerAtomId, atomTagId, timeBaseTimeNs, currentTimeNs,
787                 pullerManager, eventActivationMap, eventDeactivationMap);
788         allMetricProducers.push_back(gaugeProducer);
789     }
790     for (int i = 0; i < config.no_report_metric_size(); ++i) {
791         const auto no_report_metric = config.no_report_metric(i);
792         if (metricMap.find(no_report_metric) == metricMap.end()) {
793             ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
794             return false;
795         }
796         noReportMetricIds.insert(no_report_metric);
797     }
798 
799     const set<int> whitelistedAtomIds(config.whitelisted_atom_ids().begin(),
800                                       config.whitelisted_atom_ids().end());
801     for (const auto& it : allMetricProducers) {
802         // Register metrics to StateTrackers
803         for (int atomId : it->getSlicedStateAtoms()) {
804             // Register listener for non-whitelisted atoms only. Using whitelisted atom as a sliced
805             // state atom is not allowed.
806             if (whitelistedAtomIds.find(atomId) == whitelistedAtomIds.end()) {
807                 StateManager::getInstance().registerListener(atomId, it);
808             } else {
809                 return false;
810             }
811         }
812     }
813     return true;
814 }
815 
initAlerts(const StatsdConfig & config,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)816 bool initAlerts(const StatsdConfig& config,
817                 const unordered_map<int64_t, int>& metricProducerMap,
818                 unordered_map<int64_t, int>& alertTrackerMap,
819                 const sp<AlarmMonitor>& anomalyAlarmMonitor,
820                 vector<sp<MetricProducer>>& allMetricProducers,
821                 vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
822     for (int i = 0; i < config.alert_size(); i++) {
823         const Alert& alert = config.alert(i);
824         const auto& itr = metricProducerMap.find(alert.metric_id());
825         if (itr == metricProducerMap.end()) {
826             ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
827                   (long long)alert.metric_id());
828             return false;
829         }
830         if (!alert.has_trigger_if_sum_gt()) {
831             ALOGW("invalid alert: missing threshold");
832             return false;
833         }
834         if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
835             ALOGW("invalid alert: threshold=%f num_buckets= %d",
836                   alert.trigger_if_sum_gt(), alert.num_buckets());
837             return false;
838         }
839         const int metricIndex = itr->second;
840         sp<MetricProducer> metric = allMetricProducers[metricIndex];
841         sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
842         if (anomalyTracker == nullptr) {
843             // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
844             return false;
845         }
846         alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
847         allAnomalyTrackers.push_back(anomalyTracker);
848     }
849     for (int i = 0; i < config.subscription_size(); ++i) {
850         const Subscription& subscription = config.subscription(i);
851         if (subscription.rule_type() != Subscription::ALERT) {
852             continue;
853         }
854         if (subscription.subscriber_information_case() ==
855             Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
856             ALOGW("subscription \"%lld\" has no subscriber info.\"",
857                 (long long)subscription.id());
858             return false;
859         }
860         const auto& itr = alertTrackerMap.find(subscription.rule_id());
861         if (itr == alertTrackerMap.end()) {
862             ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
863                 (long long)subscription.id(), (long long)subscription.rule_id());
864             return false;
865         }
866         const int anomalyTrackerIndex = itr->second;
867         allAnomalyTrackers[anomalyTrackerIndex]->addSubscription(subscription);
868     }
869     return true;
870 }
871 
initAlarms(const StatsdConfig & config,const ConfigKey & key,const sp<AlarmMonitor> & periodicAlarmMonitor,const int64_t timeBaseNs,const int64_t currentTimeNs,vector<sp<AlarmTracker>> & allAlarmTrackers)872 bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
873                 const sp<AlarmMonitor>& periodicAlarmMonitor,
874                 const int64_t timeBaseNs, const int64_t currentTimeNs,
875                 vector<sp<AlarmTracker>>& allAlarmTrackers) {
876     unordered_map<int64_t, int> alarmTrackerMap;
877     int64_t startMillis = timeBaseNs / 1000 / 1000;
878     int64_t currentTimeMillis = currentTimeNs / 1000 /1000;
879     for (int i = 0; i < config.alarm_size(); i++) {
880         const Alarm& alarm = config.alarm(i);
881         if (alarm.offset_millis() <= 0) {
882             ALOGW("Alarm offset_millis should be larger than 0.");
883             return false;
884         }
885         if (alarm.period_millis() <= 0) {
886             ALOGW("Alarm period_millis should be larger than 0.");
887             return false;
888         }
889         alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
890         allAlarmTrackers.push_back(
891             new AlarmTracker(startMillis, currentTimeMillis,
892                              alarm, key, periodicAlarmMonitor));
893     }
894     for (int i = 0; i < config.subscription_size(); ++i) {
895         const Subscription& subscription = config.subscription(i);
896         if (subscription.rule_type() != Subscription::ALARM) {
897             continue;
898         }
899         if (subscription.subscriber_information_case() ==
900             Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
901             ALOGW("subscription \"%lld\" has no subscriber info.\"",
902                 (long long)subscription.id());
903             return false;
904         }
905         const auto& itr = alarmTrackerMap.find(subscription.rule_id());
906         if (itr == alarmTrackerMap.end()) {
907             ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
908                 (long long)subscription.id(), (long long)subscription.rule_id());
909             return false;
910         }
911         const int trackerIndex = itr->second;
912         allAlarmTrackers[trackerIndex]->addSubscription(subscription);
913     }
914     return true;
915 }
916 
initStatsdConfig(const ConfigKey & key,const StatsdConfig & config,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<LogMatchingTracker>> & allAtomMatchers,vector<sp<ConditionTracker>> & allConditionTrackers,vector<sp<MetricProducer>> & allMetricProducers,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,std::set<int64_t> & noReportMetricIds)917 bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
918                       const sp<StatsPullerManager>& pullerManager,
919                       const sp<AlarmMonitor>& anomalyAlarmMonitor,
920                       const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
921                       const int64_t currentTimeNs, set<int>& allTagIds,
922                       vector<sp<LogMatchingTracker>>& allAtomMatchers,
923                       vector<sp<ConditionTracker>>& allConditionTrackers,
924                       vector<sp<MetricProducer>>& allMetricProducers,
925                       vector<sp<AnomalyTracker>>& allAnomalyTrackers,
926                       vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
927                       unordered_map<int, std::vector<int>>& conditionToMetricMap,
928                       unordered_map<int, std::vector<int>>& trackerToMetricMap,
929                       unordered_map<int, std::vector<int>>& trackerToConditionMap,
930                       unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
931                       unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
932                       unordered_map<int64_t, int>& alertTrackerMap,
933                       vector<int>& metricsWithActivation,
934                       std::set<int64_t>& noReportMetricIds) {
935     unordered_map<int64_t, int> logTrackerMap;
936     unordered_map<int64_t, int> conditionTrackerMap;
937     vector<ConditionState> initialConditionCache;
938     unordered_map<int64_t, int> metricProducerMap;
939     unordered_map<int64_t, int> stateAtomIdMap;
940     unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
941 
942     if (!initLogTrackers(config, uidMap, logTrackerMap, allAtomMatchers, allTagIds)) {
943         ALOGE("initLogMatchingTrackers failed");
944         return false;
945     }
946     VLOG("initLogMatchingTrackers succeed...");
947 
948     if (!initConditions(key, config, logTrackerMap, conditionTrackerMap, allConditionTrackers,
949                         trackerToConditionMap, initialConditionCache)) {
950         ALOGE("initConditionTrackers failed");
951         return false;
952     }
953 
954     if (!initStates(config, stateAtomIdMap, allStateGroupMaps)) {
955         ALOGE("initStates failed");
956         return false;
957     }
958     if (!initMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager, logTrackerMap,
959                      conditionTrackerMap, allAtomMatchers, stateAtomIdMap, allStateGroupMaps,
960                      allConditionTrackers, initialConditionCache, allMetricProducers,
961                      conditionToMetricMap, trackerToMetricMap, metricProducerMap, noReportMetricIds,
962                      activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
963                      metricsWithActivation)) {
964         ALOGE("initMetricProducers failed");
965         return false;
966     }
967     if (!initAlerts(config, metricProducerMap, alertTrackerMap, anomalyAlarmMonitor,
968                     allMetricProducers, allAnomalyTrackers)) {
969         ALOGE("initAlerts failed");
970         return false;
971     }
972     if (!initAlarms(config, key, periodicAlarmMonitor,
973                     timeBaseNs, currentTimeNs, allPeriodicAlarmTrackers)) {
974         ALOGE("initAlarms failed");
975         return false;
976     }
977 
978     return true;
979 }
980 
981 }  // namespace statsd
982 }  // namespace os
983 }  // namespace android
984