summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot2017-09-30 03:14:55 -0500
committerandroid-build-team Robot2017-09-30 03:14:55 -0500
commit8f640d31fa0b1b8c5591cd6f10901506d18481cf (patch)
treea08b547d76318c717dbc71caacd2e7048a54eb38
parent1d845c3c5de4e5953da997fd0f405159c37dad76 (diff)
parente366ac3164b07f087e622bdeaa96a16251ed7036 (diff)
downloadplatform-system-libvintf-8f640d31fa0b1b8c5591cd6f10901506d18481cf.tar.gz
platform-system-libvintf-8f640d31fa0b1b8c5591cd6f10901506d18481cf.tar.xz
platform-system-libvintf-8f640d31fa0b1b8c5591cd6f10901506d18481cf.zip
release-request-b4bc7b84-64b6-4176-8f16-ce17068fad13-for-git_pi-release-4370135 snap-temp-L93500000107644030
Change-Id: If1355ec02d39ecaa1d192ce47907f054f77dc36a
-rw-r--r--RuntimeInfo-host.cpp2
-rw-r--r--RuntimeInfo-target.cpp44
-rw-r--r--VintfObject.cpp31
-rw-r--r--include/vintf/RuntimeInfo.h19
-rw-r--r--include/vintf/VintfObject.h13
-rw-r--r--test/RuntimeInfo-fake.cpp2
-rw-r--r--test/utils-fake.cpp2
-rw-r--r--test/utils-fake.h29
-rw-r--r--test/vintf_object_tests.cpp45
-rw-r--r--utils.cpp4
-rw-r--r--utils.h9
11 files changed, 170 insertions, 30 deletions
diff --git a/RuntimeInfo-host.cpp b/RuntimeInfo-host.cpp
index 96eff42..bd46a9f 100644
--- a/RuntimeInfo-host.cpp
+++ b/RuntimeInfo-host.cpp
@@ -23,7 +23,7 @@
23namespace android { 23namespace android {
24namespace vintf { 24namespace vintf {
25 25
26status_t RuntimeInfo::fetchAllInformation() { 26status_t RuntimeInfo::fetchAllInformation(RuntimeInfo::FetchFlags /* flags */) {
27 LOG(WARNING) << "Should not run fetchAllInformation on host."; 27 LOG(WARNING) << "Should not run fetchAllInformation on host.";
28 return OK; 28 return OK;
29} 29}
diff --git a/RuntimeInfo-target.cpp b/RuntimeInfo-target.cpp
index 9518a0c..1bdf2c3 100644
--- a/RuntimeInfo-target.cpp
+++ b/RuntimeInfo-target.cpp
@@ -45,8 +45,9 @@ namespace vintf {
45 45
46struct RuntimeInfoFetcher { 46struct RuntimeInfoFetcher {
47 RuntimeInfoFetcher(RuntimeInfo *ki) : mRuntimeInfo(ki) { } 47 RuntimeInfoFetcher(RuntimeInfo *ki) : mRuntimeInfo(ki) { }
48 status_t fetchAllInformation(); 48 status_t fetchAllInformation(RuntimeInfo::FetchFlags flags);
49private: 49
50 private:
50 status_t fetchVersion(); 51 status_t fetchVersion();
51 status_t fetchKernelConfigs(); 52 status_t fetchKernelConfigs();
52 status_t fetchCpuInfo(); 53 status_t fetchCpuInfo();
@@ -159,28 +160,31 @@ status_t RuntimeInfoFetcher::fetchAvb() {
159 return OK; 160 return OK;
160} 161}
161 162
162status_t RuntimeInfoFetcher::fetchAllInformation() { 163status_t RuntimeInfoFetcher::fetchAllInformation(RuntimeInfo::FetchFlags flags) {
164
165 using F = RuntimeInfo::FetchFlag;
166 using RF = RuntimeInfoFetcher;
167 using FetchFunction = status_t(RF::*)();
168 const static std::vector<std::tuple<F, FetchFunction, std::string>> gFetchFunctions({
169 // flag fetch function description
170 {F::CPU_VERSION, &RF::fetchVersion, "/proc/version"},
171 {F::CONFIG_GZ, &RF::fetchKernelConfigs, "/proc/config.gz"},
172 {F::CPU_INFO, &RF::fetchCpuInfo, "/proc/cpuinfo"},
173 {F::POLICYVERS, &RF::fetchKernelSepolicyVers, "kernel sepolicy version"},
174 {F::AVB, &RF::fetchAvb, "avb version"},
175 });
176
163 status_t err; 177 status_t err;
164 if ((err = fetchVersion()) != OK) { 178 for (const auto& tuple : gFetchFunctions)
165 LOG(WARNING) << "Cannot fetch or parse /proc/version: " << strerror(-err); 179 if ((flags & std::get<0>(tuple)) && (err = (*this.*std::get<1>(tuple))()) != OK)
166 } 180 LOG(WARNING) << "Cannot fetch or parse " << std::get<2>(tuple) << ": "
167 if ((err = fetchKernelConfigs()) != OK) { 181 << strerror(-err);
168 LOG(WARNING) << "Cannot fetch or parse /proc/config.gz: " << strerror(-err); 182
169 }
170 if ((err = fetchCpuInfo()) != OK) {
171 LOG(WARNING) << "Cannot fetch /proc/cpuinfo: " << strerror(-err);
172 }
173 if ((err = fetchKernelSepolicyVers()) != OK) {
174 LOG(WARNING) << "Cannot fetch kernel sepolicy version: " << strerror(-err);
175 }
176 if ((err = fetchAvb()) != OK) {
177 LOG(WARNING) << "Cannot fetch sepolicy avb version: " << strerror(-err);
178 }
179 return OK; 183 return OK;
180} 184}
181 185
182status_t RuntimeInfo::fetchAllInformation() { 186status_t RuntimeInfo::fetchAllInformation(RuntimeInfo::FetchFlags flags) {
183 return RuntimeInfoFetcher(this).fetchAllInformation(); 187 return RuntimeInfoFetcher(this).fetchAllInformation(flags);
184} 188}
185 189
186} // namespace vintf 190} // namespace vintf
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 92fa0b0..698bf30 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -33,6 +33,12 @@ struct LockedSharedPtr {
33 std::mutex mutex; 33 std::mutex mutex;
34}; 34};
35 35
36struct LockedRuntimeInfoCache {
37 std::shared_ptr<RuntimeInfo> object;
38 std::mutex mutex;
39 RuntimeInfo::FetchFlags fetchedFlags = RuntimeInfo::FetchFlag::NONE;
40};
41
36template <typename T, typename F> 42template <typename T, typename F>
37static std::shared_ptr<const T> Get( 43static std::shared_ptr<const T> Get(
38 LockedSharedPtr<T> *ptr, 44 LockedSharedPtr<T> *ptr,
@@ -82,10 +88,27 @@ std::shared_ptr<const CompatibilityMatrix> VintfObject::GetFrameworkCompatibilit
82} 88}
83 89
84// static 90// static
85std::shared_ptr<const RuntimeInfo> VintfObject::GetRuntimeInfo(bool skipCache) { 91std::shared_ptr<const RuntimeInfo> VintfObject::GetRuntimeInfo(bool skipCache,
86 static LockedSharedPtr<RuntimeInfo> gDeviceRuntimeInfo; 92 RuntimeInfo::FetchFlags flags) {
87 return Get(&gDeviceRuntimeInfo, skipCache, 93 static LockedRuntimeInfoCache gDeviceRuntimeInfo;
88 std::bind(&RuntimeInfo::fetchAllInformation, std::placeholders::_1)); 94 std::unique_lock<std::mutex> _lock(gDeviceRuntimeInfo.mutex);
95
96 if (!skipCache) {
97 flags &= (~gDeviceRuntimeInfo.fetchedFlags);
98 }
99
100 if (gDeviceRuntimeInfo.object == nullptr) {
101 gDeviceRuntimeInfo.object = details::gRuntimeInfoFactory->make_shared();
102 }
103
104 status_t status = gDeviceRuntimeInfo.object->fetchAllInformation(flags);
105 if (status != OK) {
106 gDeviceRuntimeInfo.fetchedFlags &= (~flags); // mark the fields as "not fetched"
107 return nullptr;
108 }
109
110 gDeviceRuntimeInfo.fetchedFlags |= flags;
111 return gDeviceRuntimeInfo.object;
89} 112}
90 113
91namespace details { 114namespace details {
diff --git a/include/vintf/RuntimeInfo.h b/include/vintf/RuntimeInfo.h
index 1505c15..68b6929 100644
--- a/include/vintf/RuntimeInfo.h
+++ b/include/vintf/RuntimeInfo.h
@@ -38,6 +38,7 @@ struct CompatibilityMatrix;
38struct RuntimeInfo { 38struct RuntimeInfo {
39 39
40 RuntimeInfo() {} 40 RuntimeInfo() {}
41 virtual ~RuntimeInfo() = default;
41 42
42 // /proc/version 43 // /proc/version
43 // utsname.sysname 44 // utsname.sysname
@@ -74,14 +75,28 @@ struct RuntimeInfo {
74 bool checkCompatibility(const CompatibilityMatrix& mat, std::string* error = nullptr, 75 bool checkCompatibility(const CompatibilityMatrix& mat, std::string* error = nullptr,
75 DisabledChecks disabledChecks = ENABLE_ALL_CHECKS) const; 76 DisabledChecks disabledChecks = ENABLE_ALL_CHECKS) const;
76 77
78 using FetchFlags = uint32_t;
79 enum FetchFlag : FetchFlags {
80 CPU_VERSION = 1 << 0,
81 CONFIG_GZ = 1 << 1,
82 CPU_INFO = 1 << 2,
83 POLICYVERS = 1 << 3,
84 AVB = 1 << 4,
85 LAST_PLUS_ONE,
86
87 NONE = 0,
88 ALL = ((LAST_PLUS_ONE - 1) << 1) - 1,
89 };
90
91 protected:
92 virtual status_t fetchAllInformation(FetchFlags flags);
93
77 private: 94 private:
78 friend struct RuntimeInfoFetcher; 95 friend struct RuntimeInfoFetcher;
79 friend class VintfObject; 96 friend class VintfObject;
80 friend struct LibVintfTest; 97 friend struct LibVintfTest;
81 friend std::string dump(const RuntimeInfo &ki); 98 friend std::string dump(const RuntimeInfo &ki);
82 99
83 status_t fetchAllInformation();
84
85 // mKernelVersion = x'.y'.z', minLts = x.y.z, 100 // mKernelVersion = x'.y'.z', minLts = x.y.z,
86 // match if x == x' , y == y' , and z <= z'. 101 // match if x == x' , y == y' , and z <= z'.
87 bool matchKernelVersion(const KernelVersion& minLts) const; 102 bool matchKernelVersion(const KernelVersion& minLts) const;
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index fe70784..5593da5 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -80,8 +80,19 @@ public:
80 80
81 /* 81 /*
82 * Return the API that access device runtime info. 82 * Return the API that access device runtime info.
83 *
84 * {skipCache == true, flags == ALL}: re-fetch everything
85 * {skipCache == false, flags == ALL}: fetch everything if not previously fetched
86 * {skipCache == true, flags == selected info}: re-fetch selected information
87 * if not previously fetched.
88 * {skipCache == false, flags == selected info}: fetch selected information
89 * if not previously fetched.
90 *
91 * @param skipCache do not fetch if previously fetched
92 * @param flags bitwise-or of RuntimeInfo::FetchFlag
83 */ 93 */
84 static std::shared_ptr<const RuntimeInfo> GetRuntimeInfo(bool skipCache = false); 94 static std::shared_ptr<const RuntimeInfo> GetRuntimeInfo(
95 bool skipCache = false, RuntimeInfo::FetchFlags flags = RuntimeInfo::FetchFlag::ALL);
85 96
86 /** 97 /**
87 * Check compatibility, given a set of manifests / matrices in packageInfo. 98 * Check compatibility, given a set of manifests / matrices in packageInfo.
diff --git a/test/RuntimeInfo-fake.cpp b/test/RuntimeInfo-fake.cpp
index 4fc568a..c13eac2 100644
--- a/test/RuntimeInfo-fake.cpp
+++ b/test/RuntimeInfo-fake.cpp
@@ -20,7 +20,7 @@ namespace android {
20namespace vintf { 20namespace vintf {
21 21
22// Fake implementation used for testing. 22// Fake implementation used for testing.
23status_t RuntimeInfo::fetchAllInformation() { 23status_t RuntimeInfo::fetchAllInformation(RuntimeInfo::FetchFlags) {
24 mOsName = "Linux"; 24 mOsName = "Linux";
25 mNodeName = "localhost"; 25 mNodeName = "localhost";
26 mOsRelease = "3.18.31-g936f9a479d0f"; 26 mOsRelease = "3.18.31-g936f9a479d0f";
diff --git a/test/utils-fake.cpp b/test/utils-fake.cpp
index 3f4f3c1..151b3bf 100644
--- a/test/utils-fake.cpp
+++ b/test/utils-fake.cpp
@@ -26,6 +26,8 @@ FileFetcher* gFetcher = nullptr;
26 26
27PartitionMounter* gPartitionMounter = nullptr; 27PartitionMounter* gPartitionMounter = nullptr;
28 28
29ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = nullptr;
30
29} // namespace details 31} // namespace details
30} // namespace vintf 32} // namespace vintf
31} // namespace android 33} // namespace android
diff --git a/test/utils-fake.h b/test/utils-fake.h
index a3cd3d7..dd93542 100644
--- a/test/utils-fake.h
+++ b/test/utils-fake.h
@@ -78,6 +78,35 @@ class MockPartitionMounter : public PartitionMounter {
78 bool vendorMounted_; 78 bool vendorMounted_;
79}; 79};
80 80
81class MockRuntimeInfo : public RuntimeInfo {
82 public:
83 MockRuntimeInfo() {
84 ON_CALL(*this, fetchAllInformation(_))
85 .WillByDefault(Invoke(this, &MockRuntimeInfo::doFetch));
86 }
87 MOCK_METHOD1(fetchAllInformation, status_t(RuntimeInfo::FetchFlags));
88 status_t doFetch(RuntimeInfo::FetchFlags flags) {
89 if (failNextFetch_) {
90 failNextFetch_ = false;
91 return android::UNKNOWN_ERROR;
92 }
93 return RuntimeInfo::fetchAllInformation(flags);
94 }
95 void failNextFetch() { failNextFetch_ = true; }
96
97 private:
98 bool failNextFetch_ = false;
99};
100class MockRuntimeInfoFactory : public ObjectFactory<RuntimeInfo> {
101 public:
102 MockRuntimeInfoFactory(const std::shared_ptr<MockRuntimeInfo>& info) { object_ = info; }
103 std::shared_ptr<RuntimeInfo> make_shared() const override { return object_; }
104 std::shared_ptr<MockRuntimeInfo> getInfo() const { return object_; }
105
106 private:
107 std::shared_ptr<MockRuntimeInfo> object_;
108};
109
81} // namespace details 110} // namespace details
82} // namespace vintf 111} // namespace vintf
83} // namespace android 112} // namespace android
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index ef65e52..aa11b6f 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -201,7 +201,6 @@ static MockPartitionMounter &mounter() {
201static MockFileFetcher &fetcher() { 201static MockFileFetcher &fetcher() {
202 return *static_cast<MockFileFetcher*>(gFetcher); 202 return *static_cast<MockFileFetcher*>(gFetcher);
203} 203}
204
205// Test fixture that provides compatible metadata from the mock device. 204// Test fixture that provides compatible metadata from the mock device.
206class VintfObjectCompatibleTest : public testing::Test { 205class VintfObjectCompatibleTest : public testing::Test {
207 protected: 206 protected:
@@ -439,6 +438,46 @@ TEST_F(VintfObjectIncompatibleTest, TestInputVsDeviceSuccess) {
439 ASSERT_STREQ(error.c_str(), ""); 438 ASSERT_STREQ(error.c_str(), "");
440} 439}
441 440
441static MockRuntimeInfoFactory& runtimeInfoFactory() {
442 return *static_cast<MockRuntimeInfoFactory*>(gRuntimeInfoFactory);
443}
444
445// Test fixture that provides compatible metadata from the mock device.
446class VintfObjectRuntimeInfoTest : public testing::Test {
447 protected:
448 virtual void SetUp() {
449 // clear fetch flags
450 runtimeInfoFactory().getInfo()->failNextFetch();
451 VintfObject::GetRuntimeInfo(true /* skipCache */, RuntimeInfo::FetchFlag::ALL);
452 }
453 virtual void TearDown() {
454 Mock::VerifyAndClear(&runtimeInfoFactory());
455 Mock::VerifyAndClear(runtimeInfoFactory().getInfo().get());
456 }
457};
458
459TEST_F(VintfObjectRuntimeInfoTest, GetRuntimeInfo) {
460 InSequence s;
461
462 EXPECT_CALL(*runtimeInfoFactory().getInfo(),
463 fetchAllInformation(RuntimeInfo::FetchFlag::CPU_VERSION));
464 EXPECT_CALL(*runtimeInfoFactory().getInfo(), fetchAllInformation(RuntimeInfo::FetchFlag::NONE));
465 EXPECT_CALL(*runtimeInfoFactory().getInfo(),
466 fetchAllInformation(RuntimeInfo::FetchFlag::CPU_VERSION));
467 EXPECT_CALL(
468 *runtimeInfoFactory().getInfo(),
469 fetchAllInformation(RuntimeInfo::FetchFlag::ALL & ~RuntimeInfo::FetchFlag::CPU_VERSION));
470 EXPECT_CALL(*runtimeInfoFactory().getInfo(), fetchAllInformation(RuntimeInfo::FetchFlag::ALL));
471 EXPECT_CALL(*runtimeInfoFactory().getInfo(), fetchAllInformation(RuntimeInfo::FetchFlag::NONE));
472
473 VintfObject::GetRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::CPU_VERSION);
474 VintfObject::GetRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::CPU_VERSION);
475 VintfObject::GetRuntimeInfo(true /* skipCache */, RuntimeInfo::FetchFlag::CPU_VERSION);
476 VintfObject::GetRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::ALL);
477 VintfObject::GetRuntimeInfo(true /* skipCache */, RuntimeInfo::FetchFlag::ALL);
478 VintfObject::GetRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::ALL);
479}
480
442int main(int argc, char** argv) { 481int main(int argc, char** argv) {
443 ::testing::InitGoogleMock(&argc, argv); 482 ::testing::InitGoogleMock(&argc, argv);
444 483
@@ -448,5 +487,9 @@ int main(int argc, char** argv) {
448 NiceMock<MockPartitionMounter> mounter; 487 NiceMock<MockPartitionMounter> mounter;
449 gPartitionMounter = &mounter; 488 gPartitionMounter = &mounter;
450 489
490 NiceMock<MockRuntimeInfoFactory> runtimeInfoFactory(
491 std::make_shared<NiceMock<MockRuntimeInfo>>());
492 gRuntimeInfoFactory = &runtimeInfoFactory;
493
451 return RUN_ALL_TESTS(); 494 return RUN_ALL_TESTS();
452} 495}
diff --git a/utils.cpp b/utils.cpp
index 9b20b01..2b0cb37 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -25,6 +25,10 @@ FileFetcher* gFetcher = &fetcher;
25 25
26static PartitionMounter partitionMounter; 26static PartitionMounter partitionMounter;
27PartitionMounter* gPartitionMounter = &partitionMounter; 27PartitionMounter* gPartitionMounter = &partitionMounter;
28
29static ObjectFactory<RuntimeInfo> runtimeInfoFactory;
30ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = &runtimeInfoFactory;
31
28} // namespace details 32} // namespace details
29} // namespace vintf 33} // namespace vintf
30} // namespace android 34} // namespace android
diff --git a/utils.h b/utils.h
index 9208b6a..973c524 100644
--- a/utils.h
+++ b/utils.h
@@ -24,6 +24,7 @@
24#include <android-base/logging.h> 24#include <android-base/logging.h>
25#include <utils/Errors.h> 25#include <utils/Errors.h>
26 26
27#include "RuntimeInfo.h"
27#include "parse_xml.h" 28#include "parse_xml.h"
28 29
29namespace android { 30namespace android {
@@ -91,6 +92,14 @@ status_t fetchAllInformation(const std::string& path, const XmlConverter<T>& con
91 return OK; 92 return OK;
92} 93}
93 94
95template <typename T>
96class ObjectFactory {
97 public:
98 virtual ~ObjectFactory() = default;
99 virtual std::shared_ptr<T> make_shared() const { return std::make_shared<T>(); }
100};
101extern ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory;
102
94} // namespace details 103} // namespace details
95} // namespace vintf 104} // namespace vintf
96} // namespace android 105} // namespace android