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 <inttypes.h>
19 #include <utils/RefBase.h>
20 
21 #include <set>
22 #include <string>
23 #include <unordered_map>
24 
25 #include "HashableDimensionKey.h"
26 #include "packages/UidMap.h"
27 #include "state/StateListener.h"
28 #include "state/StateTracker.h"
29 
30 namespace android {
31 namespace os {
32 namespace statsd {
33 
34 /**
35  * This class is NOT thread safe.
36  * It should only be used while StatsLogProcessor's lock is held.
37  */
38 class StateManager : public virtual RefBase {
39 public:
40     StateManager();
41 
~StateManager()42     ~StateManager(){};
43 
44     // Returns a pointer to the single, shared StateManager object.
45     static StateManager& getInstance();
46 
47     // Unregisters all listeners and removes all trackers from StateManager.
48     void clear();
49 
50     // Notifies the correct StateTracker of an event.
51     void onLogEvent(const LogEvent& event);
52 
53     // Notifies the StateTracker for the given atomId to register listener.
54     // If the correct StateTracker does not exist, a new StateTracker is created.
55     // Note: StateTrackers can be created for non-state atoms. They are essentially empty and
56     // do not perform any actions.
57     void registerListener(const int32_t atomId, wp<StateListener> listener);
58 
59     // Notifies the correct StateTracker to unregister a listener
60     // and removes the tracker if it no longer has any listeners.
61     void unregisterListener(const int32_t atomId, wp<StateListener> listener);
62 
63     // Returns true if the StateTracker exists and queries for the
64     // original state value mapped to the given query key. The state value is
65     // stored and output in a FieldValue class.
66     // Returns false if the StateTracker doesn't exist.
67     bool getStateValue(const int32_t atomId, const HashableDimensionKey& queryKey,
68                        FieldValue* output) const;
69 
70     // Updates mAllowedLogSources with the latest uids for the packages that are allowed to log.
71     void updateLogSources(const sp<UidMap>& uidMap);
72 
73     void notifyAppChanged(const string& apk, const sp<UidMap>& uidMap);
74 
getStateTrackersCount()75     inline int getStateTrackersCount() const {
76         return mStateTrackers.size();
77     }
78 
getListenersCount(const int32_t atomId)79     inline int getListenersCount(const int32_t atomId) const {
80         auto it = mStateTrackers.find(atomId);
81         if (it != mStateTrackers.end()) {
82             return it->second->getListenersCount();
83         }
84         return -1;
85     }
86 
87 private:
88     mutable std::mutex mMutex;
89 
90     // Maps state atom ids to StateTrackers
91     std::unordered_map<int32_t, sp<StateTracker>> mStateTrackers;
92 
93     // The package names that can log state events.
94     const std::set<std::string> mAllowedPkg;
95 
96     // The combined uid sources (after translating pkg name to uid).
97     // State events from uids that are not in the list will be ignored to avoid state pollution.
98     std::set<int32_t> mAllowedLogSources;
99 };
100 
101 }  // namespace statsd
102 }  // namespace os
103 }  // namespace android
104