summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.bp31
-rw-r--r--CompatibilityMatrix.cpp7
-rw-r--r--HalManifest.cpp6
-rw-r--r--RuntimeInfo-host.cpp2
-rw-r--r--RuntimeInfo-target.cpp44
-rw-r--r--VintfObject.cpp82
-rw-r--r--check_vintf.cpp68
-rw-r--r--include/vintf/CompatibilityMatrix.h3
-rw-r--r--include/vintf/HalManifest.h7
-rw-r--r--include/vintf/RuntimeInfo.h19
-rw-r--r--include/vintf/VintfObject.h27
-rw-r--r--include/vintf/constants.h31
-rw-r--r--main.cpp10
-rw-r--r--parse_xml.cpp20
-rw-r--r--test/Android.bp2
-rw-r--r--test/RuntimeInfo-fake.cpp2
-rw-r--r--test/main.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.h12
22 files changed, 363 insertions, 92 deletions
diff --git a/Android.bp b/Android.bp
index a6bfe7f..7b6213e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -16,15 +16,18 @@ subdirs = [
16 "test" 16 "test"
17] 17]
18 18
19libvintf_flags = [ 19cc_defaults {
20 "-Wall", 20 name: "libvintf-defaults",
21 "-Werror", 21 cflags: [
22] 22 "-Wall",
23 "-Werror",
24 ],
25}
23 26
24cc_library { 27cc_library {
25 name: "libvintf", 28 name: "libvintf",
26 host_supported: true, 29 host_supported: true,
27 cflags: libvintf_flags, 30 defaults: ["libvintf-defaults"],
28 shared_libs: [ 31 shared_libs: [
29 "libbase", 32 "libbase",
30 "liblog", 33 "liblog",
@@ -77,7 +80,7 @@ cc_library {
77 80
78cc_binary { 81cc_binary {
79 name: "vintf", 82 name: "vintf",
80 cflags: libvintf_flags, 83 defaults: ["libvintf-defaults"],
81 shared_libs: [ 84 shared_libs: [
82 "libvintf", 85 "libvintf",
83 ], 86 ],
@@ -87,8 +90,21 @@ cc_binary {
87} 90}
88 91
89cc_binary_host { 92cc_binary_host {
93 name: "checkvintf",
94 defaults: ["libvintf-defaults"],
95 shared_libs: [
96 "libvintf",
97 "libbase"
98 ],
99 srcs: [
100 "check_vintf.cpp",
101 "utils.cpp"
102 ],
103}
104
105cc_binary_host {
90 name: "assemble_vintf", 106 name: "assemble_vintf",
91 cflags: libvintf_flags, 107 defaults: ["libvintf-defaults"],
92 shared_libs: [ 108 shared_libs: [
93 "libvintf", 109 "libvintf",
94 "libbase", 110 "libbase",
@@ -100,6 +116,7 @@ cc_binary_host {
100 116
101cc_library { 117cc_library {
102 name: "libvintftest", 118 name: "libvintftest",
119 defaults: ["libvintf-defaults"],
103 host_supported: true, 120 host_supported: true,
104 shared_libs: [ 121 shared_libs: [
105 "libbase", 122 "libbase",
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index f320861..73d0384 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -22,8 +22,6 @@
22namespace android { 22namespace android {
23namespace vintf { 23namespace vintf {
24 24
25constexpr Version CompatibilityMatrix::kVersion;
26
27bool CompatibilityMatrix::add(MatrixHal &&hal) { 25bool CompatibilityMatrix::add(MatrixHal &&hal) {
28 return HalGroup<MatrixHal>::add(std::move(hal)); 26 return HalGroup<MatrixHal>::add(std::move(hal));
29} 27}
@@ -40,6 +38,11 @@ SchemaType CompatibilityMatrix::type() const {
40 return mType; 38 return mType;
41} 39}
42 40
41Version CompatibilityMatrix::getMinimumMetaVersion() const {
42 // TODO(b/62801658): this needs to depend on whether there are 1.1 requirements
43 // (e.g. required <xmlfile> entry)
44 return {1, 0};
45}
43 46
44status_t CompatibilityMatrix::fetchAllInformation(const std::string &path) { 47status_t CompatibilityMatrix::fetchAllInformation(const std::string &path) {
45 return details::fetchAllInformation(path, gCompatibilityMatrixConverter, this); 48 return details::fetchAllInformation(path, gCompatibilityMatrixConverter, this);
diff --git a/HalManifest.cpp b/HalManifest.cpp
index f0fcf3f..4345d7a 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -32,8 +32,6 @@
32namespace android { 32namespace android {
33namespace vintf { 33namespace vintf {
34 34
35constexpr Version HalManifest::kVersion;
36
37// Check <version> tag for all <hal> with the same name. 35// Check <version> tag for all <hal> with the same name.
38bool HalManifest::shouldAdd(const ManifestHal& hal) const { 36bool HalManifest::shouldAdd(const ManifestHal& hal) const {
39 if (!hal.isValid()) { 37 if (!hal.isValid()) {
@@ -364,6 +362,10 @@ SchemaType HalManifest::type() const {
364 return mType; 362 return mType;
365} 363}
366 364
365Version HalManifest::getMetaVersion() const {
366 return mMetaVersion;
367}
368
367const Version &HalManifest::sepolicyVersion() const { 369const Version &HalManifest::sepolicyVersion() const {
368 CHECK(mType == SchemaType::DEVICE); 370 CHECK(mType == SchemaType::DEVICE);
369 return device.mSepolicyVersion; 371 return device.mSepolicyVersion;
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 d441245..698bf30 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -28,20 +28,20 @@ namespace android {
28namespace vintf { 28namespace vintf {
29 29
30template <typename T> 30template <typename T>
31struct LockedUniquePtr { 31struct LockedSharedPtr {
32 std::unique_ptr<T> object; 32 std::shared_ptr<T> object;
33 std::mutex mutex; 33 std::mutex mutex;
34}; 34};
35 35
36static LockedUniquePtr<HalManifest> gDeviceManifest; 36struct LockedRuntimeInfoCache {
37static LockedUniquePtr<HalManifest> gFrameworkManifest; 37 std::shared_ptr<RuntimeInfo> object;
38static LockedUniquePtr<CompatibilityMatrix> gDeviceMatrix; 38 std::mutex mutex;
39static LockedUniquePtr<CompatibilityMatrix> gFrameworkMatrix; 39 RuntimeInfo::FetchFlags fetchedFlags = RuntimeInfo::FetchFlag::NONE;
40static LockedUniquePtr<RuntimeInfo> gDeviceRuntimeInfo; 40};
41 41
42template <typename T, typename F> 42template <typename T, typename F>
43static const T *Get( 43static std::shared_ptr<const T> Get(
44 LockedUniquePtr<T> *ptr, 44 LockedSharedPtr<T> *ptr,
45 bool skipCache, 45 bool skipCache,
46 const F &fetchAllInformation) { 46 const F &fetchAllInformation) {
47 std::unique_lock<std::mutex> _lock(ptr->mutex); 47 std::unique_lock<std::mutex> _lock(ptr->mutex);
@@ -51,18 +51,20 @@ static const T *Get(
51 ptr->object = nullptr; // frees the old object 51 ptr->object = nullptr; // frees the old object
52 } 52 }
53 } 53 }
54 return ptr->object.get(); 54 return ptr->object;
55} 55}
56 56
57// static 57// static
58const HalManifest *VintfObject::GetDeviceHalManifest(bool skipCache) { 58std::shared_ptr<const HalManifest> VintfObject::GetDeviceHalManifest(bool skipCache) {
59 static LockedSharedPtr<HalManifest> gDeviceManifest;
59 return Get(&gDeviceManifest, skipCache, 60 return Get(&gDeviceManifest, skipCache,
60 std::bind(&HalManifest::fetchAllInformation, std::placeholders::_1, 61 std::bind(&HalManifest::fetchAllInformation, std::placeholders::_1,
61 "/vendor/manifest.xml")); 62 "/vendor/manifest.xml"));
62} 63}
63 64
64// static 65// static
65const HalManifest *VintfObject::GetFrameworkHalManifest(bool skipCache) { 66std::shared_ptr<const HalManifest> VintfObject::GetFrameworkHalManifest(bool skipCache) {
67 static LockedSharedPtr<HalManifest> gFrameworkManifest;
66 return Get(&gFrameworkManifest, skipCache, 68 return Get(&gFrameworkManifest, skipCache,
67 std::bind(&HalManifest::fetchAllInformation, std::placeholders::_1, 69 std::bind(&HalManifest::fetchAllInformation, std::placeholders::_1,
68 "/system/manifest.xml")); 70 "/system/manifest.xml"));
@@ -70,23 +72,43 @@ const HalManifest *VintfObject::GetFrameworkHalManifest(bool skipCache) {
70 72
71 73
72// static 74// static
73const CompatibilityMatrix *VintfObject::GetDeviceCompatibilityMatrix(bool skipCache) { 75std::shared_ptr<const CompatibilityMatrix> VintfObject::GetDeviceCompatibilityMatrix(bool skipCache) {
76 static LockedSharedPtr<CompatibilityMatrix> gDeviceMatrix;
74 return Get(&gDeviceMatrix, skipCache, 77 return Get(&gDeviceMatrix, skipCache,
75 std::bind(&CompatibilityMatrix::fetchAllInformation, std::placeholders::_1, 78 std::bind(&CompatibilityMatrix::fetchAllInformation, std::placeholders::_1,
76 "/vendor/compatibility_matrix.xml")); 79 "/vendor/compatibility_matrix.xml"));
77} 80}
78 81
79// static 82// static
80const CompatibilityMatrix *VintfObject::GetFrameworkCompatibilityMatrix(bool skipCache) { 83std::shared_ptr<const CompatibilityMatrix> VintfObject::GetFrameworkCompatibilityMatrix(bool skipCache) {
84 static LockedSharedPtr<CompatibilityMatrix> gFrameworkMatrix;
81 return Get(&gFrameworkMatrix, skipCache, 85 return Get(&gFrameworkMatrix, skipCache,
82 std::bind(&CompatibilityMatrix::fetchAllInformation, std::placeholders::_1, 86 std::bind(&CompatibilityMatrix::fetchAllInformation, std::placeholders::_1,
83 "/system/compatibility_matrix.xml")); 87 "/system/compatibility_matrix.xml"));
84} 88}
85 89
86// static 90// static
87const RuntimeInfo *VintfObject::GetRuntimeInfo(bool skipCache) { 91std::shared_ptr<const RuntimeInfo> VintfObject::GetRuntimeInfo(bool skipCache,
88 return Get(&gDeviceRuntimeInfo, skipCache, 92 RuntimeInfo::FetchFlags flags) {
89 std::bind(&RuntimeInfo::fetchAllInformation, std::placeholders::_1)); 93 static LockedRuntimeInfoCache gDeviceRuntimeInfo;
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;
90} 112}
91 113
92namespace details { 114namespace details {
@@ -110,8 +132,8 @@ static std::string toString(ParseStatus status) {
110 132
111template<typename T> 133template<typename T>
112static ParseStatus tryParse(const std::string &xml, const XmlConverter<T> &parse, 134static ParseStatus tryParse(const std::string &xml, const XmlConverter<T> &parse,
113 std::unique_ptr<T> *fwk, std::unique_ptr<T> *dev) { 135 std::shared_ptr<T> *fwk, std::shared_ptr<T> *dev) {
114 std::unique_ptr<T> ret = std::make_unique<T>(); 136 std::shared_ptr<T> ret = std::make_shared<T>();
115 if (!parse(ret.get(), xml)) { 137 if (!parse(ret.get(), xml)) {
116 return ParseStatus::PARSE_ERROR; 138 return ParseStatus::PARSE_ERROR;
117 } 139 }
@@ -130,9 +152,9 @@ static ParseStatus tryParse(const std::string &xml, const XmlConverter<T> &parse
130} 152}
131 153
132template<typename T, typename GetFunction> 154template<typename T, typename GetFunction>
133static status_t getMissing(const T *pkg, bool mount, 155static status_t getMissing(const std::shared_ptr<T>& pkg, bool mount,
134 std::function<status_t(void)> mountFunction, 156 std::function<status_t(void)> mountFunction,
135 const T **updated, 157 std::shared_ptr<const T>* updated,
136 GetFunction getFunction) { 158 GetFunction getFunction) {
137 if (pkg != nullptr) { 159 if (pkg != nullptr) {
138 *updated = pkg; 160 *updated = pkg;
@@ -152,8 +174,8 @@ static status_t getMissing(const T *pkg, bool mount,
152 174
153struct PackageInfo { 175struct PackageInfo {
154 struct Pair { 176 struct Pair {
155 std::unique_ptr<HalManifest> manifest; 177 std::shared_ptr<HalManifest> manifest;
156 std::unique_ptr<CompatibilityMatrix> matrix; 178 std::shared_ptr<CompatibilityMatrix> matrix;
157 }; 179 };
158 Pair dev; 180 Pair dev;
159 Pair fwk; 181 Pair fwk;
@@ -161,12 +183,12 @@ struct PackageInfo {
161 183
162struct UpdatedInfo { 184struct UpdatedInfo {
163 struct Pair { 185 struct Pair {
164 const HalManifest *manifest; 186 std::shared_ptr<const HalManifest> manifest;
165 const CompatibilityMatrix *matrix; 187 std::shared_ptr<const CompatibilityMatrix> matrix;
166 }; 188 };
167 Pair dev; 189 Pair dev;
168 Pair fwk; 190 Pair fwk;
169 const RuntimeInfo *runtimeInfo; 191 std::shared_ptr<const RuntimeInfo> runtimeInfo;
170}; 192};
171 193
172// Checks given compatibility info against info on the device. If no 194// Checks given compatibility info against info on the device. If no
@@ -207,23 +229,23 @@ int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount,
207 auto mountSystem = [&mounter] { return mounter.mountSystem(); }; 229 auto mountSystem = [&mounter] { return mounter.mountSystem(); };
208 auto mountVendor = [&mounter] { return mounter.mountVendor(); }; 230 auto mountVendor = [&mounter] { return mounter.mountVendor(); };
209 if ((status = getMissing( 231 if ((status = getMissing(
210 pkg.fwk.manifest.get(), mount, mountSystem, &updated.fwk.manifest, 232 pkg.fwk.manifest, mount, mountSystem, &updated.fwk.manifest,
211 std::bind(VintfObject::GetFrameworkHalManifest, true /* skipCache */))) != OK) { 233 std::bind(VintfObject::GetFrameworkHalManifest, true /* skipCache */))) != OK) {
212 return status; 234 return status;
213 } 235 }
214 if ((status = getMissing( 236 if ((status = getMissing(
215 pkg.dev.manifest.get(), mount, mountVendor, &updated.dev.manifest, 237 pkg.dev.manifest, mount, mountVendor, &updated.dev.manifest,
216 std::bind(VintfObject::GetDeviceHalManifest, true /* skipCache */))) != OK) { 238 std::bind(VintfObject::GetDeviceHalManifest, true /* skipCache */))) != OK) {
217 return status; 239 return status;
218 } 240 }
219 if ((status = getMissing( 241 if ((status = getMissing(
220 pkg.fwk.matrix.get(), mount, mountSystem, &updated.fwk.matrix, 242 pkg.fwk.matrix, mount, mountSystem, &updated.fwk.matrix,
221 std::bind(VintfObject::GetFrameworkCompatibilityMatrix, true /* skipCache */))) != 243 std::bind(VintfObject::GetFrameworkCompatibilityMatrix, true /* skipCache */))) !=
222 OK) { 244 OK) {
223 return status; 245 return status;
224 } 246 }
225 if ((status = getMissing( 247 if ((status = getMissing(
226 pkg.dev.matrix.get(), mount, mountVendor, &updated.dev.matrix, 248 pkg.dev.matrix, mount, mountVendor, &updated.dev.matrix,
227 std::bind(VintfObject::GetDeviceCompatibilityMatrix, true /* skipCache */))) != OK) { 249 std::bind(VintfObject::GetDeviceCompatibilityMatrix, true /* skipCache */))) != OK) {
228 return status; 250 return status;
229 } 251 }
diff --git a/check_vintf.cpp b/check_vintf.cpp
new file mode 100644
index 0000000..211702e
--- /dev/null
+++ b/check_vintf.cpp
@@ -0,0 +1,68 @@
1/*
2 * Copyright (C) 2017 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#include <iostream>
18
19#include <vintf/parse_xml.h>
20#include "utils.h"
21
22namespace android {
23namespace vintf {
24
25template <typename T>
26std::unique_ptr<T> readObject(const std::string& path, const XmlConverter<T>& converter) {
27 std::string xml;
28 status_t err = details::gFetcher->fetch(path, xml);
29 if (err != OK) {
30 std::cerr << "Error: Cannot read '" << path << "': " << strerror(-err) << std::endl;
31 return nullptr;
32 }
33 auto ret = std::make_unique<T>();
34 if (!converter(ret.get(), xml)) {
35 std::cerr << "Error: Cannot parse '" << path << "': " << converter.lastError() << std::endl;
36 return nullptr;
37 }
38 return ret;
39}
40
41} // namespace vintf
42} // namespace android
43
44int main(int argc, char** argv) {
45 using namespace android::vintf;
46 if (argc < 3) {
47 std::cerr << "usage: " << argv[0] << " <manifest.xml> <matrix.xml>" << std::endl
48 << " Checks compatibility between a manifest and a compatibility matrix."
49 << std::endl;
50 return -1;
51 }
52
53 auto manifest = readObject(argv[1], gHalManifestConverter);
54 auto matrix = readObject(argv[2], gCompatibilityMatrixConverter);
55 if (manifest == nullptr || matrix == nullptr) {
56 return -1;
57 }
58
59 std::string error;
60 if (!manifest->checkCompatibility(*matrix, &error)) {
61 std::cerr << "Error: Incompatible: " << error << std::endl;
62 std::cout << "false" << std::endl;
63 return 1;
64 }
65
66 std::cout << "true" << std::endl;
67 return 0;
68}
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 36aac51..bc3fbf4 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -40,8 +40,7 @@ struct CompatibilityMatrix : public HalGroup<MatrixHal>, public XmlFileGroup<Mat
40 CompatibilityMatrix() : mType(SchemaType::FRAMEWORK) {}; 40 CompatibilityMatrix() : mType(SchemaType::FRAMEWORK) {};
41 41
42 SchemaType type() const; 42 SchemaType type() const;
43 43 Version getMinimumMetaVersion() const;
44 constexpr static Version kVersion{1, 0};
45 44
46 // If the corresponding <xmlfile> with the given version exists, for the first match, 45 // If the corresponding <xmlfile> with the given version exists, for the first match,
47 // - Return the overridden <path> if it is present, 46 // - Return the overridden <path> if it is present,
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index 31c4801..bf224db 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -41,8 +41,6 @@ struct CompatibilityMatrix;
41// framework code. This is the API for the framework. 41// framework code. This is the API for the framework.
42struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> { 42struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> {
43 public: 43 public:
44 // manifest.version
45 constexpr static Version kVersion{1, 0};
46 44
47 // Construct a device HAL manifest. 45 // Construct a device HAL manifest.
48 HalManifest() : mType(SchemaType::DEVICE) {} 46 HalManifest() : mType(SchemaType::DEVICE) {}
@@ -127,6 +125,9 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
127 // Otherwise if the <xmlfile> entry does not exist, "" is returned. 125 // Otherwise if the <xmlfile> entry does not exist, "" is returned.
128 std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const; 126 std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const;
129 127
128 // Get metaversion of this manifest.
129 Version getMetaVersion() const;
130
130 protected: 131 protected:
131 // Check before add() 132 // Check before add()
132 bool shouldAdd(const ManifestHal& toAdd) const override; 133 bool shouldAdd(const ManifestHal& toAdd) const override;
@@ -153,6 +154,8 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
153 bool includeOptional = true) const; 154 bool includeOptional = true) const;
154 155
155 SchemaType mType; 156 SchemaType mType;
157 // version attribute. Default is 1.0 for manifests created programatically.
158 Version mMetaVersion{1, 0};
156 159
157 // entries for device hal manifest only 160 // entries for device hal manifest only
158 struct { 161 struct {
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 e4dbe7c..5593da5 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -17,6 +17,8 @@
17#ifndef ANDROID_VINTF_VINTF_OBJECT_H_ 17#ifndef ANDROID_VINTF_VINTF_OBJECT_H_
18#define ANDROID_VINTF_VINTF_OBJECT_H_ 18#define ANDROID_VINTF_VINTF_OBJECT_H_
19 19
20#include <memory>
21
20#include "CompatibilityMatrix.h" 22#include "CompatibilityMatrix.h"
21#include "DisabledChecks.h" 23#include "DisabledChecks.h"
22#include "HalManifest.h" 24#include "HalManifest.h"
@@ -54,30 +56,43 @@ public:
54 * Return the API that access the device-side HAL manifest stored 56 * Return the API that access the device-side HAL manifest stored
55 * in /vendor/manifest.xml. 57 * in /vendor/manifest.xml.
56 */ 58 */
57 static const HalManifest *GetDeviceHalManifest(bool skipCache = false); 59 static std::shared_ptr<const HalManifest> GetDeviceHalManifest(bool skipCache = false);
58 60
59 /* 61 /*
60 * Return the API that access the framework-side HAL manifest stored 62 * Return the API that access the framework-side HAL manifest stored
61 * in /system/manfiest.xml. 63 * in /system/manfiest.xml.
62 */ 64 */
63 static const HalManifest *GetFrameworkHalManifest(bool skipCache = false); 65 static std::shared_ptr<const HalManifest> GetFrameworkHalManifest(bool skipCache = false);
64 66
65 /* 67 /*
66 * Return the API that access the device-side compatibility matrix stored 68 * Return the API that access the device-side compatibility matrix stored
67 * in /vendor/compatibility_matrix.xml. 69 * in /vendor/compatibility_matrix.xml.
68 */ 70 */
69 static const CompatibilityMatrix *GetDeviceCompatibilityMatrix(bool skipCache = false); 71 static std::shared_ptr<const CompatibilityMatrix> GetDeviceCompatibilityMatrix(
72 bool skipCache = false);
70 73
71 /* 74 /*
72 * Return the API that access the device-side compatibility matrix stored 75 * Return the API that access the framework-side compatibility matrix stored
73 * in /system/compatibility_matrix.xml. 76 * in /system/compatibility_matrix.xml.
74 */ 77 */
75 static const CompatibilityMatrix *GetFrameworkCompatibilityMatrix(bool skipCache = false); 78 static std::shared_ptr<const CompatibilityMatrix> GetFrameworkCompatibilityMatrix(
79 bool skipCache = false);
76 80
77 /* 81 /*
78 * 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
79 */ 93 */
80 static const RuntimeInfo *GetRuntimeInfo(bool skipCache = false); 94 static std::shared_ptr<const RuntimeInfo> GetRuntimeInfo(
95 bool skipCache = false, RuntimeInfo::FetchFlags flags = RuntimeInfo::FetchFlag::ALL);
81 96
82 /** 97 /**
83 * Check compatibility, given a set of manifests / matrices in packageInfo. 98 * Check compatibility, given a set of manifests / matrices in packageInfo.
diff --git a/include/vintf/constants.h b/include/vintf/constants.h
new file mode 100644
index 0000000..efbb73c
--- /dev/null
+++ b/include/vintf/constants.h
@@ -0,0 +1,31 @@
1/*
2 * Copyright (C) 2017 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 ANDROID_VINTF_CONSTANTS_H
18#define ANDROID_VINTF_CONSTANTS_H
19
20#include "Version.h"
21
22namespace android {
23namespace vintf {
24
25/* libvintf meta-version */
26constexpr Version kMetaVersion{1, 0};
27
28} // namespace vintf
29} // namespace android
30
31#endif // ANDROID_VINTF_CONSTANTS_H
diff --git a/main.cpp b/main.cpp
index 01e3ea0..e4b8f6b 100644
--- a/main.cpp
+++ b/main.cpp
@@ -25,31 +25,31 @@ int main(int, char **) {
25 25
26 std::cout << "======== Device HAL Manifest =========" << std::endl; 26 std::cout << "======== Device HAL Manifest =========" << std::endl;
27 27
28 const HalManifest *vm = VintfObject::GetDeviceHalManifest(); 28 std::shared_ptr<const HalManifest> vm = VintfObject::GetDeviceHalManifest();
29 if (vm != nullptr) 29 if (vm != nullptr)
30 std::cout << gHalManifestConverter(*vm); 30 std::cout << gHalManifestConverter(*vm);
31 31
32 std::cout << "======== Framework HAL Manifest =========" << std::endl; 32 std::cout << "======== Framework HAL Manifest =========" << std::endl;
33 33
34 const HalManifest *fm = VintfObject::GetFrameworkHalManifest(); 34 std::shared_ptr<const HalManifest> fm = VintfObject::GetFrameworkHalManifest();
35 if (fm != nullptr) 35 if (fm != nullptr)
36 std::cout << gHalManifestConverter(*fm); 36 std::cout << gHalManifestConverter(*fm);
37 37
38 std::cout << "======== Device Compatibility Matrix =========" << std::endl; 38 std::cout << "======== Device Compatibility Matrix =========" << std::endl;
39 39
40 const CompatibilityMatrix *vcm = VintfObject::GetDeviceCompatibilityMatrix(); 40 std::shared_ptr<const CompatibilityMatrix> vcm = VintfObject::GetDeviceCompatibilityMatrix();
41 if (vcm != nullptr) 41 if (vcm != nullptr)
42 std::cout << gCompatibilityMatrixConverter(*vcm); 42 std::cout << gCompatibilityMatrixConverter(*vcm);
43 43
44 std::cout << "======== Framework Compatibility Matrix =========" << std::endl; 44 std::cout << "======== Framework Compatibility Matrix =========" << std::endl;
45 45
46 const CompatibilityMatrix *fcm = VintfObject::GetFrameworkCompatibilityMatrix(); 46 std::shared_ptr<const CompatibilityMatrix> fcm = VintfObject::GetFrameworkCompatibilityMatrix();
47 if (fcm != nullptr) 47 if (fcm != nullptr)
48 std::cout << gCompatibilityMatrixConverter(*fcm); 48 std::cout << gCompatibilityMatrixConverter(*fcm);
49 49
50 std::cout << "======== Runtime Info =========" << std::endl; 50 std::cout << "======== Runtime Info =========" << std::endl;
51 51
52 const RuntimeInfo* ki = VintfObject::GetRuntimeInfo(); 52 std::shared_ptr<const RuntimeInfo> ki = VintfObject::GetRuntimeInfo();
53 if (ki != nullptr) std::cout << dump(*ki); 53 if (ki != nullptr) std::cout << dump(*ki);
54 std::cout << std::endl; 54 std::cout << std::endl;
55 55
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 0094f81..1a0626a 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -25,6 +25,7 @@
25 25
26#include <tinyxml2.h> 26#include <tinyxml2.h>
27 27
28#include "constants.h"
28#include "parse_string.h" 29#include "parse_string.h"
29 30
30namespace android { 31namespace android {
@@ -43,7 +44,7 @@ inline DocType *createDocument() {
43// caller is responsible for deleteDocument() call 44// caller is responsible for deleteDocument() call
44inline DocType *createDocument(const std::string &xml) { 45inline DocType *createDocument(const std::string &xml) {
45 DocType *doc = new tinyxml2::XMLDocument(); 46 DocType *doc = new tinyxml2::XMLDocument();
46 if (doc->Parse(xml.c_str()) == tinyxml2::XML_NO_ERROR) { 47 if (doc->Parse(xml.c_str()) == tinyxml2::XML_SUCCESS) {
47 return doc; 48 return doc;
48 } 49 }
49 delete doc; 50 delete doc;
@@ -745,7 +746,7 @@ const ManifestXmlFileConverter manifestXmlFileConverter{};
745struct HalManifestConverter : public XmlNodeConverter<HalManifest> { 746struct HalManifestConverter : public XmlNodeConverter<HalManifest> {
746 std::string elementName() const override { return "manifest"; } 747 std::string elementName() const override { return "manifest"; }
747 void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override { 748 void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override {
748 appendAttr(root, "version", HalManifest::kVersion); 749 appendAttr(root, "version", m.getMetaVersion());
749 appendAttr(root, "type", m.mType); 750 appendAttr(root, "type", m.mType);
750 751
751 appendChildren(root, manifestHalConverter, m.getHals(), d); 752 appendChildren(root, manifestHalConverter, m.getHals(), d);
@@ -758,15 +759,15 @@ struct HalManifestConverter : public XmlNodeConverter<HalManifest> {
758 appendChildren(root, manifestXmlFileConverter, m.getXmlFiles(), d); 759 appendChildren(root, manifestXmlFileConverter, m.getXmlFiles(), d);
759 } 760 }
760 bool buildObject(HalManifest *object, NodeType *root) const override { 761 bool buildObject(HalManifest *object, NodeType *root) const override {
761 Version version;
762 std::vector<ManifestHal> hals; 762 std::vector<ManifestHal> hals;
763 if (!parseAttr(root, "version", &version) || 763 if (!parseAttr(root, "version", &object->mMetaVersion) ||
764 !parseAttr(root, "type", &object->mType) || 764 !parseAttr(root, "type", &object->mType) ||
765 !parseChildren(root, manifestHalConverter, &hals)) { 765 !parseChildren(root, manifestHalConverter, &hals)) {
766 return false; 766 return false;
767 } 767 }
768 if (version != HalManifest::kVersion) { 768 if (!kMetaVersion.minorAtLeast(object->mMetaVersion)) {
769 this->mLastError = "Unrecognized manifest.version"; 769 this->mLastError = "Unrecognized manifest.version " + to_string(object->mMetaVersion) +
770 " (libvintf@" + to_string(kMetaVersion) + ")";
770 return false; 771 return false;
771 } 772 }
772 if (object->mType == SchemaType::DEVICE) { 773 if (object->mType == SchemaType::DEVICE) {
@@ -855,7 +856,7 @@ const MatrixXmlFileConverter matrixXmlFileConverter{};
855struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatrix> { 856struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatrix> {
856 std::string elementName() const override { return "compatibility-matrix"; } 857 std::string elementName() const override { return "compatibility-matrix"; }
857 void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override { 858 void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override {
858 appendAttr(root, "version", CompatibilityMatrix::kVersion); 859 appendAttr(root, "version", m.getMinimumMetaVersion());
859 appendAttr(root, "type", m.mType); 860 appendAttr(root, "type", m.mType);
860 appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d); 861 appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d);
861 if (m.mType == SchemaType::FRAMEWORK) { 862 if (m.mType == SchemaType::FRAMEWORK) {
@@ -908,8 +909,9 @@ struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatri
908 } 909 }
909 } 910 }
910 911
911 if (version != CompatibilityMatrix::kVersion) { 912 if (!kMetaVersion.minorAtLeast(version)) {
912 this->mLastError = "Unrecognized compatibility-matrix.version"; 913 this->mLastError = "Unrecognized compatibility-matrix.version " + to_string(version) +
914 " (libvintf@" + to_string(kMetaVersion) + ")";
913 return false; 915 return false;
914 } 916 }
915 for (auto &&hal : hals) { 917 for (auto &&hal : hals) {
diff --git a/test/Android.bp b/test/Android.bp
index c5aa618..4849a63 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -14,6 +14,7 @@
14 14
15cc_test { 15cc_test {
16 name: "libvintf_test", 16 name: "libvintf_test",
17 defaults: ["libvintf-defaults"],
17 host_supported: true, 18 host_supported: true,
18 gtest: false, 19 gtest: false,
19 srcs: ["main.cpp"], 20 srcs: ["main.cpp"],
@@ -39,6 +40,7 @@ cc_test {
39 40
40cc_test { 41cc_test {
41 name: "vintf_object_test", 42 name: "vintf_object_test",
43 defaults: ["libvintf-defaults"],
42 host_supported: true, 44 host_supported: true,
43 native_coverage: true, 45 native_coverage: true,
44 srcs: [ 46 srcs: [
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/main.cpp b/test/main.cpp
index 495b35c..507e0d1 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -39,11 +39,13 @@ extern const XmlConverter<KernelConfigTypedValue> &gKernelConfigTypedValueConver
39extern const XmlConverter<HalManifest> &gHalManifestConverter; 39extern const XmlConverter<HalManifest> &gHalManifestConverter;
40extern const XmlConverter<CompatibilityMatrix> &gCompatibilityMatrixConverter; 40extern const XmlConverter<CompatibilityMatrix> &gCompatibilityMatrixConverter;
41 41
42#ifdef LIBVINTF_HOST
42static bool Contains(const std::string& str, const std::string& sub) { 43static bool Contains(const std::string& str, const std::string& sub) {
43 return str.find(sub) != std::string::npos; 44 return str.find(sub) != std::string::npos;
44} 45}
45#define EXPECT_CONTAINS(str, sub) \ 46#define EXPECT_CONTAINS(str, sub) \
46 EXPECT_TRUE(Contains((str), (sub))) << "Cannot find \"" << (sub) << "\" in \"" << (str) << "\"" 47 EXPECT_TRUE(Contains((str), (sub))) << "Cannot find \"" << (sub) << "\" in \"" << (str) << "\""
48#endif
47 49
48struct LibVintfTest : public ::testing::Test { 50struct LibVintfTest : public ::testing::Test {
49public: 51public:
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..c08a22e 100644
--- a/utils.h
+++ b/utils.h
@@ -23,8 +23,8 @@
23 23
24#include <android-base/logging.h> 24#include <android-base/logging.h>
25#include <utils/Errors.h> 25#include <utils/Errors.h>
26 26#include <vintf/RuntimeInfo.h>
27#include "parse_xml.h" 27#include <vintf/parse_xml.h>
28 28
29namespace android { 29namespace android {
30namespace vintf { 30namespace vintf {
@@ -91,6 +91,14 @@ status_t fetchAllInformation(const std::string& path, const XmlConverter<T>& con
91 return OK; 91 return OK;
92} 92}
93 93
94template <typename T>
95class ObjectFactory {
96 public:
97 virtual ~ObjectFactory() = default;
98 virtual std::shared_ptr<T> make_shared() const { return std::make_shared<T>(); }
99};
100extern ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory;
101
94} // namespace details 102} // namespace details
95} // namespace vintf 103} // namespace vintf
96} // namespace android 104} // namespace android