diff options
Diffstat (limited to 'cmds/statsd/src/state/StateTracker.h')
-rw-r--r-- | cmds/statsd/src/state/StateTracker.h | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/cmds/statsd/src/state/StateTracker.h b/cmds/statsd/src/state/StateTracker.h new file mode 100644 index 000000000000..abd579e7e302 --- /dev/null +++ b/cmds/statsd/src/state/StateTracker.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2019, 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 <utils/RefBase.h> +#include "HashableDimensionKey.h" +#include "logd/LogEvent.h" + +#include "state/StateListener.h" + +#include <unordered_map> + +namespace android { +namespace os { +namespace statsd { + +class StateTracker : public virtual RefBase { +public: + StateTracker(const int32_t atomId); + + virtual ~StateTracker(){}; + + // Updates state map and notifies all listeners if a state change occurs. + // Checks if a state change has occurred by getting the state value from + // the log event and comparing the old and new states. + void onLogEvent(const LogEvent& event); + + // Adds new listeners to set of StateListeners. If a listener is already + // registered, it is ignored. + void registerListener(wp<StateListener> listener); + + void unregisterListener(wp<StateListener> listener); + + // The output is a FieldValue object that has mStateField as the field and + // the original state value (found using the given query key) as the value. + // + // If the key isn't mapped to a state or the key size doesn't match the + // number of primary fields, the output value is set to kStateUnknown. + bool getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const; + + inline int getListenersCount() const { + return mListeners.size(); + } + + const static int kStateUnknown = -1; + +private: + struct StateValueInfo { + int32_t state = kStateUnknown; // state value + int count = 0; // nested count (only used for binary states) + }; + + Field mField; + + // Maps primary key to state value info + std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap; + + // Set of all StateListeners (objects listening for state changes) + std::set<wp<StateListener>> mListeners; + + // Reset all state values in map to the given state. + void handleReset(const int64_t eventTimeNs, const FieldValue& newState); + + // Clears the state value mapped to the given primary key by setting it to kStateUnknown. + void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey); + + // Update the StateMap based on the received state value. + void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, + const FieldValue& newState, const bool nested, + StateValueInfo* stateValueInfo); + + // Notify registered state listeners of state change. + void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey, + const FieldValue& oldState, const FieldValue& newState); +}; + +bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output); + +} // namespace statsd +} // namespace os +} // namespace android |