1 /* 2 * Copyright (C) 2019, 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 <utils/RefBase.h> 19 20 #include <set> 21 #include <unordered_map> 22 23 #include "HashableDimensionKey.h" 24 #include "logd/LogEvent.h" 25 #include "state/StateListener.h" 26 27 namespace android { 28 namespace os { 29 namespace statsd { 30 31 class StateTracker : public virtual RefBase { 32 public: 33 StateTracker(int32_t atomId); 34 ~StateTracker()35 virtual ~StateTracker(){}; 36 37 // Updates state map and notifies all listeners if a state change occurs. 38 // Checks if a state change has occurred by getting the state value from 39 // the log event and comparing the old and new states. 40 void onLogEvent(const LogEvent& event); 41 42 // Adds new listeners to set of StateListeners. If a listener is already 43 // registered, it is ignored. 44 void registerListener(const wp<StateListener>& listener); 45 46 void unregisterListener(const wp<StateListener>& listener); 47 48 // The output is a FieldValue object that has mStateField as the field and 49 // the original state value (found using the given query key) as the value. 50 // 51 // If the key isn't mapped to a state or the key size doesn't match the 52 // number of primary fields, the output value is set to kStateUnknown. 53 bool getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const; 54 getListenersCount()55 inline int getListenersCount() const { 56 return mListeners.size(); 57 } 58 59 const static int kStateUnknown = -1; 60 61 private: 62 struct StateValueInfo { 63 int32_t state = kStateUnknown; // state value 64 int count = 0; // nested count (only used for binary states) 65 }; 66 67 Field mField; 68 69 // Maps primary key to state value info 70 std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap; 71 72 // Set of all StateListeners (objects listening for state changes) 73 std::set<wp<StateListener>> mListeners; 74 75 // Reset all state values in map to the given state. 76 void handleReset(const int64_t eventTimeNs, const FieldValue& newState); 77 78 // Clears the state value mapped to the given primary key by setting it to kStateUnknown. 79 void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey); 80 81 // Update the StateMap based on the received state value. 82 void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, 83 const FieldValue& newState, const bool nested, 84 StateValueInfo& stateValueInfo); 85 86 // Notify registered state listeners of state change. 87 void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, 88 const FieldValue& oldState, const FieldValue& newState); 89 }; 90 91 bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output); 92 93 } // namespace statsd 94 } // namespace os 95 } // namespace android 96