/* * Copyright 2018, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include "ConditionTracker.h" #include "config/ConfigKey.h" #include "frameworks/base/cmds/statsd/src/statsd_config.pb.h" #include "stats_util.h" namespace android { namespace os { namespace statsd { class StateTracker : public virtual ConditionTracker { public: StateTracker(const ConfigKey& key, const int64_t& id, const int index, const SimplePredicate& simplePredicate, const std::unordered_map& trackerNameIndexMap, const vector primaryKeys); ~StateTracker(); bool init(const std::vector& allConditionConfig, const std::vector>& allConditionTrackers, const std::unordered_map& conditionIdIndexMap, std::vector& stack) override; void evaluateCondition(const LogEvent& event, const std::vector& eventMatcherValues, const std::vector>& mAllConditions, std::vector& conditionCache, std::vector& changedCache) override; /** * Note: dimensionFields will be ignored in StateTracker, because we demand metrics * must take the entire dimension fields from StateTracker. This is to make implementation * simple and efficient. * * For example: wakelock duration by uid process states: * dimension in condition must be {uid, process state}. */ void isConditionMet(const ConditionKey& conditionParameters, const std::vector>& allConditions, const vector& dimensionFields, const bool isSubOutputDimensionFields, const bool isPartialLink, std::vector& conditionCache, std::unordered_set& dimensionsKeySet) const override; /** * Note: dimensionFields will be ignored in StateTracker, because we demand metrics * must take the entire dimension fields from StateTracker. This is to make implementation * simple and efficient. */ ConditionState getMetConditionDimension( const std::vector>& allConditions, const vector& dimensionFields, const bool isSubOutputDimensionFields, std::unordered_set& dimensionsKeySet) const override; virtual const std::set* getChangedToTrueDimensions( const std::vector>& allConditions) const { return &mLastChangedToTrueDimensions; } virtual const std::set* getChangedToFalseDimensions( const std::vector>& allConditions) const { return &mLastChangedToFalseDimensions; } bool IsChangedDimensionTrackable() const override { return true; } bool IsSimpleCondition() const override { return true; } bool equalOutputDimensions( const std::vector>& allConditions, const vector& dimensions) const override { return equalDimensions(mOutputDimensions, dimensions); } void getTrueSlicedDimensions( const std::vector>& allConditions, std::set* dimensions) const override { for (const auto& itr : mSlicedState) { dimensions->insert(itr.second); } } private: const ConfigKey mConfigKey; // The index of the LogEventMatcher which defines the start. int mStartLogMatcherIndex; std::set mLastChangedToTrueDimensions; std::set mLastChangedToFalseDimensions; std::vector mOutputDimensions; std::vector mPrimaryKeys; ConditionState mInitialValue; int mDimensionTag; void dumpState(); bool hitGuardRail(const HashableDimensionKey& newKey); // maps from [primary_key] to [primary_key, exclusive_state]. std::unordered_map mSlicedState; FRIEND_TEST(StateTrackerTest, TestStateChange); }; } // namespace statsd } // namespace os } // namespace android