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 #pragma once 18 19 20 #include <unordered_map> 21 22 #include <android/util/ProtoOutputStream.h> 23 #include "../anomaly/DurationAnomalyTracker.h" 24 #include "../condition/ConditionTracker.h" 25 #include "../matchers/matcher_util.h" 26 #include "MetricProducer.h" 27 #include "duration_helper/DurationTracker.h" 28 #include "duration_helper/MaxDurationTracker.h" 29 #include "duration_helper/OringDurationTracker.h" 30 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" 31 #include "stats_util.h" 32 33 using namespace std; 34 35 namespace android { 36 namespace os { 37 namespace statsd { 38 39 class DurationMetricProducer : public MetricProducer { 40 public: 41 DurationMetricProducer( 42 const ConfigKey& key, const DurationMetric& durationMetric, const int conditionIndex, 43 const vector<ConditionState>& initialConditionCache, const size_t startIndex, 44 const size_t stopIndex, const size_t stopAllIndex, const bool nesting, 45 const sp<ConditionWizard>& wizard, const FieldMatcher& internalDimensions, 46 const int64_t timeBaseNs, const int64_t startTimeNs, 47 const unordered_map<int, shared_ptr<Activation>>& eventActivationMap = {}, 48 const unordered_map<int, vector<shared_ptr<Activation>>>& eventDeactivationMap = {}, 49 const vector<int>& slicedStateAtoms = {}, 50 const unordered_map<int, unordered_map<int, int64_t>>& stateGroupMap = {}); 51 52 virtual ~DurationMetricProducer(); 53 54 sp<AnomalyTracker> addAnomalyTracker(const Alert &alert, 55 const sp<AlarmMonitor>& anomalyAlarmMonitor) override; 56 57 void onStateChanged(const int64_t eventTimeNs, const int32_t atomId, 58 const HashableDimensionKey& primaryKey, const FieldValue& oldState, 59 const FieldValue& newState) override; 60 61 protected: 62 void onMatchedLogEventLocked(const size_t matcherIndex, const LogEvent& event) override; 63 64 void onMatchedLogEventInternalLocked( 65 const size_t matcherIndex, const MetricDimensionKey& eventKey, 66 const ConditionKey& conditionKeys, bool condition, const LogEvent& event, 67 const std::map<int, HashableDimensionKey>& statePrimaryKeys) override; 68 69 private: 70 void handleStartEvent(const MetricDimensionKey& eventKey, const ConditionKey& conditionKeys, 71 bool condition, const LogEvent& event); 72 73 void onDumpReportLocked(const int64_t dumpTimeNs, 74 const bool include_current_partial_bucket, 75 const bool erase_data, 76 const DumpLatency dumpLatency, 77 std::set<string> *str_set, 78 android::util::ProtoOutputStream* protoOutput) override; 79 80 void clearPastBucketsLocked(const int64_t dumpTimeNs) override; 81 82 // Internal interface to handle condition change. 83 void onConditionChangedLocked(const bool conditionMet, const int64_t eventTime) override; 84 85 // Internal interface to handle active state change. 86 void onActiveStateChangedLocked(const int64_t& eventTimeNs) override; 87 88 // Internal interface to handle sliced condition change. 89 void onSlicedConditionMayChangeLocked(bool overallCondition, const int64_t eventTime) override; 90 91 void onSlicedConditionMayChangeInternalLocked(bool overallCondition, 92 const int64_t eventTimeNs); 93 94 void onSlicedConditionMayChangeLocked_opt1(bool overallCondition, const int64_t eventTime); 95 void onSlicedConditionMayChangeLocked_opt2(bool overallCondition, const int64_t eventTime); 96 97 // Internal function to calculate the current used bytes. 98 size_t byteSizeLocked() const override; 99 100 void dumpStatesLocked(FILE* out, bool verbose) const override; 101 102 void dropDataLocked(const int64_t dropTimeNs) override; 103 104 // Util function to flush the old packet. 105 void flushIfNeededLocked(const int64_t& eventTime); 106 107 void flushCurrentBucketLocked(const int64_t& eventTimeNs, 108 const int64_t& nextBucketStartTimeNs) override; 109 110 const DurationMetric_AggregationType mAggregationType; 111 112 // Index of the SimpleAtomMatcher which defines the start. 113 const size_t mStartIndex; 114 115 // Index of the SimpleAtomMatcher which defines the stop. 116 const size_t mStopIndex; 117 118 // Index of the SimpleAtomMatcher which defines the stop all for all dimensions. 119 const size_t mStopAllIndex; 120 121 // nest counting -- for the same key, stops must match the number of starts to make real stop 122 const bool mNested; 123 124 // The dimension from the atom predicate. e.g., uid, wakelock name. 125 vector<Matcher> mInternalDimensions; 126 127 bool mContainANYPositionInInternalDimensions; 128 129 // This boolean is true iff When mInternalDimensions == mDimensionsInWhat 130 bool mUseWhatDimensionAsInternalDimension; 131 132 // Caches the current unsliced part condition. 133 ConditionState mUnSlicedPartCondition; 134 135 // Save the past buckets and we can clear when the StatsLogReport is dumped. 136 std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>> mPastBuckets; 137 138 // The duration trackers in the current bucket. 139 std::unordered_map<HashableDimensionKey, std::unique_ptr<DurationTracker>> 140 mCurrentSlicedDurationTrackerMap; 141 142 // Helper function to create a duration tracker given the metric aggregation type. 143 std::unique_ptr<DurationTracker> createDurationTracker( 144 const MetricDimensionKey& eventKey) const; 145 146 // This hides the base class's std::vector<sp<AnomalyTracker>> mAnomalyTrackers 147 std::vector<sp<DurationAnomalyTracker>> mAnomalyTrackers; 148 149 // Util function to check whether the specified dimension hits the guardrail. 150 bool hitGuardRailLocked(const MetricDimensionKey& newKey); 151 152 static const size_t kBucketSize = sizeof(DurationBucket{}); 153 154 FRIEND_TEST(DurationMetricTrackerTest, TestNoCondition); 155 FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedCondition); 156 FRIEND_TEST(DurationMetricTrackerTest, TestNonSlicedConditionUnknownState); 157 FRIEND_TEST(WakelockDurationE2eTest, TestAggregatedPredicates); 158 FRIEND_TEST(DurationMetricTrackerTest, TestFirstBucket); 159 160 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestSumDuration); 161 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, 162 TestSumDurationWithSplitInFollowingBucket); 163 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDuration); 164 FRIEND_TEST(DurationMetricProducerTest_PartialBucket, TestMaxDurationWithSplitInNextBucket); 165 }; 166 167 } // namespace statsd 168 } // namespace os 169 } // namespace android 170