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 #pragma once
18 
19 #include "condition/condition_util.h"
20 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
21 #include "matchers/LogMatchingTracker.h"
22 #include "matchers/matcher_util.h"
23 
24 #include <utils/RefBase.h>
25 
26 #include <unordered_map>
27 
28 namespace android {
29 namespace os {
30 namespace statsd {
31 
32 class ConditionTracker : public virtual RefBase {
33 public:
ConditionTracker(const int64_t & id,const int index)34     ConditionTracker(const int64_t& id, const int index)
35         : mConditionId(id),
36           mIndex(index),
37           mInitialized(false),
38           mTrackerIndex(),
39           mUnSlicedPartCondition(ConditionState::kUnknown),
40           mSliced(false){};
41 
~ConditionTracker()42     virtual ~ConditionTracker(){};
43 
getId()44     inline const int64_t& getId() { return mConditionId; }
45 
46     // Initialize this ConditionTracker. This initialization is done recursively (DFS). It can also
47     // be done in the constructor, but we do it separately because (1) easy to return a bool to
48     // indicate whether the initialization is successful. (2) makes unit test easier.
49     // allConditionConfig: the list of all Predicate config from statsd_config.
50     // allConditionTrackers: the list of all ConditionTrackers (this is needed because we may also
51     //                       need to call init() on children conditions)
52     // conditionIdIndexMap: the mapping from condition id to its index.
53     // stack: a bit map to keep track which nodes have been visited on the stack in the recursion.
54     // initialConditionCache: tracks initial conditions of all ConditionTrackers.
55     virtual bool init(const std::vector<Predicate>& allConditionConfig,
56                       const std::vector<sp<ConditionTracker>>& allConditionTrackers,
57                       const std::unordered_map<int64_t, int>& conditionIdIndexMap,
58                       std::vector<bool>& stack,
59                       std::vector<ConditionState>& initialConditionCache) = 0;
60 
61     // evaluate current condition given the new event.
62     // event: the new log event
63     // eventMatcherValues: the results of the LogMatcherTrackers. LogMatcherTrackers always process
64     //                     event before ConditionTrackers, because ConditionTracker depends on
65     //                     LogMatchingTrackers.
66     // mAllConditions: the list of all ConditionTracker
67     // conditionCache: the cached non-sliced condition of the ConditionTrackers for this new event.
68     // conditionChanged: the bit map to record whether the condition has changed.
69     //                   If the condition has dimension, then any sub condition changes will report
70     //                   conditionChanged.
71     virtual void evaluateCondition(const LogEvent& event,
72                                    const std::vector<MatchingState>& eventMatcherValues,
73                                    const std::vector<sp<ConditionTracker>>& mAllConditions,
74                                    std::vector<ConditionState>& conditionCache,
75                                    std::vector<bool>& conditionChanged) = 0;
76 
77     // Query the condition with parameters.
78     // [conditionParameters]: a map from condition name to the HashableDimensionKey to query the
79     //                       condition.
80     // [allConditions]: all condition trackers. This is needed because the condition evaluation is
81     //                  done recursively
82     // [isPartialLink]: true if the link specified by 'conditionParameters' contains all the fields
83     //                  in the condition tracker output dimension.
84     // [conditionCache]: the cache holding the condition evaluation values.
85     virtual void isConditionMet(
86             const ConditionKey& conditionParameters,
87             const std::vector<sp<ConditionTracker>>& allConditions,
88             const bool isPartialLink,
89             std::vector<ConditionState>& conditionCache) const = 0;
90 
91     // return the list of LogMatchingTracker index that this ConditionTracker uses.
getLogTrackerIndex()92     virtual const std::set<int>& getLogTrackerIndex() const {
93         return mTrackerIndex;
94     }
95 
setSliced(bool sliced)96     virtual void setSliced(bool sliced) {
97         mSliced = mSliced | sliced;
98     }
99 
isSliced()100     inline bool isSliced() const {
101         return mSliced;
102     }
103 
104     virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions(
105             const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
106     virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions(
107             const std::vector<sp<ConditionTracker>>& allConditions) const = 0;
108 
getConditionId()109     inline int64_t getConditionId() const {
110         return mConditionId;
111     }
112 
113     virtual void getTrueSlicedDimensions(
114         const std::vector<sp<ConditionTracker>>& allConditions,
115         std::set<HashableDimensionKey>* dimensions) const = 0;
116 
117     virtual bool IsChangedDimensionTrackable() const = 0;
118 
119     virtual bool IsSimpleCondition() const = 0;
120 
121     virtual bool equalOutputDimensions(
122         const std::vector<sp<ConditionTracker>>& allConditions,
123         const vector<Matcher>& dimensions) const = 0;
124 
125     // Return the current condition state of the unsliced part of the condition.
getUnSlicedPartConditionState()126     inline ConditionState getUnSlicedPartConditionState() const  {
127         return mUnSlicedPartCondition;
128     }
129 
130 protected:
131     const int64_t mConditionId;
132 
133     // the index of this condition in the manager's condition list.
134     const int mIndex;
135 
136     // if it's properly initialized.
137     bool mInitialized;
138 
139     // the list of LogMatchingTracker index that this ConditionTracker uses.
140     std::set<int> mTrackerIndex;
141 
142     // This variable is only used for CombinationConditionTrackers.
143     // SimpleConditionTrackers technically don't have an unsliced part because
144     // they are either sliced or unsliced.
145     //
146     // CombinationConditionTrackers have multiple children ConditionTrackers
147     // that can be a mixture of sliced or unsliced. This tracks the
148     // condition of the unsliced part of the combination condition.
149     ConditionState mUnSlicedPartCondition;
150 
151     bool mSliced;
152 };
153 
154 }  // namespace statsd
155 }  // namespace os
156 }  // namespace android
157