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, bool nesting,
33                        int64_t currentBucketStartNs, int64_t currentBucketNum, int64_t startTimeNs,
34                        int64_t bucketSizeNs, bool conditionSliced, bool fullLink,
35                        const std::vector<sp<AnomalyTracker>>& anomalyTrackers);
36 
37     MaxDurationTracker(const MaxDurationTracker& tracker) = default;
38 
39     void noteStart(const HashableDimensionKey& key, bool condition, const int64_t eventTime,
40                    const ConditionKey& conditionKey) override;
41     void noteStop(const HashableDimensionKey& key, const int64_t eventTime,
42                   const bool stopAll) override;
43     void noteStopAll(const int64_t eventTime) override;
44 
45     bool flushIfNeeded(
46             int64_t timestampNs, const optional<UploadThreshold>& uploadThreshold,
47             std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>* output) override;
48     bool flushCurrentBucket(
49             const int64_t& eventTimeNs, const optional<UploadThreshold>& uploadThreshold,
50             std::unordered_map<MetricDimensionKey, std::vector<DurationBucket>>*) override;
51 
52     void onSlicedConditionMayChange(bool overallCondition, const int64_t timestamp) override;
53     void onConditionChanged(bool condition, const int64_t timestamp) override;
54 
55     void onStateChanged(const int64_t timestamp, const int32_t atomId,
56                         const FieldValue& newState) override;
57 
58     int64_t predictAnomalyTimestampNs(const AnomalyTracker& anomalyTracker,
59                                       const int64_t currentTimestamp) const override;
60     void dumpStates(FILE* out, bool verbose) const override;
61 
62     int64_t getCurrentStateKeyDuration() const override;
63 
64     int64_t getCurrentStateKeyFullBucketDuration() const override;
65 
66     void updateCurrentStateKey(const int32_t atomId, const FieldValue& newState);
67 
68 protected:
69     // Returns true if at least one of the mInfos is started.
70     bool hasAccumulatingDuration() override;
71 
72 private:
73     std::unordered_map<HashableDimensionKey, DurationInfo> mInfos;
74 
75     void noteConditionChanged(const HashableDimensionKey& key, bool conditionMet,
76                               const int64_t timestamp);
77 
78     // return true if we should not allow newKey to be tracked because we are above the threshold
79     bool hitGuardRail(const HashableDimensionKey& newKey);
80 
81     FRIEND_TEST(MaxDurationTrackerTest, TestSimpleMaxDuration);
82     FRIEND_TEST(MaxDurationTrackerTest, TestCrossBucketBoundary);
83     FRIEND_TEST(MaxDurationTrackerTest, TestMaxDurationWithCondition);
84     FRIEND_TEST(MaxDurationTrackerTest, TestStopAll);
85     FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyDetection);
86     FRIEND_TEST(MaxDurationTrackerTest, TestAnomalyPredictedTimestamp);
87     FRIEND_TEST(MaxDurationTrackerTest, TestUploadThreshold);
88 };
89 
90 }  // namespace statsd
91 }  // namespace os
92 }  // namespace android
93 
94 #endif  // MAX_DURATION_TRACKER_H
95