• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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