• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2020, 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 
17 #ifndef CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_
18 #define CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_
19 
20 #include "WatchdogServiceHelper.h"
21 
22 #include <android-base/result.h>
23 #include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
24 #include <android/automotive/watchdog/internal/PackageInfo.h>
25 #include <binder/IBinder.h>
26 #include <gtest/gtest_prod.h>
27 #include <utils/Mutex.h>
28 #include <utils/RefBase.h>
29 #include <utils/StrongPointer.h>
30 
31 #include <pwd.h>
32 
33 #include <functional>
34 #include <shared_mutex>
35 #include <unordered_map>
36 #include <unordered_set>
37 
38 namespace android {
39 namespace automotive {
40 namespace watchdog {
41 
42 class ServiceManager;
43 class IoOveruseMonitor;
44 class IoOveruseConfigs;
45 
46 // Forward declaration for testing use only.
47 namespace internal {
48 
49 class PackageInfoResolverPeer;
50 
51 }  // namespace internal
52 
53 class IPackageInfoResolver : public android::RefBase {
54 public:
55     virtual std::unordered_map<uid_t, std::string> getPackageNamesForUids(
56             const std::vector<uid_t>& uids) = 0;
57     virtual std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
58     getPackageInfosForUids(const std::vector<uid_t>& uids) = 0;
59 
60 protected:
61     virtual android::base::Result<void> initWatchdogServiceHelper(
62             const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper) = 0;
63     virtual void setPackageConfigurations(
64             const std::unordered_set<std::string>& vendorPackagePrefixes,
65             const std::unordered_map<
66                     std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
67                     packagesToAppCategories) = 0;
68 
69 private:
70     friend class ServiceManager;
71     friend class IoOveruseMonitor;
72     friend class IoOveruseConfigs;
73 };
74 
75 /*
76  * PackageInfoResolver maintains a cache of the UID to PackageInfo mapping in the CarWatchdog
77  * daemon. PackageInfoResolver is a singleton and must be accessed only via the public static
78  * methods.
79  *
80  * TODO(b/158131194): Extend IUidObserver in WatchdogBinderMediator and use the onUidGone API to
81  *  keep the local mapping cache up-to-date.
82  */
83 class PackageInfoResolver : public IPackageInfoResolver {
84 public:
85     /*
86      * Initializes the PackageInfoResolver's singleton instance only on the first call. Main thread
87      * should make the first call as this method doesn't offer multi-threading protection.
88      */
89     static sp<IPackageInfoResolver> getInstance();
90 
91     /*
92      * Resolves the given |uids| and returns a mapping of uids to package names. If the mapping
93      * doesn't exist in the local cache, queries the car watchdog service for application uids and
94      * getpwuid for native uids. Logs any error observed during this process.
95      */
96     std::unordered_map<uid_t, std::string> getPackageNamesForUids(const std::vector<uid_t>& uids);
97 
98     /*
99      * Similar to getPackageNamesForUids, resolves the given |uids| and returns a mapping of uids to
100      * package infos.
101      */
102     std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
103     getPackageInfosForUids(const std::vector<uid_t>& uids);
104 
~PackageInfoResolver()105     ~PackageInfoResolver() {
106         std::unique_lock writeLock(mRWMutex);
107         mWatchdogServiceHelper.clear();
108         mUidToPackageInfoMapping.clear();
109     }
110 
111 protected:
112     static void terminate();
113 
114     android::base::Result<void> initWatchdogServiceHelper(
115             const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper);
116 
117     virtual void setPackageConfigurations(
118             const std::unordered_set<std::string>& vendorPackagePrefixes,
119             const std::unordered_map<
120                     std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
121                     packagesToAppCategories);
122 
123 private:
124     // PackageInfoResolver instance can only be obtained via |getInstance|.
PackageInfoResolver()125     PackageInfoResolver() :
126           mWatchdogServiceHelper(nullptr),
127           mUidToPackageInfoMapping({}),
128           mVendorPackagePrefixes({}) {}
129 
130     void updatePackageInfos(const std::vector<uid_t>& uids);
131 
132     // Singleton instance.
133     static android::sp<PackageInfoResolver> sInstance;
134 
135     mutable std::shared_mutex mRWMutex;
136 
137     /*
138      * ServiceManager::startServices initializes PackageInfoResolver. However, between the
139      * |getInstance| and |initWatchdogServiceHelper| calls it initializes few other services, which
140      * may call |getPackageNamesForUids| or |getPackageInfosForUids| simultaneously on a separate
141      * thread. In order to avoid a race condition between |initWatchdogServiceHelper| and
142      * |getPackage*ForUids| calls, mWatchdogServiceHelper is guarded by a read-write lock.
143      */
144     android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper GUARDED_BY(mRWMutex);
145     std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
146             mUidToPackageInfoMapping GUARDED_BY(mRWMutex);
147     std::vector<std::string> mVendorPackagePrefixes GUARDED_BY(mRWMutex);
148     std::unordered_map<std::string,
149                        android::automotive::watchdog::internal::ApplicationCategoryType>
150             mPackagesToAppCategories GUARDED_BY(mRWMutex);
151 
152     friend class ServiceManager;
153     friend class IoOveruseMonitor;
154     friend class IoOveruseConfigs;
155 
156     // For unit tests.
157     static std::function<struct passwd*(uid_t)> sGetpwuidHandler;
158 
159     friend class internal::PackageInfoResolverPeer;
160     FRIEND_TEST(PackageInfoResolverTest, TestResolvesNativeUid);
161     FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromWatchdogServiceHelper);
162     FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromLocalCache);
163 };
164 
165 }  // namespace watchdog
166 }  // namespace automotive
167 }  // namespace android
168 
169 #endif  //  CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_
170