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 #ifndef MAX_DURATION_TRACKER_H
18 #define MAX_DURATION_TRACKER_H
19 
20 #include "DurationTracker.h"
21 
22 namespace android {
23 namespace os {
24 namespace statsd {
25 
26 // Tracks a pool of atom durations, and output the max duration for each bucket.
27 // To get max duration, we need to keep track of each individual durations, and compare them when
28 // they stop or bucket expires.
29 class MaxDurationTracker : public DurationTracker {
30 public:
31     MaxDurationTracker(const ConfigKey& key, const int64_t& id, const MetricDimensionKey& eventKey,
32                        sp<ConditionWizard> wizard, int conditionIndex,
33                        const std::vector<Matcher>& dimensionInCondition, bool nesting,
34                        int64_t currentBucketStartNs, int64_t currentBucketNum,
35                        int64_t startTimeNs, int64_t bucketSizeNs, bool conditionSliced,
36                        bool fullLink,
37                        const std::vector<sp<DurationAnomalyTracker>>& anomalyTrackers);
38 
39     MaxDurationTracker(const MaxDurationTracker& tracker) = default;
40 
41     unique_ptr<DurationTracker> clone(const int64_t eventTime) override;
42 
43     void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
44                    const ConditionKey& conditionKey) override;
45     void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
46                   const bool stopAll) override;
47     void noteStopAll(const int64_t eventTime) override;
48 
49     bool flushIfNeeded(
50             int64_t timestampNs,
51             std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
52     bool flushCurrentBucket(
53             const int64_t& eventTimeNs,
54             std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
55 
56     void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
57     void onConditionChanged(bool condition, const int64_t timestamp) override;
58 
59     int64_t predictAnomalyTimestampNs(const DurationAnomalyTracker& anomalyTracker,
60                                       const int64_t currentTimestamp) const override;
61     void dumpStates(FILE* out, bool verbose) const override;
62 
63 private:
64     // Returns true if at least one of the mInfos is started.
65     bool anyStarted();
66 
67     std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
68 
69     void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
70                               const int64_t timestamp);
71 
72     // return true if we should not allow newKey to be tracked because we are above the threshold
73     bool hitGuardRail(const HashableDimensionKey& newKey);
74 
75     FRIEND_TEST(MaxDurationTrackerTest, TestSimpleMaxDuration);
76     FRIEND_TEST(MaxDurationTrackerTest, TestCrossBucketBoundary);
77     FRIEND_TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition);
78     FRIEND_TEST(MaxDurationTrackerTest, TestStopAll);
79     FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
80     FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
81 };
82 
83 }  // namespace statsd
84 }  // namespace os
85 }  // namespace android
86 
87 #endif  // MAX_DURATION_TRACKER_H
88