1 /* 2 * Copyright 2018, 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 #pragma once 17 18 #include <gtest/gtest_prod.h> 19 #include "ConditionTracker.h" 20 #include "config/ConfigKey.h" 21 #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" 22 #include "stats_util.h" 23 24 namespace android { 25 namespace os { 26 namespace statsd { 27 28 class StateTracker : public virtual ConditionTracker { 29 public: 30 StateTracker(const ConfigKey& key, const int64_t& id, const int index, 31 const SimplePredicate& simplePredicate, 32 const std::unordered_map<int64_t, int>& trackerNameIndexMap, 33 const vector<Matcher> primaryKeys); 34 35 ~StateTracker(); 36 37 bool init(const std::vector<Predicate>& allConditionConfig, 38 const std::vector<sp<ConditionTracker>>& allConditionTrackers, 39 const std::unordered_map<int64_t, int>& conditionIdIndexMap, 40 std::vector<bool>& stack) override; 41 42 void evaluateCondition(const LogEvent& event, 43 const std::vector<MatchingState>& eventMatcherValues, 44 const std::vector<sp<ConditionTracker>>& mAllConditions, 45 std::vector<ConditionState>& conditionCache, 46 std::vector<bool>& changedCache) override; 47 48 /** 49 * Note: dimensionFields will be ignored in StateTracker, because we demand metrics 50 * must take the entire dimension fields from StateTracker. This is to make implementation 51 * simple and efficient. 52 * 53 * For example: wakelock duration by uid process states: 54 * dimension in condition must be {uid, process state}. 55 */ 56 void isConditionMet(const ConditionKey& conditionParameters, 57 const std::vector<sp<ConditionTracker>>& allConditions, 58 const vector<Matcher>& dimensionFields, 59 const bool isSubOutputDimensionFields, 60 const bool isPartialLink, 61 std::vector<ConditionState>& conditionCache, 62 std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; 63 64 /** 65 * Note: dimensionFields will be ignored in StateTracker, because we demand metrics 66 * must take the entire dimension fields from StateTracker. This is to make implementation 67 * simple and efficient. 68 */ 69 ConditionState getMetConditionDimension( 70 const std::vector<sp<ConditionTracker>>& allConditions, 71 const vector<Matcher>& dimensionFields, 72 const bool isSubOutputDimensionFields, 73 std::unordered_set<HashableDimensionKey>& dimensionsKeySet) const override; 74 getChangedToTrueDimensions(const std::vector<sp<ConditionTracker>> & allConditions)75 virtual const std::set<HashableDimensionKey>* getChangedToTrueDimensions( 76 const std::vector<sp<ConditionTracker>>& allConditions) const { 77 return &mLastChangedToTrueDimensions; 78 } 79 getChangedToFalseDimensions(const std::vector<sp<ConditionTracker>> & allConditions)80 virtual const std::set<HashableDimensionKey>* getChangedToFalseDimensions( 81 const std::vector<sp<ConditionTracker>>& allConditions) const { 82 return &mLastChangedToFalseDimensions; 83 } 84 IsChangedDimensionTrackable()85 bool IsChangedDimensionTrackable() const override { return true; } 86 IsSimpleCondition()87 bool IsSimpleCondition() const override { return true; } 88 equalOutputDimensions(const std::vector<sp<ConditionTracker>> & allConditions,const vector<Matcher> & dimensions)89 bool equalOutputDimensions( 90 const std::vector<sp<ConditionTracker>>& allConditions, 91 const vector<Matcher>& dimensions) const override { 92 return equalDimensions(mOutputDimensions, dimensions); 93 } 94 getTrueSlicedDimensions(const std::vector<sp<ConditionTracker>> & allConditions,std::set<HashableDimensionKey> * dimensions)95 void getTrueSlicedDimensions( 96 const std::vector<sp<ConditionTracker>>& allConditions, 97 std::set<HashableDimensionKey>* dimensions) const override { 98 for (const auto& itr : mSlicedState) { 99 dimensions->insert(itr.second); 100 } 101 } 102 103 private: 104 const ConfigKey mConfigKey; 105 106 // The index of the LogEventMatcher which defines the start. 107 int mStartLogMatcherIndex; 108 109 std::set<HashableDimensionKey> mLastChangedToTrueDimensions; 110 std::set<HashableDimensionKey> mLastChangedToFalseDimensions; 111 112 std::vector<Matcher> mOutputDimensions; 113 std::vector<Matcher> mPrimaryKeys; 114 115 ConditionState mInitialValue; 116 117 int mDimensionTag; 118 119 void dumpState(); 120 121 bool hitGuardRail(const HashableDimensionKey& newKey); 122 123 // maps from [primary_key] to [primary_key, exclusive_state]. 124 std::unordered_map<HashableDimensionKey, HashableDimensionKey> mSlicedState; 125 126 FRIEND_TEST(StateTrackerTest, TestStateChange); 127 }; 128 129 } // namespace statsd 130 } // namespace os 131 } // namespace android