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