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