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 SIMPLE_CONDITION_TRACKER_H
18 #define SIMPLE_CONDITION_TRACKER_H
19 
20 #include <gtest/gtest_prod.h>
21 #include "ConditionTracker.h"
22 #include "config/ConfigKey.h"
23 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
24 #include "stats_util.h"
25 
26 namespace android {
27 namespace os {
28 namespace statsd {
29 
30 class SimpleConditionTracker : public virtual ConditionTracker {
31 public:
32     SimpleConditionTracker(const ConfigKey& key, const int64_t& id, const int index,
33                            const SimplePredicate& simplePredicate,
34                            const std::unordered_map<int64_t, int>& trackerNameIndexMap);
35 
36     ~SimpleConditionTracker();
37 
38     bool init(const std::vector<Predicate>& allConditionConfig,
39               const std::vector<sp<ConditionTracker>>& allConditionTrackers,
40               const std::unordered_map<int64_t, int>& conditionIdIndexMap,
41               std::vector<bool>& stack) override;
42 
43     void evaluateCondition(const LogEvent& event,
44                            const std::vector<MatchingState>& eventMatcherValues,
45                            const std::vector<sp<ConditionTracker>>& mAllConditions,
46                            std::vector<ConditionState>& conditionCache,
47                            std::vector<bool>& changedCache) override;
48 
49     void isConditionMet(const ConditionKey& conditionParameters,
50                         const std::vector<sp<ConditionTracker>>& allConditions,
51                         const vector<Matcher>& dimensionFields,
52                         const bool isSubOutputDimensionFields,
53                         const bool isPartialLink,
54                         std::vector<ConditionState>& conditionCache,
55                         std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
56 
57     ConditionState getMetConditionDimension(
58             const std::vector<sp<ConditionTracker>>& allConditions,
59             const vector<Matcher>& dimensionFields,
60             const bool isSubOutputDimensionFields,
61             std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override;
62 
getChangedToTrueDimensions(const std::vector<sp<ConditionTracker>> & allConditions)63     virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
64             const std::vector<sp<ConditionTracker>>& allConditions) const {
65         if (mSliced) {
66             return &mLastChangedToTrueDimensions;
67         } else {
68             return nullptr;
69         }
70     }
71 
getChangedToFalseDimensions(const std::vector<sp<ConditionTracker>> & allConditions)72     virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
73             const std::vector<sp<ConditionTracker>>& allConditions) const {
74         if (mSliced) {
75             return &mLastChangedToFalseDimensions;
76         } else {
77             return nullptr;
78         }
79     }
80 
getTrueSlicedDimensions(const std::vector<sp<ConditionTracker>> & allConditions,std::set<HashableDimensionKey> * dimensions)81     void getTrueSlicedDimensions(
82             const std::vector<sp<ConditionTracker>>& allConditions,
83             std::set<HashableDimensionKey>* dimensions) const override {
84         for (const auto& itr : mSlicedConditionState) {
85             if (itr.second > 0) {
86                 dimensions->insert(itr.first);
87             }
88         }
89     }
90 
IsChangedDimensionTrackable()91     bool IsChangedDimensionTrackable() const  override { return true; }
92 
IsSimpleCondition()93     bool IsSimpleCondition() const  override { return true; }
94 
equalOutputDimensions(const std::vector<sp<ConditionTracker>> & allConditions,const vector<Matcher> & dimensions)95     bool equalOutputDimensions(
96         const std::vector<sp<ConditionTracker>>& allConditions,
97         const vector<Matcher>& dimensions) const override {
98             return equalDimensions(mOutputDimensions, dimensions);
99     }
100 
101 private:
102     const ConfigKey mConfigKey;
103     // The index of the LogEventMatcher which defines the start.
104     int mStartLogMatcherIndex;
105 
106     // The index of the LogEventMatcher which defines the end.
107     int mStopLogMatcherIndex;
108 
109     // if the start end needs to be nested.
110     bool mCountNesting;
111 
112     // The index of the LogEventMatcher which defines the stop all.
113     int mStopAllLogMatcherIndex;
114 
115     ConditionState mInitialValue;
116 
117     std::vector<Matcher> mOutputDimensions;
118 
119     bool mContainANYPositionInInternalDimensions;
120 
121     std::set<HashableDimensionKey> mLastChangedToTrueDimensions;
122     std::set<HashableDimensionKey> mLastChangedToFalseDimensions;
123 
124     int mDimensionTag;
125 
126     std::map<HashableDimensionKey, int> mSlicedConditionState;
127 
128     void handleStopAll(std::vector<ConditionState>& conditionCache,
129                        std::vector<bool>& changedCache);
130 
131     void handleConditionEvent(const HashableDimensionKey& outputKey, bool matchStart,
132                               ConditionState* conditionCache, bool* changedCache);
133 
134     bool hitGuardRail(const HashableDimensionKey& newKey);
135 
136     void dumpState();
137 
138     FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedCondition);
139     FRIEND_TEST(SimpleConditionTrackerTest, TestSlicedWithNoOutputDim);
140     FRIEND_TEST(SimpleConditionTrackerTest, TestStopAll);
141 };
142 
143 }  // namespace statsd
144 }  // namespace os
145 }  // namespace android
146 
147 #endif  // SIMPLE_CONDITION_TRACKER_H
148