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 <aidl/android/automotive/watchdog/internal/ApplicationCategoryType.h> 23 #include <aidl/android/automotive/watchdog/internal/PackageInfo.h> 24 #include <android-base/result.h> 25 #include <gtest/gtest_prod.h> 26 #include <utils/Mutex.h> 27 #include <utils/RefBase.h> 28 #include <utils/StrongPointer.h> 29 30 #include <pwd.h> 31 32 #include <functional> 33 #include <shared_mutex> 34 #include <unordered_map> 35 #include <unordered_set> 36 37 namespace android { 38 namespace automotive { 39 namespace watchdog { 40 41 class ServiceManager; 42 class IoOveruseMonitor; 43 class IoOveruseConfigs; 44 45 // Forward declaration for testing use only. 46 namespace internal { 47 48 class PackageInfoResolverPeer; 49 50 } // namespace internal 51 52 class PackageInfoResolverInterface : virtual public android::RefBase { 53 public: 54 virtual std::unordered_map<uid_t, std::string> getPackageNamesForUids( 55 const std::vector<uid_t>& uids) = 0; 56 virtual std::unordered_map<uid_t, aidl::android::automotive::watchdog::internal::PackageInfo> 57 getPackageInfosForUids(const std::vector<uid_t>& uids) = 0; 58 59 protected: 60 virtual android::base::Result<void> initWatchdogServiceHelper( 61 const android::sp<WatchdogServiceHelperInterface>& watchdogServiceHelper) = 0; 62 virtual void setPackageConfigurations( 63 const std::unordered_set<std::string>& vendorPackagePrefixes, 64 const std::unordered_map< 65 std::string, 66 aidl::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 car watchdog 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, aidl::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, 120 aidl::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<WatchdogServiceHelperInterface> mWatchdogServiceHelper GUARDED_BY(mRWMutex); 145 std::unordered_map<uid_t, aidl::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 aidl::android::automotive::watchdog::internal::ApplicationCategoryType> 150 mPackagesToAppCategories GUARDED_BY(mRWMutex); 151 152 // Required to instantiate the class in |getInstance|. 153 friend class android::sp<PackageInfoResolver>; 154 155 // For unit tests. 156 static std::function<struct passwd*(uid_t)> sGetpwuidHandler; 157 158 friend class internal::PackageInfoResolverPeer; 159 FRIEND_TEST(PackageInfoResolverTest, TestResolvesNativeUid); 160 FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromWatchdogServiceHelper); 161 FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromLocalCache); 162 }; 163 164 } // namespace watchdog 165 } // namespace automotive 166 } // namespace android 167 168 #endif // CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_ 169