Allow RuntimeInfo::fetch to fetch conditionally
... to avoid unnecessary denials if the caller process does
not have enough permissions.
Test: CtsDeviceInfo
Bug: 66960848
Change-Id: I5555307ff086fbc10cfa677c530dc3de673e18f6
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 92fa0b0..e87dd05 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -33,6 +33,12 @@
std::mutex mutex;
};
+struct LockedRuntimeInfoCache {
+ std::shared_ptr<RuntimeInfo> object;
+ std::mutex mutex;
+ RuntimeInfo::FetchFlags fetchedFlags = RuntimeInfo::FetchFlag::NONE;
+};
+
template <typename T, typename F>
static std::shared_ptr<const T> Get(
LockedSharedPtr<T> *ptr,
@@ -82,10 +88,27 @@
}
// static
-std::shared_ptr<const RuntimeInfo> VintfObject::GetRuntimeInfo(bool skipCache) {
- static LockedSharedPtr<RuntimeInfo> gDeviceRuntimeInfo;
- return Get(&gDeviceRuntimeInfo, skipCache,
- std::bind(&RuntimeInfo::fetchAllInformation, std::placeholders::_1));
+std::shared_ptr<const RuntimeInfo> VintfObject::GetRuntimeInfo(bool skipCache,
+ RuntimeInfo::FetchFlags flags) {
+ static LockedRuntimeInfoCache gDeviceRuntimeInfo;
+ std::unique_lock<std::mutex> _lock(gDeviceRuntimeInfo.mutex);
+
+ if (!skipCache) {
+ flags &= (~gDeviceRuntimeInfo.fetchedFlags);
+ }
+
+ if (gDeviceRuntimeInfo.object == nullptr) {
+ gDeviceRuntimeInfo.object = std::make_shared<RuntimeInfo>();
+ }
+
+ status_t status = gDeviceRuntimeInfo.object->fetchAllInformation(flags);
+ if (status != OK) {
+ gDeviceRuntimeInfo.fetchedFlags &= (~flags); // mark the fields as "not fetched"
+ return nullptr;
+ }
+
+ gDeviceRuntimeInfo.fetchedFlags |= flags;
+ return gDeviceRuntimeInfo.object;
}
namespace details {