diff options
author | android-build-team Robot | 2017-09-30 03:14:55 -0500 |
---|---|---|
committer | android-build-team Robot | 2017-09-30 03:14:55 -0500 |
commit | 8f640d31fa0b1b8c5591cd6f10901506d18481cf (patch) | |
tree | a08b547d76318c717dbc71caacd2e7048a54eb38 | |
parent | 1d845c3c5de4e5953da997fd0f405159c37dad76 (diff) | |
parent | e366ac3164b07f087e622bdeaa96a16251ed7036 (diff) | |
download | platform-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.cpp | 2 | ||||
-rw-r--r-- | RuntimeInfo-target.cpp | 44 | ||||
-rw-r--r-- | VintfObject.cpp | 31 | ||||
-rw-r--r-- | include/vintf/RuntimeInfo.h | 19 | ||||
-rw-r--r-- | include/vintf/VintfObject.h | 13 | ||||
-rw-r--r-- | test/RuntimeInfo-fake.cpp | 2 | ||||
-rw-r--r-- | test/utils-fake.cpp | 2 | ||||
-rw-r--r-- | test/utils-fake.h | 29 | ||||
-rw-r--r-- | test/vintf_object_tests.cpp | 45 | ||||
-rw-r--r-- | utils.cpp | 4 | ||||
-rw-r--r-- | utils.h | 9 |
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 @@ | |||
23 | namespace android { | 23 | namespace android { |
24 | namespace vintf { | 24 | namespace vintf { |
25 | 25 | ||
26 | status_t RuntimeInfo::fetchAllInformation() { | 26 | status_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 | ||
46 | struct RuntimeInfoFetcher { | 46 | struct RuntimeInfoFetcher { |
47 | RuntimeInfoFetcher(RuntimeInfo *ki) : mRuntimeInfo(ki) { } | 47 | RuntimeInfoFetcher(RuntimeInfo *ki) : mRuntimeInfo(ki) { } |
48 | status_t fetchAllInformation(); | 48 | status_t fetchAllInformation(RuntimeInfo::FetchFlags flags); |
49 | private: | 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 | ||
162 | status_t RuntimeInfoFetcher::fetchAllInformation() { | 163 | status_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 | ||
182 | status_t RuntimeInfo::fetchAllInformation() { | 186 | status_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 | ||
36 | struct LockedRuntimeInfoCache { | ||
37 | std::shared_ptr<RuntimeInfo> object; | ||
38 | std::mutex mutex; | ||
39 | RuntimeInfo::FetchFlags fetchedFlags = RuntimeInfo::FetchFlag::NONE; | ||
40 | }; | ||
41 | |||
36 | template <typename T, typename F> | 42 | template <typename T, typename F> |
37 | static std::shared_ptr<const T> Get( | 43 | static 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 |
85 | std::shared_ptr<const RuntimeInfo> VintfObject::GetRuntimeInfo(bool skipCache) { | 91 | std::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 | ||
91 | namespace details { | 114 | namespace 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; | |||
38 | struct RuntimeInfo { | 38 | struct 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 { | |||
20 | namespace vintf { | 20 | namespace vintf { |
21 | 21 | ||
22 | // Fake implementation used for testing. | 22 | // Fake implementation used for testing. |
23 | status_t RuntimeInfo::fetchAllInformation() { | 23 | status_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 | ||
27 | PartitionMounter* gPartitionMounter = nullptr; | 27 | PartitionMounter* gPartitionMounter = nullptr; |
28 | 28 | ||
29 | ObjectFactory<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 | ||
81 | class 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 | }; | ||
100 | class 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() { | |||
201 | static MockFileFetcher &fetcher() { | 201 | static 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. |
206 | class VintfObjectCompatibleTest : public testing::Test { | 205 | class 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 | ||
441 | static MockRuntimeInfoFactory& runtimeInfoFactory() { | ||
442 | return *static_cast<MockRuntimeInfoFactory*>(gRuntimeInfoFactory); | ||
443 | } | ||
444 | |||
445 | // Test fixture that provides compatible metadata from the mock device. | ||
446 | class 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 | |||
459 | TEST_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 | |||
442 | int main(int argc, char** argv) { | 481 | int 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 | } |
@@ -25,6 +25,10 @@ FileFetcher* gFetcher = &fetcher; | |||
25 | 25 | ||
26 | static PartitionMounter partitionMounter; | 26 | static PartitionMounter partitionMounter; |
27 | PartitionMounter* gPartitionMounter = &partitionMounter; | 27 | PartitionMounter* gPartitionMounter = &partitionMounter; |
28 | |||
29 | static ObjectFactory<RuntimeInfo> runtimeInfoFactory; | ||
30 | ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory = &runtimeInfoFactory; | ||
31 | |||
28 | } // namespace details | 32 | } // namespace details |
29 | } // namespace vintf | 33 | } // namespace vintf |
30 | } // namespace android | 34 | } // namespace android |
@@ -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 | ||
29 | namespace android { | 30 | namespace 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 | ||
95 | template <typename T> | ||
96 | class ObjectFactory { | ||
97 | public: | ||
98 | virtual ~ObjectFactory() = default; | ||
99 | virtual std::shared_ptr<T> make_shared() const { return std::make_shared<T>(); } | ||
100 | }; | ||
101 | extern ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory; | ||
102 | |||
94 | } // namespace details | 103 | } // namespace details |
95 | } // namespace vintf | 104 | } // namespace vintf |
96 | } // namespace android | 105 | } // namespace android |