167 lines
6.2 KiB
C++
167 lines
6.2 KiB
C++
/**
|
|
* Copyright (c) 2020, The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_
|
|
#define CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_
|
|
|
|
#include "WatchdogServiceHelper.h"
|
|
|
|
#include <android-base/result.h>
|
|
#include <android/automotive/watchdog/internal/ApplicationCategoryType.h>
|
|
#include <android/automotive/watchdog/internal/PackageInfo.h>
|
|
#include <binder/IBinder.h>
|
|
#include <gtest/gtest_prod.h>
|
|
#include <utils/Mutex.h>
|
|
#include <utils/RefBase.h>
|
|
#include <utils/StrongPointer.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <functional>
|
|
#include <shared_mutex>
|
|
#include <unordered_map>
|
|
#include <unordered_set>
|
|
|
|
namespace android {
|
|
namespace automotive {
|
|
namespace watchdog {
|
|
|
|
class ServiceManager;
|
|
class IoOveruseMonitor;
|
|
class IoOveruseConfigs;
|
|
|
|
// Forward declaration for testing use only.
|
|
namespace internal {
|
|
|
|
class PackageInfoResolverPeer;
|
|
|
|
} // namespace internal
|
|
|
|
class PackageInfoResolverInterface : public android::RefBase {
|
|
public:
|
|
virtual std::unordered_map<uid_t, std::string> getPackageNamesForUids(
|
|
const std::vector<uid_t>& uids) = 0;
|
|
virtual std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
|
|
getPackageInfosForUids(const std::vector<uid_t>& uids) = 0;
|
|
|
|
protected:
|
|
virtual android::base::Result<void> initWatchdogServiceHelper(
|
|
const android::sp<WatchdogServiceHelperInterface>& watchdogServiceHelper) = 0;
|
|
virtual void setPackageConfigurations(
|
|
const std::unordered_set<std::string>& vendorPackagePrefixes,
|
|
const std::unordered_map<
|
|
std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
|
|
packagesToAppCategories) = 0;
|
|
|
|
private:
|
|
friend class ServiceManager;
|
|
friend class IoOveruseMonitor;
|
|
friend class IoOveruseConfigs;
|
|
};
|
|
|
|
/*
|
|
* PackageInfoResolver maintains a cache of the UID to PackageInfo mapping in the CarWatchdog
|
|
* daemon. PackageInfoResolver is a singleton and must be accessed only via the public static
|
|
* methods.
|
|
*
|
|
* TODO(b/158131194): Extend IUidObserver in WatchdogBinderMediator and use the onUidGone API to
|
|
* keep the local mapping cache up-to-date.
|
|
*/
|
|
class PackageInfoResolver final : public PackageInfoResolverInterface {
|
|
public:
|
|
~PackageInfoResolver() {
|
|
std::unique_lock writeLock(mRWMutex);
|
|
mWatchdogServiceHelper.clear();
|
|
mUidToPackageInfoMapping.clear();
|
|
}
|
|
|
|
/*
|
|
* Initializes the PackageInfoResolver's singleton instance only on the first call. Main thread
|
|
* should make the first call as this method doesn't offer multi-threading protection.
|
|
*/
|
|
static sp<PackageInfoResolverInterface> getInstance();
|
|
|
|
android::base::Result<void> initWatchdogServiceHelper(
|
|
const android::sp<WatchdogServiceHelperInterface>& watchdogServiceHelper);
|
|
|
|
static void terminate();
|
|
|
|
/*
|
|
* Resolves the given |uids| and returns a mapping of uids to package names. If the mapping
|
|
* doesn't exist in the local cache, queries the car watchdog service for application uids and
|
|
* getpwuid for native uids. Logs any error observed during this process.
|
|
*/
|
|
std::unordered_map<uid_t, std::string> getPackageNamesForUids(const std::vector<uid_t>& uids);
|
|
|
|
/*
|
|
* Similar to getPackageNamesForUids, resolves the given |uids| and returns a mapping of uids to
|
|
* package infos.
|
|
*/
|
|
std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
|
|
getPackageInfosForUids(const std::vector<uid_t>& uids);
|
|
|
|
virtual void setPackageConfigurations(
|
|
const std::unordered_set<std::string>& vendorPackagePrefixes,
|
|
const std::unordered_map<
|
|
std::string, android::automotive::watchdog::internal::ApplicationCategoryType>&
|
|
packagesToAppCategories);
|
|
|
|
private:
|
|
// PackageInfoResolver instance can only be obtained via |getInstance|.
|
|
PackageInfoResolver() :
|
|
mWatchdogServiceHelper(nullptr),
|
|
mUidToPackageInfoMapping({}),
|
|
mVendorPackagePrefixes({}) {}
|
|
|
|
void updatePackageInfos(const std::vector<uid_t>& uids);
|
|
|
|
// Singleton instance.
|
|
static android::sp<PackageInfoResolver> sInstance;
|
|
|
|
mutable std::shared_mutex mRWMutex;
|
|
|
|
/*
|
|
* ServiceManager::startServices initializes PackageInfoResolver. However, between the
|
|
* |getInstance| and |initWatchdogServiceHelper| calls it initializes few other services, which
|
|
* may call |getPackageNamesForUids| or |getPackageInfosForUids| simultaneously on a separate
|
|
* thread. In order to avoid a race condition between |initWatchdogServiceHelper| and
|
|
* |getPackage*ForUids| calls, mWatchdogServiceHelper is guarded by a read-write lock.
|
|
*/
|
|
android::sp<WatchdogServiceHelperInterface> mWatchdogServiceHelper GUARDED_BY(mRWMutex);
|
|
std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
|
|
mUidToPackageInfoMapping GUARDED_BY(mRWMutex);
|
|
std::vector<std::string> mVendorPackagePrefixes GUARDED_BY(mRWMutex);
|
|
std::unordered_map<std::string,
|
|
android::automotive::watchdog::internal::ApplicationCategoryType>
|
|
mPackagesToAppCategories GUARDED_BY(mRWMutex);
|
|
|
|
friend class android::sp<PackageInfoResolver>;
|
|
|
|
// For unit tests.
|
|
static std::function<struct passwd*(uid_t)> sGetpwuidHandler;
|
|
|
|
friend class internal::PackageInfoResolverPeer;
|
|
FRIEND_TEST(PackageInfoResolverTest, TestResolvesNativeUid);
|
|
FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromWatchdogServiceHelper);
|
|
FRIEND_TEST(PackageInfoResolverTest, TestResolvesApplicationUidFromLocalCache);
|
|
};
|
|
|
|
} // namespace watchdog
|
|
} // namespace automotive
|
|
} // namespace android
|
|
|
|
#endif // CPP_WATCHDOG_SERVER_SRC_PACKAGEINFORESOLVER_H_
|