diff options
-rw-r--r-- | Android.bp | 31 | ||||
-rw-r--r-- | CompatibilityMatrix.cpp | 7 | ||||
-rw-r--r-- | HalManifest.cpp | 6 | ||||
-rw-r--r-- | RuntimeInfo-host.cpp | 2 | ||||
-rw-r--r-- | RuntimeInfo-target.cpp | 44 | ||||
-rw-r--r-- | VintfObject.cpp | 82 | ||||
-rw-r--r-- | check_vintf.cpp | 68 | ||||
-rw-r--r-- | include/vintf/CompatibilityMatrix.h | 3 | ||||
-rw-r--r-- | include/vintf/HalManifest.h | 7 | ||||
-rw-r--r-- | include/vintf/RuntimeInfo.h | 19 | ||||
-rw-r--r-- | include/vintf/VintfObject.h | 27 | ||||
-rw-r--r-- | include/vintf/constants.h | 31 | ||||
-rw-r--r-- | main.cpp | 10 | ||||
-rw-r--r-- | parse_xml.cpp | 20 | ||||
-rw-r--r-- | test/Android.bp | 2 | ||||
-rw-r--r-- | test/RuntimeInfo-fake.cpp | 2 | ||||
-rw-r--r-- | test/main.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 | 12 |
22 files changed, 363 insertions, 92 deletions
@@ -16,15 +16,18 @@ subdirs = [ | |||
16 | "test" | 16 | "test" |
17 | ] | 17 | ] |
18 | 18 | ||
19 | libvintf_flags = [ | 19 | cc_defaults { |
20 | "-Wall", | 20 | name: "libvintf-defaults", |
21 | "-Werror", | 21 | cflags: [ |
22 | ] | 22 | "-Wall", |
23 | "-Werror", | ||
24 | ], | ||
25 | } | ||
23 | 26 | ||
24 | cc_library { | 27 | cc_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 | ||
78 | cc_binary { | 81 | cc_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 | ||
89 | cc_binary_host { | 92 | cc_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 | |||
105 | cc_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 | ||
101 | cc_library { | 117 | cc_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 @@ | |||
22 | namespace android { | 22 | namespace android { |
23 | namespace vintf { | 23 | namespace vintf { |
24 | 24 | ||
25 | constexpr Version CompatibilityMatrix::kVersion; | ||
26 | |||
27 | bool CompatibilityMatrix::add(MatrixHal &&hal) { | 25 | bool 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 | ||
41 | Version 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 | ||
44 | status_t CompatibilityMatrix::fetchAllInformation(const std::string &path) { | 47 | status_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 @@ | |||
32 | namespace android { | 32 | namespace android { |
33 | namespace vintf { | 33 | namespace vintf { |
34 | 34 | ||
35 | constexpr 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. |
38 | bool HalManifest::shouldAdd(const ManifestHal& hal) const { | 36 | bool 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 | ||
365 | Version HalManifest::getMetaVersion() const { | ||
366 | return mMetaVersion; | ||
367 | } | ||
368 | |||
367 | const Version &HalManifest::sepolicyVersion() const { | 369 | const 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 @@ | |||
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 d441245..698bf30 100644 --- a/VintfObject.cpp +++ b/VintfObject.cpp | |||
@@ -28,20 +28,20 @@ namespace android { | |||
28 | namespace vintf { | 28 | namespace vintf { |
29 | 29 | ||
30 | template <typename T> | 30 | template <typename T> |
31 | struct LockedUniquePtr { | 31 | struct 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 | ||
36 | static LockedUniquePtr<HalManifest> gDeviceManifest; | 36 | struct LockedRuntimeInfoCache { |
37 | static LockedUniquePtr<HalManifest> gFrameworkManifest; | 37 | std::shared_ptr<RuntimeInfo> object; |
38 | static LockedUniquePtr<CompatibilityMatrix> gDeviceMatrix; | 38 | std::mutex mutex; |
39 | static LockedUniquePtr<CompatibilityMatrix> gFrameworkMatrix; | 39 | RuntimeInfo::FetchFlags fetchedFlags = RuntimeInfo::FetchFlag::NONE; |
40 | static LockedUniquePtr<RuntimeInfo> gDeviceRuntimeInfo; | 40 | }; |
41 | 41 | ||
42 | template <typename T, typename F> | 42 | template <typename T, typename F> |
43 | static const T *Get( | 43 | static 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 |
58 | const HalManifest *VintfObject::GetDeviceHalManifest(bool skipCache) { | 58 | std::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 |
65 | const HalManifest *VintfObject::GetFrameworkHalManifest(bool skipCache) { | 66 | std::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 |
73 | const CompatibilityMatrix *VintfObject::GetDeviceCompatibilityMatrix(bool skipCache) { | 75 | std::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 |
80 | const CompatibilityMatrix *VintfObject::GetFrameworkCompatibilityMatrix(bool skipCache) { | 83 | std::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 |
87 | const RuntimeInfo *VintfObject::GetRuntimeInfo(bool skipCache) { | 91 | std::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 | ||
92 | namespace details { | 114 | namespace details { |
@@ -110,8 +132,8 @@ static std::string toString(ParseStatus status) { | |||
110 | 132 | ||
111 | template<typename T> | 133 | template<typename T> |
112 | static ParseStatus tryParse(const std::string &xml, const XmlConverter<T> &parse, | 134 | static 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 | ||
132 | template<typename T, typename GetFunction> | 154 | template<typename T, typename GetFunction> |
133 | static status_t getMissing(const T *pkg, bool mount, | 155 | static 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 | ||
153 | struct PackageInfo { | 175 | struct 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 | ||
162 | struct UpdatedInfo { | 184 | struct 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 | |||
22 | namespace android { | ||
23 | namespace vintf { | ||
24 | |||
25 | template <typename T> | ||
26 | std::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 | |||
44 | int 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. |
42 | struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> { | 42 | struct 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; | |||
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 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 | |||
22 | namespace android { | ||
23 | namespace vintf { | ||
24 | |||
25 | /* libvintf meta-version */ | ||
26 | constexpr Version kMetaVersion{1, 0}; | ||
27 | |||
28 | } // namespace vintf | ||
29 | } // namespace android | ||
30 | |||
31 | #endif // ANDROID_VINTF_CONSTANTS_H | ||
@@ -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 | ||
30 | namespace android { | 31 | namespace android { |
@@ -43,7 +44,7 @@ inline DocType *createDocument() { | |||
43 | // caller is responsible for deleteDocument() call | 44 | // caller is responsible for deleteDocument() call |
44 | inline DocType *createDocument(const std::string &xml) { | 45 | inline 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{}; | |||
745 | struct HalManifestConverter : public XmlNodeConverter<HalManifest> { | 746 | struct 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{}; | |||
855 | struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatrix> { | 856 | struct 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 | ||
15 | cc_test { | 15 | cc_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 | ||
40 | cc_test { | 41 | cc_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 { | |||
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/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 | |||
39 | extern const XmlConverter<HalManifest> &gHalManifestConverter; | 39 | extern const XmlConverter<HalManifest> &gHalManifestConverter; |
40 | extern const XmlConverter<CompatibilityMatrix> &gCompatibilityMatrixConverter; | 40 | extern const XmlConverter<CompatibilityMatrix> &gCompatibilityMatrixConverter; |
41 | 41 | ||
42 | #ifdef LIBVINTF_HOST | ||
42 | static bool Contains(const std::string& str, const std::string& sub) { | 43 | static 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 | ||
48 | struct LibVintfTest : public ::testing::Test { | 50 | struct LibVintfTest : public ::testing::Test { |
49 | public: | 51 | public: |
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 |
@@ -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 | ||
29 | namespace android { | 29 | namespace android { |
30 | namespace vintf { | 30 | namespace 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 | ||
94 | template <typename T> | ||
95 | class ObjectFactory { | ||
96 | public: | ||
97 | virtual ~ObjectFactory() = default; | ||
98 | virtual std::shared_ptr<T> make_shared() const { return std::make_shared<T>(); } | ||
99 | }; | ||
100 | extern ObjectFactory<RuntimeInfo>* gRuntimeInfoFactory; | ||
101 | |||
94 | } // namespace details | 102 | } // namespace details |
95 | } // namespace vintf | 103 | } // namespace vintf |
96 | } // namespace android | 104 | } // namespace android |