• 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 PackageInfoResolverInterface : 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<WatchdogServiceHelperInterface>& 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 final : public PackageInfoResolverInterface {
84 public:
~PackageInfoResolver()85     ~PackageInfoResolver() {
86         std::unique_lock writeLock(mRWMutex);
87         mWatchdogServiceHelper.clear();
88         mUidToPackageInfoMapping.clear();
89     }
90 
91     /*
92      * Initializes the PackageInfoResolver's singleton instance only on the first call. Main thread
93      * should make the first call as this method doesn't offer multi-threading protection.
94      */
95     static sp<PackageInfoResolverInterface> getInstance();
96 
97     android::base::Result<void> initWatchdogServiceHelper(
98             const android::sp<WatchdogServiceHelperInterface>& watchdogServiceHelper);
99 
100     static void terminate();
101 
102     /*
103      * Resolves the given |uids| and returns a mapping of uids to package names. If the mapping
104      * doesn't exist in the local cache, queries the car watchdog service for application uids and
105      * getpwuid for native uids. Logs any error observed during this process.
106      */
107     std::unordered_map<uid_t, std::string> getPackageNamesForUids(const std::vector<uid_t>& uids);
108 
109     /*
110      * Similar to getPackageNamesForUids, resolves the given |uids| and returns a mapping of uids to
111      * package infos.
112      */
113     std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
114     getPackageInfosForUids(const std::vector<uid_t>& uids);
115 
116     virtual void setPackageConfigurations(
117             const std::unordered_set<std::string>& vendorPackagePrefixes,
118             const std::unordered_map<
119                     std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
120                     packagesToAppCategories);
121 
122 private:
123     // PackageInfoResolver instance can only be obtained via |getInstance|.
PackageInfoResolver()124     PackageInfoResolver() :
125           mWatchdogServiceHelper(nullptr),
126           mUidToPackageInfoMapping({}),
127           mVendorPackagePrefixes({}) {}
128 
129     void updatePackageInfos(const std::vector<uid_t>& uids);
130 
131     // Singleton instance.
132     static android::sp<PackageInfoResolver> sInstance;
133 
134     mutable std::shared_mutex mRWMutex;
135 
136     /*
137      * ServiceManager::startServices initializes PackageInfoResolver. However, between the
138      * |getInstance| and |initWatchdogServiceHelper| calls it initializes few other services, which
139      * may call |getPackageNamesForUids| or |getPackageInfosForUids| simultaneously on a separate
140      * thread. In order to avoid a race condition between |initWatchdogServiceHelper| and
141      * |getPackage*ForUids| calls, mWatchdogServiceHelper is guarded by a read-write lock.
142      */
143     android::sp<WatchdogServiceHelperInterface> mWatchdogServiceHelper GUARDED_BY(mRWMutex);
144     std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
145             mUidToPackageInfoMapping GUARDED_BY(mRWMutex);
146     std::vector<std::string> mVendorPackagePrefixes GUARDED_BY(mRWMutex);
147     std::unordered_map<std::string,
148                        android::automotive::watchdog::internal::ApplicationCategoryType>
149             mPackagesToAppCategories GUARDED_BY(mRWMutex);
150 
151     friend class android::sp<PackageInfoResolver>;
152 
153     // For unit tests.
154     static std::function<struct passwd*(uid_t)> sGetpwuidHandler;
155 
156     friend class internal::PackageInfoResolverPeer;
157     FRIEND_TEST(PackageInfoResolverTest, TestResolvesNativeUid);
158     FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromWatchdogServiceHelper);
159     FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromLocalCache);
160 };
161 
162 }  // namespace watchdog
163 }  // namespace automotive
164 }  // namespace android
165 
166 #endif  //  CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_
167