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