blob: 3ab44f4a06af8766f7f33a3cfed370966e02b0da [file] [log] [blame]
Yao Chencaf339d2017-10-06 16:01:10 -07001/*
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
Tej Singh484524a2018-02-01 15:10:05 -080017#define DEBUG false // STOPSHIP if true
Yao Chen10535b92017-11-27 11:31:55 -080018#include "Log.h"
19
Yangster-mac932ecec2018-02-01 10:23:52 -080020#include "metrics_manager_util.h"
21
tsaichristined21aacf2019-10-07 14:47:38 -070022#include <inttypes.h>
Yangster-mac932ecec2018-02-01 10:23:52 -080023
tsaichristinec876b492019-12-10 13:47:05 -080024#include "FieldValue.h"
25#include "MetricProducer.h"
tsaichristined21aacf2019-10-07 14:47:38 -070026#include "condition/CombinationConditionTracker.h"
27#include "condition/SimpleConditionTracker.h"
tsaichristined21aacf2019-10-07 14:47:38 -070028#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"
Yao Chencaf339d2017-10-06 16:01:10 -070038#include "stats_util.h"
39
40using std::set;
Yao Chencaf339d2017-10-06 16:01:10 -070041using std::unordered_map;
42using std::vector;
43
44namespace android {
45namespace os {
46namespace statsd {
47
Yao Chen8a8d16c2018-02-08 14:50:40 -080048namespace {
49
50bool 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
Yangster-mac94e197c2018-01-02 16:03:03 -080064bool handleMetricWithLogTrackers(const int64_t what, const int metricIndex,
Yao Chen5154a372017-10-30 22:57:06 -070065 const bool usedForDimension,
Stefan Lafonb8c9aa82017-12-03 14:27:25 -080066 const vector<sp<LogMatchingTracker>>& allAtomMatchers,
Yangster-mac94e197c2018-01-02 16:03:03 -080067 const unordered_map<int64_t, int>& logTrackerMap,
Yao Chen5110bed2017-10-23 12:50:02 -070068 unordered_map<int, std::vector<int>>& trackerToMetricMap,
69 int& logTrackerIndex) {
70 auto logTrackerIt = logTrackerMap.find(what);
Yao Chen729093d2017-10-16 10:33:26 -070071 if (logTrackerIt == logTrackerMap.end()) {
Yangster-mac94e197c2018-01-02 16:03:03 -080072 ALOGW("cannot find the AtomMatcher \"%lld\" in config", (long long)what);
Yao Chen5110bed2017-10-23 12:50:02 -070073 return false;
Yao Chen729093d2017-10-16 10:33:26 -070074 }
Yangster-mac20877162017-12-22 17:19:39 -080075 if (usedForDimension && allAtomMatchers[logTrackerIt->second]->getAtomIds().size() > 1) {
Yangster-mac94e197c2018-01-02 16:03:03 -080076 ALOGE("AtomMatcher \"%lld\" has more than one tag ids. When a metric has dimension, "
Stefan Lafon7c8f0a52017-11-21 14:49:09 -080077 "the \"what\" can only about one atom type.",
Yangster-mac94e197c2018-01-02 16:03:03 -080078 (long long)what);
Yao Chen5154a372017-10-30 22:57:06 -070079 return false;
80 }
Yao Chen5110bed2017-10-23 12:50:02 -070081 logTrackerIndex = logTrackerIt->second;
82 auto& metric_list = trackerToMetricMap[logTrackerIndex];
83 metric_list.push_back(metricIndex);
84 return true;
85}
86
Chenjie Yu88588972018-08-03 09:49:22 -070087bool 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
Yao Chen5110bed2017-10-23 12:50:02 -0700109bool handleMetricWithConditions(
Yangster-mac94e197c2018-01-02 16:03:03 -0800110 const int64_t condition, const int metricIndex,
111 const unordered_map<int64_t, int>& conditionTrackerMap,
Stefan Lafona5b51912017-12-05 21:43:52 -0800112 const ::google::protobuf::RepeatedPtrField<::android::os::statsd::MetricConditionLink>&
Yao Chen5110bed2017-10-23 12:50:02 -0700113 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()) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800118 ALOGW("cannot find Predicate \"%lld\" in the config", (long long)condition);
Yao Chen5110bed2017-10-23 12:50:02 -0700119 return false;
120 }
121
122 for (const auto& link : links) {
123 auto it = conditionTrackerMap.find(link.condition());
124 if (it == conditionTrackerMap.end()) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800125 ALOGW("cannot find Predicate \"%lld\" in the config", (long long)link.condition());
Yao Chen5110bed2017-10-23 12:50:02 -0700126 return false;
127 }
128 allConditionTrackers[condition_it->second]->setSliced(true);
129 allConditionTrackers[it->second]->setSliced(true);
Yao Chen5110bed2017-10-23 12:50:02 -0700130 }
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;
Yao Chen729093d2017-10-16 10:33:26 -0700137}
138
tsaichristined21aacf2019-10-07 14:47:38 -0700139// 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
151bool 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
tsaichristinec876b492019-12-10 13:47:05 -0800174bool 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
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700182// 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.
186bool 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
Yangster-mac20877162017-12-22 17:19:39 -0800238bool initLogTrackers(const StatsdConfig& config, const UidMap& uidMap,
Yangster-mac94e197c2018-01-02 16:03:03 -0800239 unordered_map<int64_t, int>& logTrackerMap,
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800240 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);
Yao Chencaf339d2017-10-06 16:01:10 -0700245
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800246 for (int i = 0; i < atomMatcherCount; i++) {
247 const AtomMatcher& logMatcher = config.atom_matcher(i);
Yao Chencaf339d2017-10-06 16:01:10 -0700248
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800249 int index = allAtomMatchers.size();
Yao Chencaf339d2017-10-06 16:01:10 -0700250 switch (logMatcher.contents_case()) {
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800251 case AtomMatcher::ContentsCase::kSimpleAtomMatcher:
252 allAtomMatchers.push_back(new SimpleLogMatchingTracker(
Yangster-mac94e197c2018-01-02 16:03:03 -0800253 logMatcher.id(), index, logMatcher.simple_atom_matcher(), uidMap));
Yao Chencaf339d2017-10-06 16:01:10 -0700254 break;
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800255 case AtomMatcher::ContentsCase::kCombination:
256 allAtomMatchers.push_back(
Yangster-mac94e197c2018-01-02 16:03:03 -0800257 new CombinationLogMatchingTracker(logMatcher.id(), index));
Yao Chencaf339d2017-10-06 16:01:10 -0700258 break;
259 default:
Yangster-mac94e197c2018-01-02 16:03:03 -0800260 ALOGE("Matcher \"%lld\" malformed", (long long)logMatcher.id());
Yao Chencaf339d2017-10-06 16:01:10 -0700261 return false;
262 // continue;
263 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800264 if (logTrackerMap.find(logMatcher.id()) != logTrackerMap.end()) {
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800265 ALOGE("Duplicate AtomMatcher found!");
Yao Chencaf339d2017-10-06 16:01:10 -0700266 return false;
267 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800268 logTrackerMap[logMatcher.id()] = index;
Yao Chencaf339d2017-10-06 16:01:10 -0700269 matcherConfigs.push_back(logMatcher);
270 }
271
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800272 vector<bool> stackTracker2(allAtomMatchers.size(), false);
273 for (auto& matcher : allAtomMatchers) {
274 if (!matcher->init(matcherConfigs, allAtomMatchers, logTrackerMap, stackTracker2)) {
Yao Chencaf339d2017-10-06 16:01:10 -0700275 return false;
276 }
277 // Collect all the tag ids that are interesting. TagIds exist in leaf nodes only.
Yangster-mac20877162017-12-22 17:19:39 -0800278 const set<int>& tagIds = matcher->getAtomIds();
Yao Chencaf339d2017-10-06 16:01:10 -0700279 allTagIds.insert(tagIds.begin(), tagIds.end());
280 }
281 return true;
282}
283
Yao Chenb3561512017-11-21 18:07:17 -0800284bool initConditions(const ConfigKey& key, const StatsdConfig& config,
Yangster-mac94e197c2018-01-02 16:03:03 -0800285 const unordered_map<int64_t, int>& logTrackerMap,
286 unordered_map<int64_t, int>& conditionTrackerMap,
Yao Chencaf339d2017-10-06 16:01:10 -0700287 vector<sp<ConditionTracker>>& allConditionTrackers,
288 unordered_map<int, std::vector<int>>& trackerToConditionMap) {
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800289 vector<Predicate> conditionConfigs;
290 const int conditionTrackerCount = config.predicate_size();
Yao Chen729093d2017-10-16 10:33:26 -0700291 conditionConfigs.reserve(conditionTrackerCount);
292 allConditionTrackers.reserve(conditionTrackerCount);
Yao Chencaf339d2017-10-06 16:01:10 -0700293
Yao Chen729093d2017-10-16 10:33:26 -0700294 for (int i = 0; i < conditionTrackerCount; i++) {
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800295 const Predicate& condition = config.predicate(i);
Yao Chencaf339d2017-10-06 16:01:10 -0700296 int index = allConditionTrackers.size();
297 switch (condition.contents_case()) {
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800298 case Predicate::ContentsCase::kSimplePredicate: {
tsaichristine3d8e12a2020-04-02 17:57:06 -0700299 allConditionTrackers.push_back(new SimpleConditionTracker(
300 key, condition.id(), index, condition.simple_predicate(), logTrackerMap));
Yao Chencaf339d2017-10-06 16:01:10 -0700301 break;
302 }
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800303 case Predicate::ContentsCase::kCombination: {
Yao Chencaf339d2017-10-06 16:01:10 -0700304 allConditionTrackers.push_back(
Yangster-mac94e197c2018-01-02 16:03:03 -0800305 new CombinationConditionTracker(condition.id(), index));
Yao Chencaf339d2017-10-06 16:01:10 -0700306 break;
307 }
308 default:
Yangster-mac94e197c2018-01-02 16:03:03 -0800309 ALOGE("Predicate \"%lld\" malformed", (long long)condition.id());
Yao Chencaf339d2017-10-06 16:01:10 -0700310 return false;
311 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800312 if (conditionTrackerMap.find(condition.id()) != conditionTrackerMap.end()) {
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800313 ALOGE("Duplicate Predicate found!");
Yao Chencaf339d2017-10-06 16:01:10 -0700314 return false;
315 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800316 conditionTrackerMap[condition.id()] = index;
Yao Chencaf339d2017-10-06 16:01:10 -0700317 conditionConfigs.push_back(condition);
318 }
319
320 vector<bool> stackTracker(allConditionTrackers.size(), false);
321 for (size_t i = 0; i < allConditionTrackers.size(); i++) {
322 auto& conditionTracker = allConditionTrackers[i];
323 if (!conditionTracker->init(conditionConfigs, allConditionTrackers, conditionTrackerMap,
324 stackTracker)) {
325 return false;
326 }
327 for (const int trackerIndex : conditionTracker->getLogTrackerIndex()) {
328 auto& conditionList = trackerToConditionMap[trackerIndex];
329 conditionList.push_back(i);
330 }
331 }
332 return true;
333}
334
tsaichristined21aacf2019-10-07 14:47:38 -0700335bool initStates(const StatsdConfig& config, unordered_map<int64_t, int>& stateAtomIdMap,
336 unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps) {
337 for (int i = 0; i < config.state_size(); i++) {
338 const State& state = config.state(i);
339 const int64_t stateId = state.id();
340 stateAtomIdMap[stateId] = state.atom_id();
341
342 const StateMap& stateMap = state.map();
343 for (auto group : stateMap.group()) {
344 for (auto value : group.value()) {
345 allStateGroupMaps[stateId][value] = group.group_id();
346 }
347 }
348 }
349
350 return true;
351}
352
Chenjie Yue2219202018-06-08 10:07:51 -0700353bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t timeBaseTimeNs,
Tej Singh9ec159a2019-11-14 11:59:48 -0800354 const int64_t currentTimeNs,
Chenjie Yue2219202018-06-08 10:07:51 -0700355 const sp<StatsPullerManager>& pullerManager,
356 const unordered_map<int64_t, int>& logTrackerMap,
Yangster-mac94e197c2018-01-02 16:03:03 -0800357 const unordered_map<int64_t, int>& conditionTrackerMap,
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800358 const vector<sp<LogMatchingTracker>>& allAtomMatchers,
tsaichristined21aacf2019-10-07 14:47:38 -0700359 const unordered_map<int64_t, int>& stateAtomIdMap,
360 const unordered_map<int64_t, unordered_map<int, int64_t>>& allStateGroupMaps,
Yao Chen729093d2017-10-16 10:33:26 -0700361 vector<sp<ConditionTracker>>& allConditionTrackers,
Yao Chencaf339d2017-10-06 16:01:10 -0700362 vector<sp<MetricProducer>>& allMetricProducers,
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700363 unordered_map<int, vector<int>>& conditionToMetricMap,
364 unordered_map<int, vector<int>>& trackerToMetricMap,
365 unordered_map<int64_t, int>& metricMap, std::set<int64_t>& noReportMetricIds,
366 unordered_map<int, vector<int>>& activationAtomTrackerToMetricMap,
367 unordered_map<int, vector<int>>& deactivationAtomTrackerToMetricMap,
368 vector<int>& metricsWithActivation) {
Yao Chen729093d2017-10-16 10:33:26 -0700369 sp<ConditionWizard> wizard = new ConditionWizard(allConditionTrackers);
Yangster-mac32f07af2018-10-13 17:08:11 -0700370 sp<EventMatcherWizard> matcherWizard = new EventMatcherWizard(allAtomMatchers);
Yao Chen93fe3a32017-11-02 13:52:59 -0700371 const int allMetricsCount = config.count_metric_size() + config.duration_metric_size() +
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700372 config.event_metric_size() + config.gauge_metric_size() +
373 config.value_metric_size();
Yao Chen729093d2017-10-16 10:33:26 -0700374 allMetricProducers.reserve(allMetricsCount);
Yangster-mac20877162017-12-22 17:19:39 -0800375
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700376 // Construct map from metric id to metric activation index. The map will be used to determine
377 // the metric activation corresponding to a metric.
378 unordered_map<int64_t, int> metricToActivationMap;
379 for (int i = 0; i < config.metric_activation_size(); i++) {
380 const MetricActivation& metricActivation = config.metric_activation(i);
381 int64_t metricId = metricActivation.metric_id();
382 if (metricToActivationMap.find(metricId) != metricToActivationMap.end()) {
383 ALOGE("Metric %lld has multiple MetricActivations", (long long) metricId);
384 return false;
385 }
386 metricToActivationMap.insert({metricId, i});
387 }
388
Yao Chencaf339d2017-10-06 16:01:10 -0700389 // Build MetricProducers for each metric defined in config.
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700390 // build CountMetricProducer
Yao Chencaf339d2017-10-06 16:01:10 -0700391 for (int i = 0; i < config.count_metric_size(); i++) {
392 const CountMetric& metric = config.count_metric(i);
393 if (!metric.has_what()) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800394 ALOGW("cannot find \"what\" in CountMetric \"%lld\"", (long long)metric.id());
Yao Chencaf339d2017-10-06 16:01:10 -0700395 return false;
396 }
397
Yao Chen729093d2017-10-16 10:33:26 -0700398 int metricIndex = allMetricProducers.size();
Yangster-mac94e197c2018-01-02 16:03:03 -0800399 metricMap.insert({metric.id(), metricIndex});
Yao Chen5110bed2017-10-23 12:50:02 -0700400 int trackerIndex;
Yangster-mac468ff042018-01-17 12:26:34 -0800401 if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
402 metric.has_dimensions_in_what(),
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800403 allAtomMatchers, logTrackerMap, trackerToMetricMap,
Yao Chen5154a372017-10-30 22:57:06 -0700404 trackerIndex)) {
Yao Chencaf339d2017-10-06 16:01:10 -0700405 return false;
406 }
407
Yao Chen5110bed2017-10-23 12:50:02 -0700408 int conditionIndex = -1;
Yao Chencaf339d2017-10-06 16:01:10 -0700409 if (metric.has_condition()) {
tsaichristined21aacf2019-10-07 14:47:38 -0700410 if (!handleMetricWithConditions(metric.condition(), metricIndex, conditionTrackerMap,
411 metric.links(), allConditionTrackers, conditionIndex,
412 conditionToMetricMap)) {
Yao Chen10535b92017-11-27 11:31:55 -0800413 return false;
414 }
Yao Chen5c925ad2017-11-15 14:15:46 -0800415 } else {
416 if (metric.links_size() > 0) {
Stefan Lafona5b51912017-12-05 21:43:52 -0800417 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
Yao Chen5c925ad2017-11-15 14:15:46 -0800418 return false;
419 }
Yao Chencaf339d2017-10-06 16:01:10 -0700420 }
Yao Chen5110bed2017-10-23 12:50:02 -0700421
tsaichristined21aacf2019-10-07 14:47:38 -0700422 std::vector<int> slicedStateAtoms;
423 unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
424 if (metric.slice_by_state_size() > 0) {
425 if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
426 allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
427 return false;
428 }
tsaichristine69000e62019-10-18 17:34:52 -0700429 } else {
430 if (metric.state_link_size() > 0) {
431 ALOGW("CountMetric has a MetricStateLink but doesn't have a slice_by_state");
432 return false;
433 }
tsaichristined21aacf2019-10-07 14:47:38 -0700434 }
435
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700436 unordered_map<int, shared_ptr<Activation>> eventActivationMap;
437 unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
438 bool success = handleMetricActivation(config, metric.id(), metricIndex,
439 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
440 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
441 eventDeactivationMap);
442 if (!success) return false;
443
444 sp<MetricProducer> countProducer = new CountMetricProducer(
445 key, metric, conditionIndex, wizard, timeBaseTimeNs, currentTimeNs,
tsaichristined21aacf2019-10-07 14:47:38 -0700446 eventActivationMap, eventDeactivationMap, slicedStateAtoms, stateGroupMap);
Yao Chencaf339d2017-10-06 16:01:10 -0700447 allMetricProducers.push_back(countProducer);
448 }
449
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700450 // build DurationMetricProducer
Yao Chen729093d2017-10-16 10:33:26 -0700451 for (int i = 0; i < config.duration_metric_size(); i++) {
452 int metricIndex = allMetricProducers.size();
Yao Chen5110bed2017-10-23 12:50:02 -0700453 const DurationMetric& metric = config.duration_metric(i);
Yangster-mac94e197c2018-01-02 16:03:03 -0800454 metricMap.insert({metric.id(), metricIndex});
Yao Chen5154a372017-10-30 22:57:06 -0700455
456 auto what_it = conditionTrackerMap.find(metric.what());
457 if (what_it == conditionTrackerMap.end()) {
458 ALOGE("DurationMetric's \"what\" is invalid");
459 return false;
460 }
461
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800462 const Predicate& durationWhat = config.predicate(what_it->second);
Yao Chen5154a372017-10-30 22:57:06 -0700463
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800464 if (durationWhat.contents_case() != Predicate::ContentsCase::kSimplePredicate) {
Yao Chen5154a372017-10-30 22:57:06 -0700465 ALOGE("DurationMetric's \"what\" must be a simple condition");
466 return false;
467 }
468
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800469 const auto& simplePredicate = durationWhat.simple_predicate();
Yao Chen5154a372017-10-30 22:57:06 -0700470
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800471 bool nesting = simplePredicate.count_nesting();
Yao Chen0ea19902017-11-15 15:44:45 -0800472
Yao Chen5110bed2017-10-23 12:50:02 -0700473 int trackerIndices[3] = {-1, -1, -1};
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800474 if (!simplePredicate.has_start() ||
475 !handleMetricWithLogTrackers(simplePredicate.start(), metricIndex,
Yangster-mac468ff042018-01-17 12:26:34 -0800476 metric.has_dimensions_in_what(), allAtomMatchers,
Yao Chen5154a372017-10-30 22:57:06 -0700477 logTrackerMap, trackerToMetricMap, trackerIndices[0])) {
Yao Chen5110bed2017-10-23 12:50:02 -0700478 ALOGE("Duration metrics must specify a valid the start event matcher");
Yao Chen729093d2017-10-16 10:33:26 -0700479 return false;
480 }
Yao Chencaf339d2017-10-06 16:01:10 -0700481
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800482 if (simplePredicate.has_stop() &&
483 !handleMetricWithLogTrackers(simplePredicate.stop(), metricIndex,
Yangster-mac468ff042018-01-17 12:26:34 -0800484 metric.has_dimensions_in_what(), allAtomMatchers,
Yao Chen5154a372017-10-30 22:57:06 -0700485 logTrackerMap, trackerToMetricMap, trackerIndices[1])) {
Yao Chen5110bed2017-10-23 12:50:02 -0700486 return false;
Yao Chen729093d2017-10-16 10:33:26 -0700487 }
488
Stefan Lafon12d01fa2017-12-04 20:56:09 -0800489 if (simplePredicate.has_stop_all() &&
490 !handleMetricWithLogTrackers(simplePredicate.stop_all(), metricIndex,
Yangster-mac468ff042018-01-17 12:26:34 -0800491 metric.has_dimensions_in_what(), allAtomMatchers,
Yao Chen5154a372017-10-30 22:57:06 -0700492 logTrackerMap, trackerToMetricMap, trackerIndices[2])) {
Yao Chen5110bed2017-10-23 12:50:02 -0700493 return false;
Yao Chen729093d2017-10-16 10:33:26 -0700494 }
495
Yangster-mac20877162017-12-22 17:19:39 -0800496 FieldMatcher internalDimensions = simplePredicate.dimensions();
Yao Chen5154a372017-10-30 22:57:06 -0700497
Yao Chen729093d2017-10-16 10:33:26 -0700498 int conditionIndex = -1;
499
Yao Chen5c925ad2017-11-15 14:15:46 -0800500 if (metric.has_condition()) {
Yao Chen10535b92017-11-27 11:31:55 -0800501 bool good = handleMetricWithConditions(
502 metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
503 allConditionTrackers, conditionIndex, conditionToMetricMap);
504 if (!good) {
505 return false;
506 }
Yao Chen5c925ad2017-11-15 14:15:46 -0800507 } else {
508 if (metric.links_size() > 0) {
Stefan Lafona5b51912017-12-05 21:43:52 -0800509 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
Yao Chen5c925ad2017-11-15 14:15:46 -0800510 return false;
511 }
Yao Chen729093d2017-10-16 10:33:26 -0700512 }
513
tsaichristine1449fa42020-01-02 12:12:05 -0800514 std::vector<int> slicedStateAtoms;
515 unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
516 if (metric.slice_by_state_size() > 0) {
517 if (metric.aggregation_type() == DurationMetric::MAX_SPARSE) {
518 ALOGE("DurationMetric with aggregation type MAX_SPARSE cannot be sliced by state");
519 return false;
520 }
521 if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
522 allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
523 return false;
524 }
525 } else {
526 if (metric.state_link_size() > 0) {
527 ALOGW("DurationMetric has a MetricStateLink but doesn't have a sliced state");
528 return false;
529 }
530 }
531
532 // Check that all metric state links are a subset of dimensions_in_what fields.
533 std::vector<Matcher> dimensionsInWhat;
534 translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
535 for (const auto& stateLink : metric.state_link()) {
536 if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
537 return false;
538 }
539 }
540
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700541 unordered_map<int, shared_ptr<Activation>> eventActivationMap;
542 unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
543 bool success = handleMetricActivation(config, metric.id(), metricIndex,
544 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
545 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
546 eventDeactivationMap);
547 if (!success) return false;
548
Yao Chen5154a372017-10-30 22:57:06 -0700549 sp<MetricProducer> durationMetric = new DurationMetricProducer(
Yao Chenb3561512017-11-21 18:07:17 -0800550 key, metric, conditionIndex, trackerIndices[0], trackerIndices[1],
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700551 trackerIndices[2], nesting, wizard, internalDimensions, timeBaseTimeNs,
tsaichristine1449fa42020-01-02 12:12:05 -0800552 currentTimeNs, eventActivationMap, eventDeactivationMap, slicedStateAtoms,
553 stateGroupMap);
Yao Chen729093d2017-10-16 10:33:26 -0700554
555 allMetricProducers.push_back(durationMetric);
556 }
Yao Chen5110bed2017-10-23 12:50:02 -0700557
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700558 // build EventMetricProducer
Yao Chen5110bed2017-10-23 12:50:02 -0700559 for (int i = 0; i < config.event_metric_size(); i++) {
560 int metricIndex = allMetricProducers.size();
561 const EventMetric& metric = config.event_metric(i);
Yangster-mac94e197c2018-01-02 16:03:03 -0800562 metricMap.insert({metric.id(), metricIndex});
563 if (!metric.has_id() || !metric.has_what()) {
Yangster-macd1815dc2017-11-13 21:43:15 -0800564 ALOGW("cannot find the metric name or what in config");
Yao Chen5110bed2017-10-23 12:50:02 -0700565 return false;
566 }
567 int trackerIndex;
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800568 if (!handleMetricWithLogTrackers(metric.what(), metricIndex, false, allAtomMatchers,
Yao Chen5154a372017-10-30 22:57:06 -0700569 logTrackerMap, trackerToMetricMap, trackerIndex)) {
Yao Chen5110bed2017-10-23 12:50:02 -0700570 return false;
571 }
572
573 int conditionIndex = -1;
574 if (metric.has_condition()) {
Yao Chen10535b92017-11-27 11:31:55 -0800575 bool good = handleMetricWithConditions(
576 metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
577 allConditionTrackers, conditionIndex, conditionToMetricMap);
578 if (!good) {
579 return false;
580 }
Yao Chen5c925ad2017-11-15 14:15:46 -0800581 } else {
582 if (metric.links_size() > 0) {
Stefan Lafona5b51912017-12-05 21:43:52 -0800583 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
Yao Chen5c925ad2017-11-15 14:15:46 -0800584 return false;
585 }
Yao Chen5110bed2017-10-23 12:50:02 -0700586 }
587
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700588 unordered_map<int, shared_ptr<Activation>> eventActivationMap;
589 unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
590 bool success = handleMetricActivation(config, metric.id(), metricIndex,
591 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
592 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
593 eventDeactivationMap);
594 if (!success) return false;
595
596 sp<MetricProducer> eventMetric = new EventMetricProducer(
597 key, metric, conditionIndex, wizard, timeBaseTimeNs, eventActivationMap,
598 eventDeactivationMap);
Yao Chen93fe3a32017-11-02 13:52:59 -0700599
Yao Chen5110bed2017-10-23 12:50:02 -0700600 allMetricProducers.push_back(eventMetric);
601 }
602
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700603 // build ValueMetricProducer
Chenjie Yub3dda412017-10-24 13:41:59 -0700604 for (int i = 0; i < config.value_metric_size(); i++) {
605 const ValueMetric& metric = config.value_metric(i);
606 if (!metric.has_what()) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800607 ALOGW("cannot find \"what\" in ValueMetric \"%lld\"", (long long)metric.id());
Chenjie Yub3dda412017-10-24 13:41:59 -0700608 return false;
609 }
Chenjie Yud7e3a222018-11-28 21:29:44 +0000610 if (!metric.has_value_field()) {
611 ALOGW("cannot find \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
612 return false;
613 }
614 std::vector<Matcher> fieldMatchers;
615 translateFieldMatcher(metric.value_field(), &fieldMatchers);
616 if (fieldMatchers.size() < 1) {
617 ALOGW("incorrect \"value_field\" in ValueMetric \"%lld\"", (long long)metric.id());
618 return false;
619 }
Chenjie Yub3dda412017-10-24 13:41:59 -0700620
Chenjie Yub3dda412017-10-24 13:41:59 -0700621 int metricIndex = allMetricProducers.size();
Yangster-mac94e197c2018-01-02 16:03:03 -0800622 metricMap.insert({metric.id(), metricIndex});
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700623 int trackerIndex;
Yangster-mac468ff042018-01-17 12:26:34 -0800624 if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
625 metric.has_dimensions_in_what(),
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800626 allAtomMatchers, logTrackerMap, trackerToMetricMap,
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700627 trackerIndex)) {
628 return false;
629 }
Chenjie Yub3dda412017-10-24 13:41:59 -0700630
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800631 sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700632 // If it is pulled atom, it should be simple matcher with one tagId.
Yangster-mac20877162017-12-22 17:19:39 -0800633 if (atomMatcher->getAtomIds().size() != 1) {
Chenjie Yud9dfda72017-12-11 17:41:20 -0800634 return false;
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700635 }
Yangster-mac20877162017-12-22 17:19:39 -0800636 int atomTagId = *(atomMatcher->getAtomIds().begin());
Tej Singh97db3ff2020-01-27 16:52:17 -0800637 int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700638
639 int conditionIndex = -1;
640 if (metric.has_condition()) {
Yao Chen10535b92017-11-27 11:31:55 -0800641 bool good = handleMetricWithConditions(
642 metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
643 allConditionTrackers, conditionIndex, conditionToMetricMap);
644 if (!good) {
645 return false;
646 }
Yao Chen5c925ad2017-11-15 14:15:46 -0800647 } else {
648 if (metric.links_size() > 0) {
Stefan Lafona5b51912017-12-05 21:43:52 -0800649 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
Yao Chen5c925ad2017-11-15 14:15:46 -0800650 return false;
651 }
Chenjie Yu5305e1d2017-10-31 13:49:36 -0700652 }
653
tsaichristinec876b492019-12-10 13:47:05 -0800654 std::vector<int> slicedStateAtoms;
655 unordered_map<int, unordered_map<int, int64_t>> stateGroupMap;
656 if (metric.slice_by_state_size() > 0) {
657 if (!handleMetricWithStates(config, metric.slice_by_state(), stateAtomIdMap,
658 allStateGroupMaps, slicedStateAtoms, stateGroupMap)) {
659 return false;
660 }
661 } else {
662 if (metric.state_link_size() > 0) {
663 ALOGW("ValueMetric has a MetricStateLink but doesn't have a sliced state");
664 return false;
665 }
666 }
667
668 // Check that all metric state links are a subset of dimensions_in_what fields.
669 std::vector<Matcher> dimensionsInWhat;
670 translateFieldMatcher(metric.dimensions_in_what(), &dimensionsInWhat);
671 for (const auto& stateLink : metric.state_link()) {
672 if (!handleMetricWithStateLink(stateLink.fields_in_what(), dimensionsInWhat)) {
673 return false;
674 }
675 }
676
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700677 unordered_map<int, shared_ptr<Activation>> eventActivationMap;
678 unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
tsaichristinec876b492019-12-10 13:47:05 -0800679 bool success = handleMetricActivation(
680 config, metric.id(), metricIndex, metricToActivationMap, logTrackerMap,
681 activationAtomTrackerToMetricMap, deactivationAtomTrackerToMetricMap,
682 metricsWithActivation, eventActivationMap, eventDeactivationMap);
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700683 if (!success) return false;
684
Chenjie Yu054ce9c2018-11-12 15:27:29 -0800685 sp<MetricProducer> valueProducer = new ValueMetricProducer(
686 key, metric, conditionIndex, wizard, trackerIndex, matcherWizard, pullTagId,
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700687 timeBaseTimeNs, currentTimeNs, pullerManager, eventActivationMap,
tsaichristinec876b492019-12-10 13:47:05 -0800688 eventDeactivationMap, slicedStateAtoms, stateGroupMap);
Chenjie Yub3dda412017-10-24 13:41:59 -0700689 allMetricProducers.push_back(valueProducer);
690 }
Yangster1d4d6862017-10-31 12:58:51 -0700691
692 // Gauge metrics.
693 for (int i = 0; i < config.gauge_metric_size(); i++) {
694 const GaugeMetric& metric = config.gauge_metric(i);
695 if (!metric.has_what()) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800696 ALOGW("cannot find \"what\" in GaugeMetric \"%lld\"", (long long)metric.id());
Chenjie Yud9dfda72017-12-11 17:41:20 -0800697 return false;
698 }
699
Yangster-mac20877162017-12-22 17:19:39 -0800700 if ((!metric.gauge_fields_filter().has_include_all() ||
701 (metric.gauge_fields_filter().include_all() == false)) &&
702 !hasLeafNode(metric.gauge_fields_filter().fields())) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800703 ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
Chenjie Yu2b4fc9d2017-12-18 15:20:00 -0800704 return false;
705 }
Yangster-mac20877162017-12-22 17:19:39 -0800706 if ((metric.gauge_fields_filter().has_include_all() &&
707 metric.gauge_fields_filter().include_all() == true) &&
708 hasLeafNode(metric.gauge_fields_filter().fields())) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800709 ALOGW("Incorrect field filter setting in GaugeMetric %lld", (long long)metric.id());
Yangster1d4d6862017-10-31 12:58:51 -0700710 return false;
711 }
712
713 int metricIndex = allMetricProducers.size();
Yangster-mac94e197c2018-01-02 16:03:03 -0800714 metricMap.insert({metric.id(), metricIndex});
Yangster1d4d6862017-10-31 12:58:51 -0700715 int trackerIndex;
Yangster-mac468ff042018-01-17 12:26:34 -0800716 if (!handleMetricWithLogTrackers(metric.what(), metricIndex,
717 metric.has_dimensions_in_what(),
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800718 allAtomMatchers, logTrackerMap, trackerToMetricMap,
Yangster1d4d6862017-10-31 12:58:51 -0700719 trackerIndex)) {
720 return false;
721 }
722
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800723 sp<LogMatchingTracker> atomMatcher = allAtomMatchers.at(trackerIndex);
Chenjie Yu88588972018-08-03 09:49:22 -0700724 // For GaugeMetric atom, it should be simple matcher with one tagId.
Yangster-mac20877162017-12-22 17:19:39 -0800725 if (atomMatcher->getAtomIds().size() != 1) {
Chenjie Yud9dfda72017-12-11 17:41:20 -0800726 return false;
Yangster1d4d6862017-10-31 12:58:51 -0700727 }
Yangster-mac20877162017-12-22 17:19:39 -0800728 int atomTagId = *(atomMatcher->getAtomIds().begin());
Tej Singh97db3ff2020-01-27 16:52:17 -0800729 int pullTagId = pullerManager->PullerForMatcherExists(atomTagId) ? atomTagId : -1;
Yangster1d4d6862017-10-31 12:58:51 -0700730
Chenjie Yu88588972018-08-03 09:49:22 -0700731 int triggerTrackerIndex;
732 int triggerAtomId = -1;
Chenjie Yue077fd22018-11-19 13:29:40 -0800733 if (metric.has_trigger_event()) {
734 if (pullTagId == -1) {
735 ALOGW("Pull atom not specified for trigger");
736 return false;
737 }
738 // event_trigger should be used with FIRST_N_SAMPLES
739 if (metric.sampling_type() != GaugeMetric::FIRST_N_SAMPLES) {
Chenjie Yu88588972018-08-03 09:49:22 -0700740 return false;
741 }
742 if (!handlePullMetricTriggerWithLogTrackers(metric.trigger_event(), metricIndex,
743 allAtomMatchers, logTrackerMap,
744 trackerToMetricMap, triggerTrackerIndex)) {
745 return false;
746 }
747 sp<LogMatchingTracker> triggerAtomMatcher = allAtomMatchers.at(triggerTrackerIndex);
748 triggerAtomId = *(triggerAtomMatcher->getAtomIds().begin());
749 }
750
Chenjie Yue077fd22018-11-19 13:29:40 -0800751 if (!metric.has_trigger_event() && pullTagId != -1 &&
752 metric.sampling_type() == GaugeMetric::FIRST_N_SAMPLES) {
753 ALOGW("FIRST_N_SAMPLES is only for pushed event or pull_on_trigger");
754 return false;
755 }
756
Yangster1d4d6862017-10-31 12:58:51 -0700757 int conditionIndex = -1;
758 if (metric.has_condition()) {
Yao Chen10535b92017-11-27 11:31:55 -0800759 bool good = handleMetricWithConditions(
760 metric.condition(), metricIndex, conditionTrackerMap, metric.links(),
761 allConditionTrackers, conditionIndex, conditionToMetricMap);
762 if (!good) {
763 return false;
764 }
Yao Chen5c925ad2017-11-15 14:15:46 -0800765 } else {
766 if (metric.links_size() > 0) {
Stefan Lafona5b51912017-12-05 21:43:52 -0800767 ALOGW("metrics has a MetricConditionLink but doesn't have a condition");
Yao Chen5c925ad2017-11-15 14:15:46 -0800768 return false;
769 }
Yangster1d4d6862017-10-31 12:58:51 -0700770 }
771
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700772 unordered_map<int, shared_ptr<Activation>> eventActivationMap;
773 unordered_map<int, vector<shared_ptr<Activation>>> eventDeactivationMap;
774 bool success = handleMetricActivation(config, metric.id(), metricIndex,
775 metricToActivationMap, logTrackerMap, activationAtomTrackerToMetricMap,
776 deactivationAtomTrackerToMetricMap, metricsWithActivation, eventActivationMap,
777 eventDeactivationMap);
778 if (!success) return false;
779
Chenjie Yu88588972018-08-03 09:49:22 -0700780 sp<MetricProducer> gaugeProducer = new GaugeMetricProducer(
Tej Singh3be093b2020-03-04 20:08:38 -0800781 key, metric, conditionIndex, wizard, trackerIndex, matcherWizard, pullTagId,
782 triggerAtomId, atomTagId, timeBaseTimeNs, currentTimeNs, pullerManager,
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700783 eventActivationMap, eventDeactivationMap);
Yangster1d4d6862017-10-31 12:58:51 -0700784 allMetricProducers.push_back(gaugeProducer);
785 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800786 for (int i = 0; i < config.no_report_metric_size(); ++i) {
787 const auto no_report_metric = config.no_report_metric(i);
788 if (metricMap.find(no_report_metric) == metricMap.end()) {
Colin Crossd013a882018-10-26 13:04:41 -0700789 ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
Yangster-mac94e197c2018-01-02 16:03:03 -0800790 return false;
791 }
792 noReportMetricIds.insert(no_report_metric);
793 }
Chih-Hung Hsieha1b644e2018-12-11 11:09:20 -0800794 for (const auto& it : allMetricProducers) {
tsaichristined21aacf2019-10-07 14:47:38 -0700795 // Register metrics to StateTrackers
796 for (int atomId : it->getSlicedStateAtoms()) {
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -0700797 StateManager::getInstance().registerListener(atomId, it);
tsaichristined21aacf2019-10-07 14:47:38 -0700798 }
David Chenbd125272018-04-04 19:02:50 -0700799 }
Yao Chencaf339d2017-10-06 16:01:10 -0700800 return true;
801}
802
Yangster-mac20877162017-12-22 17:19:39 -0800803bool initAlerts(const StatsdConfig& config,
Yangster-mac94e197c2018-01-02 16:03:03 -0800804 const unordered_map<int64_t, int>& metricProducerMap,
Jeffrey Huang38d70262020-03-19 17:28:59 -0700805 unordered_map<int64_t, int>& alertTrackerMap,
Yangster-mac932ecec2018-02-01 10:23:52 -0800806 const sp<AlarmMonitor>& anomalyAlarmMonitor,
Yangster-mace2cd6d52017-11-09 20:38:30 -0800807 vector<sp<MetricProducer>>& allMetricProducers,
808 vector<sp<AnomalyTracker>>& allAnomalyTrackers) {
809 for (int i = 0; i < config.alert_size(); i++) {
810 const Alert& alert = config.alert(i);
Yangster-mac94e197c2018-01-02 16:03:03 -0800811 const auto& itr = metricProducerMap.find(alert.metric_id());
Yangster-mace2cd6d52017-11-09 20:38:30 -0800812 if (itr == metricProducerMap.end()) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800813 ALOGW("alert \"%lld\" has unknown metric id: \"%lld\"", (long long)alert.id(),
814 (long long)alert.metric_id());
Yangster-mace2cd6d52017-11-09 20:38:30 -0800815 return false;
816 }
Bookatz6bf98252018-03-14 10:44:24 -0700817 if (!alert.has_trigger_if_sum_gt()) {
818 ALOGW("invalid alert: missing threshold");
819 return false;
820 }
Yangster-maca7fb12d2018-01-03 17:17:20 -0800821 if (alert.trigger_if_sum_gt() < 0 || alert.num_buckets() <= 0) {
822 ALOGW("invalid alert: threshold=%f num_buckets= %d",
823 alert.trigger_if_sum_gt(), alert.num_buckets());
Bookatzcc5adef2017-11-21 14:36:23 -0800824 return false;
825 }
Yangster-mace2cd6d52017-11-09 20:38:30 -0800826 const int metricIndex = itr->second;
Bookatz450099d2017-11-30 17:09:30 -0800827 sp<MetricProducer> metric = allMetricProducers[metricIndex];
Yangster-mac932ecec2018-02-01 10:23:52 -0800828 sp<AnomalyTracker> anomalyTracker = metric->addAnomalyTracker(alert, anomalyAlarmMonitor);
Bookatz1476ef22018-02-13 12:26:01 -0800829 if (anomalyTracker == nullptr) {
830 // The ALOGW for this invalid alert was already displayed in addAnomalyTracker().
831 return false;
Bookatzcc5adef2017-11-21 14:36:23 -0800832 }
Jeffrey Huang38d70262020-03-19 17:28:59 -0700833 alertTrackerMap.insert(std::make_pair(alert.id(), allAnomalyTrackers.size()));
Bookatz1476ef22018-02-13 12:26:01 -0800834 allAnomalyTrackers.push_back(anomalyTracker);
Yangster-mace2cd6d52017-11-09 20:38:30 -0800835 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800836 for (int i = 0; i < config.subscription_size(); ++i) {
837 const Subscription& subscription = config.subscription(i);
Yangster-mac932ecec2018-02-01 10:23:52 -0800838 if (subscription.rule_type() != Subscription::ALERT) {
839 continue;
840 }
Yangster-mac94e197c2018-01-02 16:03:03 -0800841 if (subscription.subscriber_information_case() ==
842 Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
843 ALOGW("subscription \"%lld\" has no subscriber info.\"",
844 (long long)subscription.id());
845 return false;
846 }
Jeffrey Huang38d70262020-03-19 17:28:59 -0700847 const auto& itr = alertTrackerMap.find(subscription.rule_id());
848 if (itr == alertTrackerMap.end()) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800849 ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
850 (long long)subscription.id(), (long long)subscription.rule_id());
851 return false;
852 }
853 const int anomalyTrackerIndex = itr->second;
854 allAnomalyTrackers[anomalyTrackerIndex]->addSubscription(subscription);
855 }
Yangster-mace2cd6d52017-11-09 20:38:30 -0800856 return true;
857}
858
Yangster-mac932ecec2018-02-01 10:23:52 -0800859bool initAlarms(const StatsdConfig& config, const ConfigKey& key,
860 const sp<AlarmMonitor>& periodicAlarmMonitor,
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700861 const int64_t timeBaseNs, const int64_t currentTimeNs,
Yangster-mac932ecec2018-02-01 10:23:52 -0800862 vector<sp<AlarmTracker>>& allAlarmTrackers) {
863 unordered_map<int64_t, int> alarmTrackerMap;
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700864 int64_t startMillis = timeBaseNs / 1000 / 1000;
865 int64_t currentTimeMillis = currentTimeNs / 1000 /1000;
Yangster-mac932ecec2018-02-01 10:23:52 -0800866 for (int i = 0; i < config.alarm_size(); i++) {
867 const Alarm& alarm = config.alarm(i);
868 if (alarm.offset_millis() <= 0) {
869 ALOGW("Alarm offset_millis should be larger than 0.");
870 return false;
871 }
872 if (alarm.period_millis() <= 0) {
873 ALOGW("Alarm period_millis should be larger than 0.");
874 return false;
875 }
876 alarmTrackerMap.insert(std::make_pair(alarm.id(), allAlarmTrackers.size()));
877 allAlarmTrackers.push_back(
Yangster-macc04feba2018-04-02 14:37:33 -0700878 new AlarmTracker(startMillis, currentTimeMillis,
879 alarm, key, periodicAlarmMonitor));
Yangster-mac932ecec2018-02-01 10:23:52 -0800880 }
881 for (int i = 0; i < config.subscription_size(); ++i) {
882 const Subscription& subscription = config.subscription(i);
883 if (subscription.rule_type() != Subscription::ALARM) {
884 continue;
885 }
886 if (subscription.subscriber_information_case() ==
887 Subscription::SubscriberInformationCase::SUBSCRIBER_INFORMATION_NOT_SET) {
888 ALOGW("subscription \"%lld\" has no subscriber info.\"",
889 (long long)subscription.id());
890 return false;
891 }
892 const auto& itr = alarmTrackerMap.find(subscription.rule_id());
893 if (itr == alarmTrackerMap.end()) {
894 ALOGW("subscription \"%lld\" has unknown rule id: \"%lld\"",
895 (long long)subscription.id(), (long long)subscription.rule_id());
896 return false;
897 }
898 const int trackerIndex = itr->second;
899 allAlarmTrackers[trackerIndex]->addSubscription(subscription);
900 }
901 return true;
902}
903
David Chenbd125272018-04-04 19:02:50 -0700904bool initStatsdConfig(const ConfigKey& key, const StatsdConfig& config, UidMap& uidMap,
Chenjie Yue2219202018-06-08 10:07:51 -0700905 const sp<StatsPullerManager>& pullerManager,
Yangster-mac932ecec2018-02-01 10:23:52 -0800906 const sp<AlarmMonitor>& anomalyAlarmMonitor,
Chenjie Yue2219202018-06-08 10:07:51 -0700907 const sp<AlarmMonitor>& periodicAlarmMonitor, const int64_t timeBaseNs,
908 const int64_t currentTimeNs, set<int>& allTagIds,
Stefan Lafonb8c9aa82017-12-03 14:27:25 -0800909 vector<sp<LogMatchingTracker>>& allAtomMatchers,
Yao Chencaf339d2017-10-06 16:01:10 -0700910 vector<sp<ConditionTracker>>& allConditionTrackers,
911 vector<sp<MetricProducer>>& allMetricProducers,
Yangster-mace2cd6d52017-11-09 20:38:30 -0800912 vector<sp<AnomalyTracker>>& allAnomalyTrackers,
Yangster-mac932ecec2018-02-01 10:23:52 -0800913 vector<sp<AlarmTracker>>& allPeriodicAlarmTrackers,
Yao Chencaf339d2017-10-06 16:01:10 -0700914 unordered_map<int, std::vector<int>>& conditionToMetricMap,
915 unordered_map<int, std::vector<int>>& trackerToMetricMap,
Yangster-mac94e197c2018-01-02 16:03:03 -0800916 unordered_map<int, std::vector<int>>& trackerToConditionMap,
Yangster-mac849dfdc22018-10-12 15:41:45 -0700917 unordered_map<int, std::vector<int>>& activationAtomTrackerToMetricMap,
Muhammad Qureshi3a5ebf52019-03-28 12:38:21 -0700918 unordered_map<int, std::vector<int>>& deactivationAtomTrackerToMetricMap,
Jeffrey Huang38d70262020-03-19 17:28:59 -0700919 unordered_map<int64_t, int>& alertTrackerMap,
Yangster-mac849dfdc22018-10-12 15:41:45 -0700920 vector<int>& metricsWithActivation,
David Chenbd125272018-04-04 19:02:50 -0700921 std::set<int64_t>& noReportMetricIds) {
Yangster-mac94e197c2018-01-02 16:03:03 -0800922 unordered_map<int64_t, int> logTrackerMap;
923 unordered_map<int64_t, int> conditionTrackerMap;
924 unordered_map<int64_t, int> metricProducerMap;
tsaichristined21aacf2019-10-07 14:47:38 -0700925 unordered_map<int64_t, int> stateAtomIdMap;
926 unordered_map<int64_t, unordered_map<int, int64_t>> allStateGroupMaps;
Yao Chencaf339d2017-10-06 16:01:10 -0700927
Yangster-mac20877162017-12-22 17:19:39 -0800928 if (!initLogTrackers(config, uidMap, logTrackerMap, allAtomMatchers, allTagIds)) {
Yao Chencaf339d2017-10-06 16:01:10 -0700929 ALOGE("initLogMatchingTrackers failed");
930 return false;
931 }
Tej Singh484524a2018-02-01 15:10:05 -0800932 VLOG("initLogMatchingTrackers succeed...");
Yao Chencaf339d2017-10-06 16:01:10 -0700933
Yao Chenb3561512017-11-21 18:07:17 -0800934 if (!initConditions(key, config, logTrackerMap, conditionTrackerMap, allConditionTrackers,
Yao Chencaf339d2017-10-06 16:01:10 -0700935 trackerToConditionMap)) {
936 ALOGE("initConditionTrackers failed");
937 return false;
938 }
Tej Singh3be093b2020-03-04 20:08:38 -0800939
tsaichristined21aacf2019-10-07 14:47:38 -0700940 if (!initStates(config, stateAtomIdMap, allStateGroupMaps)) {
941 ALOGE("initStates failed");
942 return false;
943 }
Tej Singh9ec159a2019-11-14 11:59:48 -0800944 if (!initMetrics(key, config, timeBaseNs, currentTimeNs, pullerManager, logTrackerMap,
tsaichristined21aacf2019-10-07 14:47:38 -0700945 conditionTrackerMap, allAtomMatchers, stateAtomIdMap, allStateGroupMaps,
946 allConditionTrackers, allMetricProducers,
David Chenbd125272018-04-04 19:02:50 -0700947 conditionToMetricMap, trackerToMetricMap, metricProducerMap,
Ruchir Rastogi21a287b2019-10-02 12:04:33 -0700948 noReportMetricIds, activationAtomTrackerToMetricMap,
949 deactivationAtomTrackerToMetricMap, metricsWithActivation)) {
Yao Chencaf339d2017-10-06 16:01:10 -0700950 ALOGE("initMetricProducers failed");
951 return false;
952 }
Jeffrey Huang38d70262020-03-19 17:28:59 -0700953 if (!initAlerts(config, metricProducerMap, alertTrackerMap, anomalyAlarmMonitor,
954 allMetricProducers, allAnomalyTrackers)) {
Yangster-mace2cd6d52017-11-09 20:38:30 -0800955 ALOGE("initAlerts failed");
956 return false;
957 }
Yangster-macc04feba2018-04-02 14:37:33 -0700958 if (!initAlarms(config, key, periodicAlarmMonitor,
Yangster-mac15f6bbc2018-04-08 11:52:26 -0700959 timeBaseNs, currentTimeNs, allPeriodicAlarmTrackers)) {
Yangster-mac932ecec2018-02-01 10:23:52 -0800960 ALOGE("initAlarms failed");
961 return false;
962 }
Tej Singh597c7162019-04-17 16:41:45 -0700963
Yao Chencaf339d2017-10-06 16:01:10 -0700964 return true;
965}
966
967} // namespace statsd
968} // namespace os
969} // namespace android