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 void onLogEventLost(DataCorruptedReason reason); 43 44 // Adds new listeners to set of StateListeners. If a listener is already 45 // registered, it is ignored. 46 void registerListener(const wp<StateListener>& listener); 47 48 void unregisterListener(const wp<StateListener>& listener); 49 50 // The output is a FieldValue object that has mStateField as the field and 51 // the original state value (found using the given query key) as the value. 52 // 53 // If the key isn't mapped to a state or the key size doesn't match the 54 // number of primary fields, the output value is set to kStateUnknown. 55 bool getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const; 56 getListenersCount()57 inline int getListenersCount() const { 58 return mListeners.size(); 59 } 60 61 const static int kStateUnknown = -1; 62 63 private: 64 struct StateValueInfo { 65 int32_t state = kStateUnknown; // state value 66 int count = 0; // nested count (only used for binary states) 67 }; 68 69 Field mField; 70 71 // Maps primary key to state value info 72 std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap; 73 74 // Set of all StateListeners (objects listening for state changes) 75 std::set<wp<StateListener>> mListeners; 76 77 // Reset all state values in map to the given state. 78 void handleReset(const int64_t eventTimeNs, const FieldValue& newState); 79 80 // Clears the state value mapped to the given primary key by setting it to kStateUnknown. 81 void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey); 82 83 // Update the StateMap based on the received state value. 84 void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, 85 const FieldValue& newState, const bool nested, 86 StateValueInfo& stateValueInfo); 87 88 // Notify registered state listeners of state change. 89 void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, 90 const FieldValue& oldState, const FieldValue& newState); 91 }; 92 93 bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output); 94 95 } // namespace statsd 96 } // namespace os 97 } // namespace android 98