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