blob: abd579e7e3027278af0bbbe847703af844d812c4 [file] [log] [blame]
tsaichristine10978642019-09-10 14:12:49 -07001/*
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
tsaichristine10978642019-09-10 14:12:49 -070018#include <utils/RefBase.h>
19#include "HashableDimensionKey.h"
20#include "logd/LogEvent.h"
21
22#include "state/StateListener.h"
23
24#include <unordered_map>
25
26namespace android {
27namespace os {
28namespace statsd {
29
30class StateTracker : public virtual RefBase {
31public:
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070032 StateTracker(const int32_t atomId);
tsaichristine10978642019-09-10 14:12:49 -070033
34 virtual ~StateTracker(){};
35
36 // Updates state map and notifies all listeners if a state change occurs.
37 // Checks if a state change has occurred by getting the state value from
38 // the log event and comparing the old and new states.
39 void onLogEvent(const LogEvent& event);
40
41 // Adds new listeners to set of StateListeners. If a listener is already
42 // registered, it is ignored.
43 void registerListener(wp<StateListener> listener);
44
45 void unregisterListener(wp<StateListener> listener);
46
tsaichristine69000e62019-10-18 17:34:52 -070047 // The output is a FieldValue object that has mStateField as the field and
48 // the original state value (found using the given query key) as the value.
49 //
tsaichristine10978642019-09-10 14:12:49 -070050 // If the key isn't mapped to a state or the key size doesn't match the
tsaichristine69000e62019-10-18 17:34:52 -070051 // number of primary fields, the output value is set to kStateUnknown.
52 bool getStateValue(const HashableDimensionKey& queryKey, FieldValue* output) const;
tsaichristine10978642019-09-10 14:12:49 -070053
54 inline int getListenersCount() const {
55 return mListeners.size();
56 }
57
58 const static int kStateUnknown = -1;
59
60private:
61 struct StateValueInfo {
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070062 int32_t state = kStateUnknown; // state value
63 int count = 0; // nested count (only used for binary states)
tsaichristine10978642019-09-10 14:12:49 -070064 };
65
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070066 Field mField;
tsaichristine5adc7e02020-01-14 17:07:39 -080067
tsaichristine10978642019-09-10 14:12:49 -070068 // Maps primary key to state value info
69 std::unordered_map<HashableDimensionKey, StateValueInfo> mStateMap;
70
71 // Set of all StateListeners (objects listening for state changes)
72 std::set<wp<StateListener>> mListeners;
73
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070074 // Reset all state values in map to the given state.
tsaichristine9f951052020-05-13 14:32:37 -070075 void handleReset(const int64_t eventTimeNs, const FieldValue& newState);
tsaichristine10978642019-09-10 14:12:49 -070076
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070077 // Clears the state value mapped to the given primary key by setting it to kStateUnknown.
78 void clearStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey);
tsaichristine10978642019-09-10 14:12:49 -070079
80 // Update the StateMap based on the received state value.
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070081 void updateStateForPrimaryKey(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
tsaichristine9f951052020-05-13 14:32:37 -070082 const FieldValue& newState, const bool nested,
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070083 StateValueInfo* stateValueInfo);
84
85 // Notify registered state listeners of state change.
86 void notifyListeners(const int64_t eventTimeNs, const HashableDimensionKey& primaryKey,
tsaichristine9f951052020-05-13 14:32:37 -070087 const FieldValue& oldState, const FieldValue& newState);
tsaichristine10978642019-09-10 14:12:49 -070088};
89
Muhammad Qureshibfc4bdb2020-04-08 06:26:49 -070090bool getStateFieldValueFromLogEvent(const LogEvent& event, FieldValue* output);
91
tsaichristine10978642019-09-10 14:12:49 -070092} // namespace statsd
93} // namespace os
94} // namespace android