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 COMBINATION_CONDITION_TRACKER_H
18 #define COMBINATION_CONDITION_TRACKER_H
19 
20 #include "ConditionTracker.h"
21 #include "src/statsd_config.pb.h"
22 
23 namespace android {
24 namespace os {
25 namespace statsd {
26 
27 class CombinationConditionTracker : public ConditionTracker {
28 public:
29     CombinationConditionTracker(const int64_t& id, const int index, const uint64_t protoHash);
30 
31     ~CombinationConditionTracker();
32 
33     bool init(const std::vector<Predicate>& allConditionConfig,
34               const std::vector<sp<ConditionTracker>>& allConditionTrackers,
35               const std::unordered_map<int64_t, int>& conditionIdIndexMap, std::vector<bool>& stack,
36               std::vector<ConditionState>& conditionCache) override;
37 
38     bool onConfigUpdated(const std::vector<Predicate>& allConditionProtos, const int index,
39                          const std::vector<sp<ConditionTracker>>& allConditionTrackers,
40                          const std::unordered_map<int64_t, int>& atomMatchingTrackerMap,
41                          const std::unordered_map<int64_t, int>& conditionTrackerMap) 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 bool isPartialLink,
52                         std::vector<ConditionState>& conditionCache) const override;
53 
54     // Only one child predicate can have dimension.
55     const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
56             const std::vector<sp<ConditionTracker>>& allConditions) const override {
57         for (const auto& child : mChildren) {
58             auto result = allConditions[child]->getChangedToTrueDimensions(allConditions);
59             if (result != nullptr) {
60                 return result;
61             }
62         }
63         return nullptr;
64     }
65 
66     // Only one child predicate can have dimension.
67     const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
68             const std::vector<sp<ConditionTracker>>& allConditions) const override {
69         for (const auto& child : mChildren) {
70             auto result = allConditions[child]->getChangedToFalseDimensions(allConditions);
71             if (result != nullptr) {
72                 return result;
73             }
74         }
75         return nullptr;
76     }
77 
78     bool IsSimpleCondition() const  override { return false; }
79 
80     bool IsChangedDimensionTrackable() const  override {
81         return mLogicalOperation == LogicalOperation::AND && mSlicedChildren.size() == 1;
82     }
83 
84     bool equalOutputDimensions(
85         const std::vector<sp<ConditionTracker>>& allConditions,
86         const vector<Matcher>& dimensions) const override;
87 
88     const std::map<HashableDimensionKey, int>* getSlicedDimensionMap(
89             const std::vector<sp<ConditionTracker>>& allConditions) const override {
90         if (mSlicedChildren.size() == 1) {
91             return allConditions[mSlicedChildren.front()]->getSlicedDimensionMap(allConditions);
92         }
93         return nullptr;
94     }
95 
96 private:
97     LogicalOperation mLogicalOperation;
98 
99     // Store index of the children Predicates.
100     // We don't store string name of the Children, because we want to get rid of the hash map to
101     // map the name to object. We don't want to store smart pointers to children, because it
102     // increases the risk of circular dependency and memory leak.
103     std::vector<int> mChildren;
104 
105     std::vector<int> mSlicedChildren;
106     std::vector<int> mUnSlicedChildren;
107 
108     FRIEND_TEST(ConfigUpdateTest, TestUpdateConditions);
109 };
110 
111 }  // namespace statsd
112 }  // namespace os
113 }  // namespace android
114 
115 #endif  // COMBINATION_CONDITION_TRACKER_H
116