summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.bp50
-rw-r--r--AssembleVintf.cpp27
-rw-r--r--CompatibilityMatrix.cpp3
-rw-r--r--HalManifest.cpp70
-rw-r--r--SystemSdk.cpp36
-rw-r--r--VintfObject.cpp172
-rw-r--r--include/vintf/CompatibilityMatrix.h2
-rw-r--r--include/vintf/HalGroup.h5
-rw-r--r--include/vintf/HalManifest.h6
-rw-r--r--include/vintf/ManifestHal.h1
-rw-r--r--include/vintf/SystemSdk.h50
-rw-r--r--include/vintf/VintfObject.h19
-rw-r--r--include/vintf/parse_string.h1
-rw-r--r--include/vintf/parse_xml.h1
-rw-r--r--parse_xml.cpp37
-rw-r--r--test/AssembleVintfTest.cpp31
-rw-r--r--test/LibVintfTest.cpp322
-rw-r--r--test/vintf_object_tests.cpp393
-rw-r--r--utils.h2
19 files changed, 1061 insertions, 167 deletions
diff --git a/Android.bp b/Android.bp
index fea4d38..a2f647e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -24,34 +24,41 @@ cc_defaults {
24 ], 24 ],
25} 25}
26 26
27cc_library { 27cc_defaults {
28 name: "libvintf", 28 name: "libvintf-common-srcs",
29 host_supported: true,
30 defaults: ["libvintf-defaults"],
31 shared_libs: [
32 "libbase",
33 "liblog",
34 "libselinux",
35 "libtinyxml2",
36 ],
37 export_include_dirs: ["include"],
38 local_include_dirs: ["include/vintf"],
39
40 srcs: [ 29 srcs: [
41 "parse_string.cpp", 30 "parse_string.cpp",
42 "parse_xml.cpp", 31 "parse_xml.cpp",
43 "CompatibilityMatrix.cpp", 32 "CompatibilityMatrix.cpp",
44 "HalManifest.cpp", 33 "HalManifest.cpp",
45 "HalInterface.cpp", 34 "HalInterface.cpp",
46 "KernelConfigParser.cpp",
47 "KernelConfigTypedValue.cpp", 35 "KernelConfigTypedValue.cpp",
48 "RuntimeInfo.cpp", 36 "RuntimeInfo.cpp",
49 "ManifestHal.cpp", 37 "ManifestHal.cpp",
50 "MatrixHal.cpp", 38 "MatrixHal.cpp",
51 "MatrixKernel.cpp", 39 "MatrixKernel.cpp",
40 "SystemSdk.cpp",
52 "TransportArch.cpp", 41 "TransportArch.cpp",
53 "VintfObject.cpp", 42 "VintfObject.cpp",
54 "XmlFile.cpp", 43 "XmlFile.cpp",
44 ]
45}
46
47cc_library {
48 name: "libvintf",
49 host_supported: true,
50 defaults: ["libvintf-defaults", "libvintf-common-srcs"],
51 shared_libs: [
52 "libbase",
53 "liblog",
54 "libselinux",
55 "libtinyxml2",
56 ],
57 export_include_dirs: ["include"],
58 local_include_dirs: ["include/vintf"],
59
60 srcs: [
61 "KernelConfigParser.cpp",
55 "utils.cpp", 62 "utils.cpp",
56 ], 63 ],
57 64
@@ -136,7 +143,7 @@ cc_binary_host {
136 143
137cc_library_static { 144cc_library_static {
138 name: "libvintftest", 145 name: "libvintftest",
139 defaults: ["libvintf-defaults"], 146 defaults: ["libvintf-defaults", "libvintf-common-srcs"],
140 host_supported: true, 147 host_supported: true,
141 shared_libs: [ 148 shared_libs: [
142 "libbase", 149 "libbase",
@@ -148,19 +155,6 @@ cc_library_static {
148 local_include_dirs: ["include/vintf", "test", "."], 155 local_include_dirs: ["include/vintf", "test", "."],
149 156
150 srcs: [ 157 srcs: [
151 "parse_string.cpp",
152 "parse_xml.cpp",
153 "CompatibilityMatrix.cpp",
154 "HalManifest.cpp",
155 "HalInterface.cpp",
156 "KernelConfigTypedValue.cpp",
157 "RuntimeInfo.cpp",
158 "ManifestHal.cpp",
159 "MatrixHal.cpp",
160 "MatrixKernel.cpp",
161 "TransportArch.cpp",
162 "VintfObject.cpp",
163 "XmlFile.cpp",
164 "test/RuntimeInfo-fake.cpp", 158 "test/RuntimeInfo-fake.cpp",
165 "test/utils-fake.cpp", 159 "test/utils-fake.cpp",
166 ], 160 ],
diff --git a/AssembleVintf.cpp b/AssembleVintf.cpp
index e19096e..f7f1fb4 100644
--- a/AssembleVintf.cpp
+++ b/AssembleVintf.cpp
@@ -76,6 +76,18 @@ class AssembleVintfImpl : public AssembleVintf {
76 return envValue != nullptr ? std::string(envValue) : std::string(); 76 return envValue != nullptr ? std::string(envValue) : std::string();
77 } 77 }
78 78
79 // Get environment variable and split with space.
80 std::vector<std::string> getEnvList(const std::string& key) const {
81 std::vector<std::string> ret;
82 for (auto&& v : base::Split(getEnv(key), " ")) {
83 v = base::Trim(v);
84 if (!v.empty()) {
85 ret.push_back(v);
86 }
87 }
88 return ret;
89 }
90
79 template <typename T> 91 template <typename T>
80 bool getFlag(const std::string& key, T* value) const { 92 bool getFlag(const std::string& key, T* value) const {
81 std::string envValue = getEnv(key); 93 std::string envValue = getEnv(key);
@@ -290,11 +302,12 @@ class AssembleVintfImpl : public AssembleVintf {
290 } 302 }
291 303
292 if (halManifest->mType == SchemaType::FRAMEWORK) { 304 if (halManifest->mType == SchemaType::FRAMEWORK) {
293 for (auto&& v : base::Split(getEnv("PROVIDED_VNDK_VERSIONS"), " ")) { 305 for (auto&& v : getEnvList("PROVIDED_VNDK_VERSIONS")) {
294 v = base::Trim(v); 306 halManifest->framework.mVendorNdks.emplace_back(std::move(v));
295 if (!v.empty()) { 307 }
296 halManifest->framework.mVendorNdks.emplace_back(std::move(v)); 308
297 } 309 for (auto&& v : getEnvList("PRODUCT_SYSTEMSDK_VERSIONS")) {
310 halManifest->framework.mSystemSdk.mVersions.emplace(std::move(v));
298 } 311 }
299 } 312 }
300 313
@@ -416,6 +429,10 @@ class AssembleVintfImpl : public AssembleVintf {
416 } 429 }
417 valueInMatrix = VendorNdk{std::move(vndkVersion)}; 430 valueInMatrix = VendorNdk{std::move(vndkVersion)};
418 } 431 }
432
433 for (auto&& v : getEnvList("BOARD_SYSTEMSDK_VERSIONS")) {
434 matrix->device.mSystemSdk.mVersions.emplace(std::move(v));
435 }
419 } 436 }
420 437
421 if (matrices->front().object.mType == SchemaType::FRAMEWORK) { 438 if (matrices->front().object.mType == SchemaType::FRAMEWORK) {
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index 8331f78..d3c4ebf 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -168,7 +168,8 @@ bool operator==(const CompatibilityMatrix &lft, const CompatibilityMatrix &rgt)
168#pragma clang diagnostic ignored "-Wdeprecated-declarations" 168#pragma clang diagnostic ignored "-Wdeprecated-declarations"
169 lft.device.mVndk == rgt.device.mVndk && 169 lft.device.mVndk == rgt.device.mVndk &&
170#pragma clang diagnostic pop 170#pragma clang diagnostic pop
171 lft.device.mVendorNdk == rgt.device.mVendorNdk)) && 171 lft.device.mVendorNdk == rgt.device.mVendorNdk &&
172 lft.device.mSystemSdk == rgt.device.mSystemSdk)) &&
172 (lft.mType != SchemaType::FRAMEWORK || 173 (lft.mType != SchemaType::FRAMEWORK ||
173 (lft.framework.mKernels == rgt.framework.mKernels && 174 (lft.framework.mKernels == rgt.framework.mKernels &&
174 lft.framework.mSepolicy == rgt.framework.mSepolicy && 175 lft.framework.mSepolicy == rgt.framework.mSepolicy &&
diff --git a/HalManifest.cpp b/HalManifest.cpp
index 45816f6..20ed7eb 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -24,6 +24,8 @@
24#include <mutex> 24#include <mutex>
25#include <set> 25#include <set>
26 26
27#include <android-base/strings.h>
28
27#include "parse_string.h" 29#include "parse_string.h"
28#include "parse_xml.h" 30#include "parse_xml.h"
29#include "utils.h" 31#include "utils.h"
@@ -37,6 +39,9 @@ bool HalManifest::shouldAdd(const ManifestHal& hal) const {
37 if (!hal.isValid()) { 39 if (!hal.isValid()) {
38 return false; 40 return false;
39 } 41 }
42 if (hal.isOverride) {
43 return true;
44 }
40 auto existingHals = mHals.equal_range(hal.name); 45 auto existingHals = mHals.equal_range(hal.name);
41 std::set<size_t> existingMajorVersions; 46 std::set<size_t> existingMajorVersions;
42 for (auto it = existingHals.first; it != existingHals.second; ++it) { 47 for (auto it = existingHals.first; it != existingHals.second; ++it) {
@@ -53,6 +58,48 @@ bool HalManifest::shouldAdd(const ManifestHal& hal) const {
53 return true; 58 return true;
54} 59}
55 60
61// Remove elements from "list" if p(element) returns true.
62template <typename List, typename Predicate>
63static void removeIf(List& list, Predicate predicate) {
64 for (auto it = list.begin(); it != list.end();) {
65 if (predicate(*it)) {
66 it = list.erase(it);
67 } else {
68 ++it;
69 }
70 }
71}
72
73void HalManifest::removeHals(const std::string& name, size_t majorVer) {
74 removeIf(mHals, [&name, majorVer](auto& existingHalPair) {
75 auto& existingHal = existingHalPair.second;
76 if (existingHal.name != name) {
77 return false;
78 }
79 auto& existingVersions = existingHal.versions;
80 removeIf(existingVersions, [majorVer](const auto& existingVersion) {
81 return existingVersion.majorVer == majorVer;
82 });
83 return existingVersions.empty();
84 });
85}
86
87bool HalManifest::add(ManifestHal&& halToAdd) {
88 if (halToAdd.isOverride) {
89 if (halToAdd.versions.empty()) {
90 // Special syntax when there are no <version> tags at all. Remove all existing HALs
91 // with the given name.
92 mHals.erase(halToAdd.name);
93 }
94 // If there are <version> tags, remove all existing major versions that causes a conflict.
95 for (const Version& versionToAdd : halToAdd.versions) {
96 removeHals(halToAdd.name, versionToAdd.majorVer);
97 }
98 }
99
100 return HalGroup::add(std::move(halToAdd));
101}
102
56bool HalManifest::shouldAddXmlFile(const ManifestXmlFile& xmlFile) const { 103bool HalManifest::shouldAddXmlFile(const ManifestXmlFile& xmlFile) const {
57 auto existingXmlFiles = getXmlFiles(xmlFile.name()); 104 auto existingXmlFiles = getXmlFiles(xmlFile.name());
58 for (auto it = existingXmlFiles.first; it != existingXmlFiles.second; ++it) { 105 for (auto it = existingXmlFiles.first; it != existingXmlFiles.second; ++it) {
@@ -254,6 +301,22 @@ static bool checkVendorNdkCompatibility(const VendorNdk& matVendorNdk,
254 return false; 301 return false;
255} 302}
256 303
304static bool checkSystemSdkCompatibility(const SystemSdk& matSystemSdk,
305 const SystemSdk& manifestSystemSdk, std::string* error) {
306 SystemSdk notSupported = matSystemSdk.removeVersions(manifestSystemSdk);
307 if (!notSupported.empty()) {
308 if (error) {
309 *error =
310 "The following System SDK versions are required by device "
311 "compatibility matrix but not supported by the framework manifest: [" +
312 base::Join(notSupported.versions(), ", ") + "]. Supported versions are: [" +
313 base::Join(manifestSystemSdk.versions(), ", ") + "].";
314 }
315 return false;
316 }
317 return true;
318}
319
257bool HalManifest::checkCompatibility(const CompatibilityMatrix &mat, std::string *error) const { 320bool HalManifest::checkCompatibility(const CompatibilityMatrix &mat, std::string *error) const {
258 if (mType == mat.mType) { 321 if (mType == mat.mType) {
259 if (error != nullptr) { 322 if (error != nullptr) {
@@ -277,6 +340,10 @@ bool HalManifest::checkCompatibility(const CompatibilityMatrix &mat, std::string
277 if (!checkVendorNdkCompatibility(mat.device.mVendorNdk, framework.mVendorNdks, error)) { 340 if (!checkVendorNdkCompatibility(mat.device.mVendorNdk, framework.mVendorNdks, error)) {
278 return false; 341 return false;
279 } 342 }
343
344 if (!checkSystemSdkCompatibility(mat.device.mSystemSdk, framework.mSystemSdk, error)) {
345 return false;
346 }
280 } else if (mType == SchemaType::DEVICE) { 347 } else if (mType == SchemaType::DEVICE) {
281 bool match = false; 348 bool match = false;
282 for (const auto &range : mat.framework.mSepolicy.sepolicyVersions()) { 349 for (const auto &range : mat.framework.mSepolicy.sepolicyVersions()) {
@@ -379,7 +446,8 @@ bool operator==(const HalManifest &lft, const HalManifest &rgt) {
379#pragma clang diagnostic ignored "-Wdeprecated-declarations" 446#pragma clang diagnostic ignored "-Wdeprecated-declarations"
380 lft.framework.mVndks == rgt.framework.mVndks && 447 lft.framework.mVndks == rgt.framework.mVndks &&
381#pragma clang diagnostic pop 448#pragma clang diagnostic pop
382 lft.framework.mVendorNdks == rgt.framework.mVendorNdks)); 449 lft.framework.mVendorNdks == rgt.framework.mVendorNdks &&
450 lft.framework.mSystemSdk == rgt.framework.mSystemSdk));
383} 451}
384 452
385} // namespace vintf 453} // namespace vintf
diff --git a/SystemSdk.cpp b/SystemSdk.cpp
new file mode 100644
index 0000000..d2ee123
--- /dev/null
+++ b/SystemSdk.cpp
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2018 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 "SystemSdk.h"
18
19#include <algorithm>
20
21namespace android {
22namespace vintf {
23
24SystemSdk SystemSdk::removeVersions(const SystemSdk& other) const {
25 SystemSdk ret;
26 std::set_difference(versions().begin(), versions().end(), other.versions().begin(),
27 other.versions().end(), std::inserter(ret.mVersions, ret.mVersions.end()));
28 return ret;
29}
30
31bool SystemSdk::operator==(const SystemSdk& other) const {
32 return versions() == other.versions();
33}
34
35} // namespace vintf
36} // namespace android
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 24694cd..90b446d 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -32,14 +32,14 @@
32 32
33#include <android-base/logging.h> 33#include <android-base/logging.h>
34 34
35#define FRAMEWORK_MATRIX_DIR "/system/etc/vintf/"
36
37using std::placeholders::_1; 35using std::placeholders::_1;
38using std::placeholders::_2; 36using std::placeholders::_2;
39 37
40namespace android { 38namespace android {
41namespace vintf { 39namespace vintf {
42 40
41using namespace details;
42
43template <typename T> 43template <typename T>
44struct LockedSharedPtr { 44struct LockedSharedPtr {
45 std::shared_ptr<T> object; 45 std::shared_ptr<T> object;
@@ -74,50 +74,21 @@ static std::shared_ptr<const T> Get(
74// static 74// static
75std::shared_ptr<const HalManifest> VintfObject::GetDeviceHalManifest(bool skipCache) { 75std::shared_ptr<const HalManifest> VintfObject::GetDeviceHalManifest(bool skipCache) {
76 static LockedSharedPtr<HalManifest> gVendorManifest; 76 static LockedSharedPtr<HalManifest> gVendorManifest;
77 static LockedSharedPtr<HalManifest> gOdmManifest; 77 return Get(&gVendorManifest, skipCache, &VintfObject::FetchDeviceHalManifest);
78#ifdef LIBVINTF_TARGET
79 static LockedSharedPtr<HalManifest> gProductManifest;
80#endif
81 static std::mutex gDeviceManifestMutex;
82
83 std::unique_lock<std::mutex> _lock(gDeviceManifestMutex);
84
85#ifdef LIBVINTF_TARGET
86 std::string productModel = android::base::GetProperty("ro.boot.product.hardware.sku", "");
87 if (!productModel.empty()) {
88 auto product = Get(&gProductManifest, skipCache,
89 std::bind(&HalManifest::fetchAllInformation, _1,
90 "/odm/etc/manifest_" + productModel + ".xml", _2));
91 if (product != nullptr) {
92 return product;
93 }
94 }
95#endif
96
97 auto odm = Get(&gOdmManifest, skipCache,
98 std::bind(&HalManifest::fetchAllInformation, _1, "/odm/etc/manifest.xml", _2));
99 if (odm != nullptr) {
100 return odm;
101 }
102
103 return Get(&gVendorManifest, skipCache,
104 std::bind(&HalManifest::fetchAllInformation, _1, "/vendor/manifest.xml", _2));
105} 78}
106 79
107// static 80// static
108std::shared_ptr<const HalManifest> VintfObject::GetFrameworkHalManifest(bool skipCache) { 81std::shared_ptr<const HalManifest> VintfObject::GetFrameworkHalManifest(bool skipCache) {
109 static LockedSharedPtr<HalManifest> gFrameworkManifest; 82 static LockedSharedPtr<HalManifest> gFrameworkManifest;
110 return Get(&gFrameworkManifest, skipCache, 83 return Get(&gFrameworkManifest, skipCache,
111 std::bind(&HalManifest::fetchAllInformation, _1, "/system/manifest.xml", _2)); 84 std::bind(&HalManifest::fetchAllInformation, _1, kSystemManifest, _2));
112} 85}
113 86
114 87
115// static 88// static
116std::shared_ptr<const CompatibilityMatrix> VintfObject::GetDeviceCompatibilityMatrix(bool skipCache) { 89std::shared_ptr<const CompatibilityMatrix> VintfObject::GetDeviceCompatibilityMatrix(bool skipCache) {
117 static LockedSharedPtr<CompatibilityMatrix> gDeviceMatrix; 90 static LockedSharedPtr<CompatibilityMatrix> gDeviceMatrix;
118 return Get(&gDeviceMatrix, skipCache, 91 return Get(&gDeviceMatrix, skipCache, &VintfObject::FetchDeviceMatrix);
119 std::bind(&CompatibilityMatrix::fetchAllInformation, _1,
120 "/vendor/compatibility_matrix.xml", _2));
121} 92}
122 93
123// static 94// static
@@ -139,8 +110,7 @@ std::shared_ptr<const CompatibilityMatrix> VintfObject::GetFrameworkCompatibilit
139 } 110 }
140 111
141 return Get(&gFrameworkMatrix, skipCache, 112 return Get(&gFrameworkMatrix, skipCache,
142 std::bind(&CompatibilityMatrix::fetchAllInformation, _1, 113 std::bind(&CompatibilityMatrix::fetchAllInformation, _1, kSystemLegacyMatrix, _2));
143 "/system/compatibility_matrix.xml", _2));
144} 114}
145 115
146status_t VintfObject::GetCombinedFrameworkMatrix( 116status_t VintfObject::GetCombinedFrameworkMatrix(
@@ -183,7 +153,7 @@ status_t VintfObject::GetCombinedFrameworkMatrix(
183 // None of the fragments specify any FCM version. Should never happen except 153 // None of the fragments specify any FCM version. Should never happen except
184 // for inconsistent builds. 154 // for inconsistent builds.
185 if (error) { 155 if (error) {
186 *error = "No framework compatibility matrix files under " FRAMEWORK_MATRIX_DIR 156 *error = "No framework compatibility matrix files under " + kSystemVintfDir +
187 " declare FCM version."; 157 " declare FCM version.";
188 } 158 }
189 return NAME_NOT_FOUND; 159 return NAME_NOT_FOUND;
@@ -198,16 +168,120 @@ status_t VintfObject::GetCombinedFrameworkMatrix(
198 return OK; 168 return OK;
199} 169}
200 170
171// Priority for loading vendor manifest:
172// 1. /vendor/etc/vintf/manifest.xml + ODM manifest
173// 2. /vendor/etc/vintf/manifest.xml
174// 3. ODM manifest
175// 4. /vendor/manifest.xml
176// where:
177// A + B means adding <hal> tags from B to A (so that <hal>s from B can override A)
178status_t VintfObject::FetchDeviceHalManifest(HalManifest* out, std::string* error) {
179 status_t vendorStatus = FetchOneHalManifest(kVendorManifest, out, error);
180 if (vendorStatus != OK && vendorStatus != NAME_NOT_FOUND) {
181 return vendorStatus;
182 }
183
184 HalManifest odmManifest;
185 status_t odmStatus = FetchOdmHalManifest(&odmManifest, error);
186 if (odmStatus != OK && odmStatus != NAME_NOT_FOUND) {
187 return odmStatus;
188 }
189
190 if (vendorStatus == OK) {
191 if (odmStatus == OK) {
192 out->addAllHals(&odmManifest);
193 }
194 return OK;
195 }
196
197 // vendorStatus != OK, "out" is not changed.
198 if (odmStatus == OK) {
199 *out = std::move(odmManifest);
200 return OK;
201 }
202
203 // Use legacy /vendor/manifest.xml
204 return out->fetchAllInformation(kVendorLegacyManifest, error);
205}
206
207// "out" is written to iff return status is OK.
208// Priority:
209// 1. if {sku} is defined, /odm/etc/vintf/manifest_{sku}.xml
210// 2. /odm/etc/vintf/manifest.xml
211// 3. if {sku} is defined, /odm/etc/manifest_{sku}.xml
212// 4. /odm/etc/manifest.xml
213// where:
214// {sku} is the value of ro.boot.product.hardware.sku
215status_t VintfObject::FetchOdmHalManifest(HalManifest* out, std::string* error) {
216 status_t status;
217
218#ifdef LIBVINTF_TARGET
219 std::string productModel;
220 productModel = android::base::GetProperty("ro.boot.product.hardware.sku", "");
221
222 if (!productModel.empty()) {
223 status =
224 FetchOneHalManifest(kOdmVintfDir + "manifest_" + productModel + ".xml", out, error);
225 if (status == OK || status != NAME_NOT_FOUND) {
226 return status;
227 }
228 }
229#endif
230
231 status = FetchOneHalManifest(kOdmManifest, out, error);
232 if (status == OK || status != NAME_NOT_FOUND) {
233 return status;
234 }
235
236#ifdef LIBVINTF_TARGET
237 if (!productModel.empty()) {
238 status = FetchOneHalManifest(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml", out,
239 error);
240 if (status == OK || status != NAME_NOT_FOUND) {
241 return status;
242 }
243 }
244#endif
245
246 status = FetchOneHalManifest(kOdmLegacyManifest, out, error);
247 if (status == OK || status != NAME_NOT_FOUND) {
248 return status;
249 }
250
251 return NAME_NOT_FOUND;
252}
253
254// Fetch one manifest.xml file. "out" is written to iff return status is OK.
255// Returns NAME_NOT_FOUND if file is missing.
256status_t VintfObject::FetchOneHalManifest(const std::string& path, HalManifest* out,
257 std::string* error) {
258 HalManifest ret;
259 status_t status = ret.fetchAllInformation(path, error);
260 if (status == OK) {
261 *out = std::move(ret);
262 }
263 return status;
264}
265
266status_t VintfObject::FetchDeviceMatrix(CompatibilityMatrix* out, std::string* error) {
267 CompatibilityMatrix etcMatrix;
268 if (etcMatrix.fetchAllInformation(kVendorMatrix, error) == OK) {
269 *out = std::move(etcMatrix);
270 return OK;
271 }
272 return out->fetchAllInformation(kVendorLegacyMatrix, error);
273}
274
201std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels( 275std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels(
202 std::string* error) { 276 std::string* error) {
203 std::vector<std::string> fileNames; 277 std::vector<std::string> fileNames;
204 std::vector<Named<CompatibilityMatrix>> results; 278 std::vector<Named<CompatibilityMatrix>> results;
205 279
206 if (details::gFetcher->listFiles(FRAMEWORK_MATRIX_DIR, &fileNames, error) != OK) { 280 if (details::gFetcher->listFiles(kSystemVintfDir, &fileNames, error) != OK) {
207 return {}; 281 return {};
208 } 282 }
209 for (const std::string& fileName : fileNames) { 283 for (const std::string& fileName : fileNames) {
210 std::string path = FRAMEWORK_MATRIX_DIR + fileName; 284 std::string path = kSystemVintfDir + fileName;
211 285
212 std::string content; 286 std::string content;
213 std::string fetchError; 287 std::string fetchError;
@@ -233,9 +307,8 @@ std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels
233 307
234 if (results.empty()) { 308 if (results.empty()) {
235 if (error) { 309 if (error) {
236 *error = "No framework matrices under " FRAMEWORK_MATRIX_DIR 310 *error = "No framework matrices under " + kSystemVintfDir +
237 " can be fetched or parsed.\n" + 311 " can be fetched or parsed.\n" + *error;
238 *error;
239 } 312 }
240 } else { 313 } else {
241 if (error && !error->empty()) { 314 if (error && !error->empty()) {
@@ -470,6 +543,21 @@ int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount,
470 return COMPATIBLE; 543 return COMPATIBLE;
471} 544}
472 545
546const std::string kSystemVintfDir = "/system/etc/vintf/";
547const std::string kVendorVintfDir = "/vendor/etc/vintf/";
548const std::string kOdmVintfDir = "/odm/etc/vintf/";
549
550const std::string kVendorManifest = kVendorVintfDir + "manifest.xml";
551const std::string kSystemManifest = kSystemVintfDir + "manifest.xml";
552const std::string kVendorMatrix = kVendorVintfDir + "compatibility_matrix.xml";
553const std::string kOdmManifest = kOdmVintfDir + "manifest.xml";
554
555const std::string kVendorLegacyManifest = "/vendor/manifest.xml";
556const std::string kVendorLegacyMatrix = "/vendor/compatibility_matrix.xml";
557const std::string kSystemLegacyMatrix = "/system/compatibility_matrix.xml";
558const std::string kOdmLegacyVintfDir = "/odm/etc/";
559const std::string kOdmLegacyManifest = kOdmLegacyVintfDir + "manifest.xml";
560
473} // namespace details 561} // namespace details
474 562
475// static 563// static
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index b7a5541..696a0bf 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -30,6 +30,7 @@
30#include "Named.h" 30#include "Named.h"
31#include "SchemaType.h" 31#include "SchemaType.h"
32#include "Sepolicy.h" 32#include "Sepolicy.h"
33#include "SystemSdk.h"
33#include "VendorNdk.h" 34#include "VendorNdk.h"
34#include "Vndk.h" 35#include "Vndk.h"
35#include "XmlFileGroup.h" 36#include "XmlFileGroup.h"
@@ -115,6 +116,7 @@ struct CompatibilityMatrix : public HalGroup<MatrixHal>, public XmlFileGroup<Mat
115#pragma clang diagnostic pop 116#pragma clang diagnostic pop
116 117
117 VendorNdk mVendorNdk; 118 VendorNdk mVendorNdk;
119 SystemSdk mSystemSdk;
118 } device; 120 } device;
119}; 121};
120 122
diff --git a/include/vintf/HalGroup.h b/include/vintf/HalGroup.h
index 0facab4..10c1eae 100644
--- a/include/vintf/HalGroup.h
+++ b/include/vintf/HalGroup.h
@@ -46,7 +46,7 @@ struct HalGroup {
46 } 46 }
47 47
48 // Add an hal to this HalGroup so that it can be constructed programatically. 48 // Add an hal to this HalGroup so that it can be constructed programatically.
49 bool add(Hal&& hal) { 49 virtual bool add(Hal&& hal) {
50 if (!shouldAdd(hal)) { 50 if (!shouldAdd(hal)) {
51 return false; 51 return false;
52 } 52 }
@@ -97,6 +97,9 @@ struct HalGroup {
97 std::set<std::string> getInstances(const std::string& halName, const Version& version, 97 std::set<std::string> getInstances(const std::string& halName, const Version& version,
98 const std::string& interfaceName) const { 98 const std::string& interfaceName) const {
99 const Hal* hal = getHal(halName, version); 99 const Hal* hal = getHal(halName, version);
100 if (hal == nullptr) {
101 return {};
102 }
100 return hal->getInstances(interfaceName); 103 return hal->getInstances(interfaceName);
101 } 104 }
102 105
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index f458753..84bd770 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -28,6 +28,7 @@
28#include "ManifestHal.h" 28#include "ManifestHal.h"
29#include "MapValueIterator.h" 29#include "MapValueIterator.h"
30#include "SchemaType.h" 30#include "SchemaType.h"
31#include "SystemSdk.h"
31#include "VendorNdk.h" 32#include "VendorNdk.h"
32#include "Version.h" 33#include "Version.h"
33#include "Vndk.h" 34#include "Vndk.h"
@@ -47,6 +48,8 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
47 // Construct a device HAL manifest. 48 // Construct a device HAL manifest.
48 HalManifest() : mType(SchemaType::DEVICE) {} 49 HalManifest() : mType(SchemaType::DEVICE) {}
49 50
51 bool add(ManifestHal&& hal) override;
52
50 // Given a component name (e.g. "android.hardware.camera"), 53 // Given a component name (e.g. "android.hardware.camera"),
51 // return getHal(name)->transport if the component exist and v exactly matches 54 // return getHal(name)->transport if the component exist and v exactly matches
52 // one of the versions in that component, else EMPTY 55 // one of the versions in that component, else EMPTY
@@ -136,6 +139,8 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
136 std::vector<std::string> checkIncompatibleXmlFiles(const CompatibilityMatrix& mat, 139 std::vector<std::string> checkIncompatibleXmlFiles(const CompatibilityMatrix& mat,
137 bool includeOptional = true) const; 140 bool includeOptional = true) const;
138 141
142 void removeHals(const std::string& name, size_t majorVer);
143
139 SchemaType mType; 144 SchemaType mType;
140 Level mLevel = Level::UNSPECIFIED; 145 Level mLevel = Level::UNSPECIFIED;
141 // version attribute. Default is 1.0 for manifests created programatically. 146 // version attribute. Default is 1.0 for manifests created programatically.
@@ -154,6 +159,7 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
154#pragma clang diagnostic pop 159#pragma clang diagnostic pop
155 160
156 std::vector<VendorNdk> mVendorNdks; 161 std::vector<VendorNdk> mVendorNdks;
162 SystemSdk mSystemSdk;
157 } framework; 163 } framework;
158}; 164};
159 165
diff --git a/include/vintf/ManifestHal.h b/include/vintf/ManifestHal.h
index c569570..09c6693 100644
--- a/include/vintf/ManifestHal.h
+++ b/include/vintf/ManifestHal.h
@@ -47,6 +47,7 @@ struct ManifestHal {
47 std::vector<Version> versions; 47 std::vector<Version> versions;
48 TransportArch transportArch; 48 TransportArch transportArch;
49 std::map<std::string, HalInterface> interfaces; 49 std::map<std::string, HalInterface> interfaces;
50 bool isOverride = false;
50 51
51 inline bool hasInterface(const std::string& interface_name) const { 52 inline bool hasInterface(const std::string& interface_name) const {
52 return interfaces.find(interface_name) != interfaces.end(); 53 return interfaces.find(interface_name) != interfaces.end();
diff --git a/include/vintf/SystemSdk.h b/include/vintf/SystemSdk.h
new file mode 100644
index 0000000..1828e4a
--- /dev/null
+++ b/include/vintf/SystemSdk.h
@@ -0,0 +1,50 @@
1/*
2 * Copyright (C) 2018 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_SYSTEM_SDK_H
18#define ANDROID_VINTF_SYSTEM_SDK_H
19
20#include <stdint.h>
21
22#include <set>
23#include <string>
24
25namespace android {
26namespace vintf {
27
28// System SDK versions provided for vendor apps.
29class SystemSdk {
30 public:
31 SystemSdk() = default;
32 SystemSdk(std::set<std::string>&& versions) : mVersions(std::move(versions)) {}
33 SystemSdk(const std::set<std::string>& versions) : mVersions(versions) {}
34 const std::set<std::string>& versions() const { return mVersions; }
35 bool empty() const { return versions().empty(); }
36
37 bool operator==(const SystemSdk& other) const;
38 // return {v : v in this and not in other}
39 SystemSdk removeVersions(const SystemSdk& other) const;
40
41 private:
42 friend class AssembleVintfImpl;
43 friend struct SystemSdkConverter;
44 std::set<std::string> mVersions;
45};
46
47} // namespace vintf
48} // namespace android
49
50#endif // ANDROID_VINTF_SYSTEM_SDK_H
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index 80df9ea..06ccd00 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -118,6 +118,11 @@ public:
118 std::string* error = nullptr); 118 std::string* error = nullptr);
119 static std::vector<Named<CompatibilityMatrix>> GetAllFrameworkMatrixLevels( 119 static std::vector<Named<CompatibilityMatrix>> GetAllFrameworkMatrixLevels(
120 std::string* error = nullptr); 120 std::string* error = nullptr);
121 static status_t FetchDeviceHalManifest(HalManifest* out, std::string* error = nullptr);
122 static status_t FetchDeviceMatrix(CompatibilityMatrix* out, std::string* error = nullptr);
123 static status_t FetchOdmHalManifest(HalManifest* out, std::string* error = nullptr);
124 static status_t FetchOneHalManifest(const std::string& path, HalManifest* out,
125 std::string* error = nullptr);
121}; 126};
122 127
123enum : int32_t { 128enum : int32_t {
@@ -131,6 +136,20 @@ class PartitionMounter;
131int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount, 136int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount,
132 const PartitionMounter& partitionMounter, std::string* error, 137 const PartitionMounter& partitionMounter, std::string* error,
133 DisabledChecks disabledChecks = ENABLE_ALL_CHECKS); 138 DisabledChecks disabledChecks = ENABLE_ALL_CHECKS);
139
140extern const std::string kSystemVintfDir;
141extern const std::string kVendorVintfDir;
142extern const std::string kOdmVintfDir;
143extern const std::string kOdmLegacyVintfDir;
144extern const std::string kOdmLegacyManifest;
145extern const std::string kVendorManifest;
146extern const std::string kSystemManifest;
147extern const std::string kVendorMatrix;
148extern const std::string kOdmManifest;
149extern const std::string kVendorLegacyManifest;
150extern const std::string kVendorLegacyMatrix;
151extern const std::string kSystemLegacyMatrix;
152
134} // namespace details 153} // namespace details
135 154
136} // namespace vintf 155} // namespace vintf
diff --git a/include/vintf/parse_string.h b/include/vintf/parse_string.h
index 0bb554a..be0c070 100644
--- a/include/vintf/parse_string.h
+++ b/include/vintf/parse_string.h
@@ -36,6 +36,7 @@ std::ostream &operator<<(std::ostream &os, Tristate tr);
36std::ostream &operator<<(std::ostream &os, SchemaType ksv); 36std::ostream &operator<<(std::ostream &os, SchemaType ksv);
37std::ostream& operator<<(std::ostream& os, XmlSchemaFormat f); 37std::ostream& operator<<(std::ostream& os, XmlSchemaFormat f);
38std::ostream& operator<<(std::ostream& os, Level l); 38std::ostream& operator<<(std::ostream& os, Level l);
39std::ostream& operator<<(std::ostream& os, KernelSepolicyVersion v);
39std::ostream &operator<<(std::ostream &os, const ManifestHal &hal); 40std::ostream &operator<<(std::ostream &os, const ManifestHal &hal);
40std::ostream &operator<<(std::ostream &os, const Version &ver); 41std::ostream &operator<<(std::ostream &os, const Version &ver);
41std::ostream &operator<<(std::ostream &os, const VersionRange &vr); 42std::ostream &operator<<(std::ostream &os, const VersionRange &vr);
diff --git a/include/vintf/parse_xml.h b/include/vintf/parse_xml.h
index a92facf..314fb72 100644
--- a/include/vintf/parse_xml.h
+++ b/include/vintf/parse_xml.h
@@ -30,6 +30,7 @@ enum SerializeFlag : uint32_t {
30 NO_VNDK = 1 << 3, 30 NO_VNDK = 1 << 3,
31 NO_KERNEL = 1 << 4, 31 NO_KERNEL = 1 << 4,
32 NO_XMLFILES = 1 << 5, 32 NO_XMLFILES = 1 << 5,
33 NO_SSDK = 1 << 6,
33 34
34 EVERYTHING = 0, 35 EVERYTHING = 0,
35 HALS_ONLY = ~NO_HALS, 36 HALS_ONLY = ~NO_HALS,
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 9a09eae..74ba880 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -596,10 +596,14 @@ struct ManifestHalConverter : public XmlNodeConverter<ManifestHal> {
596 appendChild(root, transportArchConverter(hal.transportArch, d)); 596 appendChild(root, transportArchConverter(hal.transportArch, d));
597 appendChildren(root, versionConverter, hal.versions, d); 597 appendChildren(root, versionConverter, hal.versions, d);
598 appendChildren(root, halInterfaceConverter, iterateValues(hal.interfaces), d); 598 appendChildren(root, halInterfaceConverter, iterateValues(hal.interfaces), d);
599 if (hal.isOverride) {
600 appendAttr(root, "override", hal.isOverride);
601 }
599 } 602 }
600 bool buildObject(ManifestHal *object, NodeType *root) const override { 603 bool buildObject(ManifestHal *object, NodeType *root) const override {
601 std::vector<HalInterface> interfaces; 604 std::vector<HalInterface> interfaces;
602 if (!parseOptionalAttr(root, "format", HalFormat::HIDL, &object->format) || 605 if (!parseOptionalAttr(root, "format", HalFormat::HIDL, &object->format) ||
606 !parseOptionalAttr(root, "override", false, &object->isOverride) ||
603 !parseTextElement(root, "name", &object->name) || 607 !parseTextElement(root, "name", &object->name) ||
604 !parseOptionalChild(root, transportArchConverter, {}, &object->transportArch) || 608 !parseOptionalChild(root, transportArchConverter, {}, &object->transportArch) ||
605 !parseChildren(root, versionConverter, &object->versions) || 609 !parseChildren(root, versionConverter, &object->versions) ||
@@ -737,6 +741,20 @@ struct VendorNdkConverter : public XmlNodeConverter<VendorNdk> {
737 741
738const VendorNdkConverter vendorNdkConverter{}; 742const VendorNdkConverter vendorNdkConverter{};
739 743
744const XmlTextConverter<std::string> systemSdkVersionConverter{"version"};
745
746struct SystemSdkConverter : public XmlNodeConverter<SystemSdk> {
747 std::string elementName() const override { return "system-sdk"; }
748 void mutateNode(const SystemSdk& object, NodeType* root, DocType* d) const override {
749 appendChildren(root, systemSdkVersionConverter, object.versions(), d);
750 }
751 bool buildObject(SystemSdk* object, NodeType* root) const override {
752 return parseChildren(root, systemSdkVersionConverter, &object->mVersions);
753 }
754};
755
756const SystemSdkConverter systemSdkConverter{};
757
740struct HalManifestSepolicyConverter : public XmlNodeConverter<Version> { 758struct HalManifestSepolicyConverter : public XmlNodeConverter<Version> {
741 std::string elementName() const override { return "sepolicy"; } 759 std::string elementName() const override { return "sepolicy"; }
742 void mutateNode(const Version &m, NodeType *root, DocType *d) const override { 760 void mutateNode(const Version &m, NodeType *root, DocType *d) const override {
@@ -797,6 +815,11 @@ struct HalManifestConverter : public XmlNodeConverter<HalManifest> {
797 815
798 appendChildren(root, vendorNdkConverter, m.framework.mVendorNdks, d); 816 appendChildren(root, vendorNdkConverter, m.framework.mVendorNdks, d);
799 } 817 }
818 if (!(flags & SerializeFlag::NO_SSDK)) {
819 if (!m.framework.mSystemSdk.empty()) {
820 appendChild(root, systemSdkConverter(m.framework.mSystemSdk, d));
821 }
822 }
800 } 823 }
801 824
802 if (!(flags & SerializeFlag::NO_XMLFILES)) { 825 if (!(flags & SerializeFlag::NO_XMLFILES)) {
@@ -842,6 +865,10 @@ struct HalManifestConverter : public XmlNodeConverter<HalManifest> {
842 if (!parseChildren(root, vendorNdkConverter, &object->framework.mVendorNdks)) { 865 if (!parseChildren(root, vendorNdkConverter, &object->framework.mVendorNdks)) {
843 return false; 866 return false;
844 } 867 }
868
869 if (!parseOptionalChild(root, systemSdkConverter, {}, &object->framework.mSystemSdk)) {
870 return false;
871 }
845 } 872 }
846 for (auto &&hal : hals) { 873 for (auto &&hal : hals) {
847 std::string description{hal.name}; 874 std::string description{hal.name};
@@ -945,6 +972,12 @@ struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatri
945 appendChild(root, vendorNdkConverter(m.device.mVendorNdk, d)); 972 appendChild(root, vendorNdkConverter(m.device.mVendorNdk, d));
946 } 973 }
947 } 974 }
975
976 if (!(flags & SerializeFlag::NO_SSDK)) {
977 if (!m.device.mSystemSdk.empty()) {
978 appendChild(root, systemSdkConverter(m.device.mSystemSdk, d));
979 }
980 }
948 } 981 }
949 982
950 if (!(flags & SerializeFlag::NO_XMLFILES)) { 983 if (!(flags & SerializeFlag::NO_XMLFILES)) {
@@ -996,6 +1029,10 @@ struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatri
996 if (!parseOptionalChild(root, vendorNdkConverter, {}, &object->device.mVendorNdk)) { 1029 if (!parseOptionalChild(root, vendorNdkConverter, {}, &object->device.mVendorNdk)) {
997 return false; 1030 return false;
998 } 1031 }
1032
1033 if (!parseOptionalChild(root, systemSdkConverter, {}, &object->device.mSystemSdk)) {
1034 return false;
1035 }
999 } 1036 }
1000 1037
1001 if (!kMetaVersion.minorAtLeast(version)) { 1038 if (!kMetaVersion.minorAtLeast(version)) {
diff --git a/test/AssembleVintfTest.cpp b/test/AssembleVintfTest.cpp
index 53a1d0d..4e481ad 100644
--- a/test/AssembleVintfTest.cpp
+++ b/test/AssembleVintfTest.cpp
@@ -356,5 +356,36 @@ TEST_F(AssembleVintfTest, VendorNdkCheckCompat) {
356 EXPECT_TRUE(getInstance()->assemble()); 356 EXPECT_TRUE(getInstance()->assemble());
357} 357}
358 358
359TEST_F(AssembleVintfTest, MatrixSystemSdk) {
360 addInput("compatibility_matrix.xml",
361 "<compatibility-matrix version=\"1.0\" type=\"device\"/>\n");
362 getInstance()->setFakeEnv("BOARD_SYSTEMSDK_VERSIONS", "P 1 2 ");
363 EXPECT_TRUE(getInstance()->assemble());
364 EXPECT_IN(
365 "<compatibility-matrix version=\"1.0\" type=\"device\">\n"
366 " <system-sdk>\n"
367 " <version>1</version>\n"
368 " <version>2</version>\n"
369 " <version>P</version>\n"
370 " </system-sdk>\n"
371 "</compatibility-matrix>\n",
372 getOutput());
373}
374
375TEST_F(AssembleVintfTest, ManifestSystemSdk) {
376 addInput("manifest.xml", "<manifest version=\"1.0\" type=\"framework\"/>\n");
377 getInstance()->setFakeEnv("PRODUCT_SYSTEMSDK_VERSIONS", "P 1 2 ");
378 EXPECT_TRUE(getInstance()->assemble());
379 EXPECT_IN(
380 "<manifest version=\"1.0\" type=\"framework\">\n"
381 " <system-sdk>\n"
382 " <version>1</version>\n"
383 " <version>2</version>\n"
384 " <version>P</version>\n"
385 " </system-sdk>\n"
386 "</manifest>\n",
387 getOutput());
388}
389
359} // namespace vintf 390} // namespace vintf
360} // namespace android 391} // namespace android
diff --git a/test/LibVintfTest.cpp b/test/LibVintfTest.cpp
index 1c2536d..e934360 100644
--- a/test/LibVintfTest.cpp
+++ b/test/LibVintfTest.cpp
@@ -2389,6 +2389,328 @@ TEST_F(LibVintfTest, MissingVendorNdkInMatrix) {
2389 } 2389 }
2390} 2390}
2391 2391
2392TEST_F(LibVintfTest, ManifestHalOverride) {
2393 HalManifest manifest;
2394 std::string xml =
2395 "<manifest version=\"1.0\" type=\"device\">\n"
2396 " <hal format=\"hidl\" override=\"true\">\n"
2397 " <name>android.hardware.foo</name>\n"
2398 " <transport>hwbinder</transport>\n"
2399 " <version>1.0</version>\n"
2400 " </hal>\n"
2401 " <hal format=\"hidl\">\n"
2402 " <name>android.hardware.bar</name>\n"
2403 " <transport>hwbinder</transport>\n"
2404 " <version>1.0</version>\n"
2405 " </hal>\n"
2406 "</manifest>\n";
2407 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2408 const ManifestHal* foo = manifest.getHal("android.hardware.foo", {1, 0});
2409 ASSERT_NE(nullptr, foo);
2410 EXPECT_TRUE(foo->isOverride);
2411 const ManifestHal* bar = manifest.getHal("android.hardware.bar", {1, 0});
2412 ASSERT_NE(nullptr, bar);
2413 EXPECT_FALSE(bar->isOverride);
2414}
2415
2416// Test functionality of override="true" tag
2417TEST_F(LibVintfTest, ManifestAddOverrideHalSimple) {
2418 HalManifest manifest;
2419 std::string xml = "<manifest version=\"1.0\" type=\"device\"/>\n";
2420 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2421
2422 HalManifest newManifest;
2423 xml =
2424 "<manifest version=\"1.0\" type=\"device\">\n"
2425 " <hal format=\"hidl\" override=\"true\">\n"
2426 " <name>android.hardware.foo</name>\n"
2427 " <transport>hwbinder</transport>\n"
2428 " <version>1.1</version>\n"
2429 " <interface>\n"
2430 " <name>IFoo</name>\n"
2431 " <instance>default</instance>\n"
2432 " </interface>\n"
2433 " </hal>\n"
2434 "</manifest>\n";
2435 EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
2436
2437 manifest.addAllHals(&newManifest);
2438 EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
2439}
2440
2441TEST_F(LibVintfTest, ManifestAddOverrideHalSimpleOverride) {
2442 HalManifest manifest;
2443 std::string xml =
2444 "<manifest version=\"1.0\" type=\"device\">\n"
2445 " <hal format=\"hidl\">\n"
2446 " <name>android.hardware.foo</name>\n"
2447 " <transport>hwbinder</transport>\n"
2448 " <version>1.0</version>\n"
2449 " </hal>\n"
2450 "</manifest>\n";
2451 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2452
2453 HalManifest newManifest;
2454 xml =
2455 "<manifest version=\"1.0\" type=\"device\">\n"
2456 " <hal format=\"hidl\" override=\"true\">\n"
2457 " <name>android.hardware.foo</name>\n"
2458 " <transport>hwbinder</transport>\n"
2459 " <version>1.1</version>\n"
2460 " <interface>\n"
2461 " <name>IFoo</name>\n"
2462 " <instance>default</instance>\n"
2463 " </interface>\n"
2464 " </hal>\n"
2465 "</manifest>\n";
2466 EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
2467
2468 manifest.addAllHals(&newManifest);
2469 EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
2470}
2471
2472// Existing major versions should be removed.
2473TEST_F(LibVintfTest, ManifestAddOverrideHalMultiVersion) {
2474 HalManifest manifest;
2475 std::string xml =
2476 "<manifest version=\"1.0\" type=\"device\">\n"
2477 " <hal format=\"hidl\">\n"
2478 " <name>android.hardware.foo</name>\n"
2479 " <transport>hwbinder</transport>\n"
2480 " <version>1.3</version>\n"
2481 " <version>2.4</version>\n"
2482 " <interface>\n"
2483 " <name>IFoo</name>\n"
2484 " <instance>slot1</instance>\n"
2485 " </interface>\n"
2486 " </hal>\n"
2487 " <hal format=\"hidl\">\n"
2488 " <name>android.hardware.bar</name>\n"
2489 " <transport>hwbinder</transport>\n"
2490 " <version>1.3</version>\n"
2491 " </hal>\n"
2492 "</manifest>\n";
2493 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2494
2495 HalManifest newManifest;
2496 xml =
2497 "<manifest version=\"1.0\" type=\"device\">\n"
2498 " <hal format=\"hidl\" override=\"true\">\n"
2499 " <name>android.hardware.foo</name>\n"
2500 " <transport>hwbinder</transport>\n"
2501 " <version>1.1</version>\n"
2502 " <version>3.1</version>\n"
2503 " <interface>\n"
2504 " <name>IFoo</name>\n"
2505 " <instance>slot2</instance>\n"
2506 " </interface>\n"
2507 " </hal>\n"
2508 "</manifest>\n";
2509 EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
2510
2511 manifest.addAllHals(&newManifest);
2512 EXPECT_EQ(
2513 "<manifest version=\"1.0\" type=\"device\">\n"
2514 " <hal format=\"hidl\">\n"
2515 " <name>android.hardware.bar</name>\n"
2516 " <transport>hwbinder</transport>\n"
2517 " <version>1.3</version>\n"
2518 " </hal>\n"
2519 " <hal format=\"hidl\">\n"
2520 " <name>android.hardware.foo</name>\n"
2521 " <transport>hwbinder</transport>\n"
2522 " <version>2.4</version>\n"
2523 " <interface>\n"
2524 " <name>IFoo</name>\n"
2525 " <instance>slot1</instance>\n"
2526 " </interface>\n"
2527 " </hal>\n"
2528 " <hal format=\"hidl\" override=\"true\">\n"
2529 " <name>android.hardware.foo</name>\n"
2530 " <transport>hwbinder</transport>\n"
2531 " <version>1.1</version>\n"
2532 " <version>3.1</version>\n"
2533 " <interface>\n"
2534 " <name>IFoo</name>\n"
2535 " <instance>slot2</instance>\n"
2536 " </interface>\n"
2537 " </hal>\n"
2538 "</manifest>\n",
2539 gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
2540}
2541
2542TEST_F(LibVintfTest, ManifestAddOverrideHalMultiVersion2) {
2543 HalManifest manifest;
2544 std::string xml =
2545 "<manifest version=\"1.0\" type=\"device\">\n"
2546 " <hal format=\"hidl\">\n"
2547 " <name>android.hardware.foo</name>\n"
2548 " <transport>hwbinder</transport>\n"
2549 " <version>1.3</version>\n"
2550 " <version>2.4</version>\n"
2551 " <interface>\n"
2552 " <name>IFoo</name>\n"
2553 " <instance>slot1</instance>\n"
2554 " </interface>\n"
2555 " </hal>\n"
2556 "</manifest>\n";
2557 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2558
2559 HalManifest newManifest;
2560 xml =
2561 "<manifest version=\"1.0\" type=\"device\">\n"
2562 " <hal format=\"hidl\" override=\"true\">\n"
2563 " <name>android.hardware.foo</name>\n"
2564 " <transport>hwbinder</transport>\n"
2565 " <version>1.1</version>\n"
2566 " <version>2.1</version>\n"
2567 " <interface>\n"
2568 " <name>IFoo</name>\n"
2569 " <instance>slot2</instance>\n"
2570 " </interface>\n"
2571 " </hal>\n"
2572 "</manifest>\n";
2573 EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
2574
2575 manifest.addAllHals(&newManifest);
2576 EXPECT_EQ(xml, gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
2577}
2578
2579// if no <versions>, remove all existing <hal> with given <name>.
2580TEST_F(LibVintfTest, ManifestAddOverrideHalRemoveAll) {
2581 HalManifest manifest;
2582 std::string xml =
2583 "<manifest version=\"1.0\" type=\"device\">\n"
2584 " <hal format=\"hidl\">\n"
2585 " <name>android.hardware.foo</name>\n"
2586 " <transport>hwbinder</transport>\n"
2587 " <version>1.3</version>\n"
2588 " <version>2.4</version>\n"
2589 " <interface>\n"
2590 " <name>IFoo</name>\n"
2591 " <instance>slot1</instance>\n"
2592 " </interface>\n"
2593 " </hal>\n"
2594 " <hal format=\"hidl\">\n"
2595 " <name>android.hardware.foo</name>\n"
2596 " <transport>hwbinder</transport>\n"
2597 " <version>3.1</version>\n"
2598 " <version>4.3</version>\n"
2599 " <interface>\n"
2600 " <name>IBar</name>\n"
2601 " <instance>slot2</instance>\n"
2602 " </interface>\n"
2603 " </hal>\n"
2604 " <hal format=\"hidl\">\n"
2605 " <name>android.hardware.bar</name>\n"
2606 " <transport>hwbinder</transport>\n"
2607 " <version>1.3</version>\n"
2608 " </hal>\n"
2609 "</manifest>\n";
2610 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2611
2612 HalManifest newManifest;
2613 xml =
2614 "<manifest version=\"1.0\" type=\"device\">\n"
2615 " <hal format=\"hidl\" override=\"true\">\n"
2616 " <name>android.hardware.foo</name>\n"
2617 " <transport>hwbinder</transport>\n"
2618 " </hal>\n"
2619 "</manifest>\n";
2620 EXPECT_TRUE(gHalManifestConverter(&newManifest, xml)) << gHalManifestConverter.lastError();
2621
2622 manifest.addAllHals(&newManifest);
2623 EXPECT_EQ(
2624 "<manifest version=\"1.0\" type=\"device\">\n"
2625 " <hal format=\"hidl\">\n"
2626 " <name>android.hardware.bar</name>\n"
2627 " <transport>hwbinder</transport>\n"
2628 " <version>1.3</version>\n"
2629 " </hal>\n"
2630 " <hal format=\"hidl\" override=\"true\">\n"
2631 " <name>android.hardware.foo</name>\n"
2632 " <transport>hwbinder</transport>\n"
2633 " </hal>\n"
2634 "</manifest>\n",
2635 gHalManifestConverter(manifest, SerializeFlag::HALS_ONLY));
2636}
2637
2638// Make sure missing tags in old VINTF files does not cause incompatibilities.
2639TEST_F(LibVintfTest, Empty) {
2640 CompatibilityMatrix cm;
2641 HalManifest manifest;
2642 std::string xml;
2643 std::string error;
2644
2645 xml = "<compatibility-matrix version=\"1.0\" type=\"device\"/>\n";
2646 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
2647 << gCompatibilityMatrixConverter.lastError();
2648
2649 xml = "<manifest version=\"1.0\" type=\"framework\"/>\n";
2650 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2651
2652 EXPECT_TRUE(manifest.checkCompatibility(cm, &error)) << error;
2653}
2654
2655TEST_F(LibVintfTest, SystemSdk) {
2656 CompatibilityMatrix cm;
2657 std::string xml;
2658 std::string error;
2659
2660 xml =
2661 "<compatibility-matrix version=\"1.0\" type=\"device\">\n"
2662 " <system-sdk>\n"
2663 " <version>1</version>\n"
2664 " <version>P</version>\n"
2665 " </system-sdk>\n"
2666 "</compatibility-matrix>\n";
2667 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml))
2668 << gCompatibilityMatrixConverter.lastError();
2669 EXPECT_EQ(xml, gCompatibilityMatrixConverter(cm, ~SerializeFlag::NO_SSDK));
2670
2671 {
2672 HalManifest manifest;
2673 xml =
2674 "<manifest version=\"1.0\" type=\"framework\">\n"
2675 " <system-sdk>\n"
2676 " <version>1</version>\n"
2677 " <version>P</version>\n"
2678 " </system-sdk>\n"
2679 "</manifest>\n";
2680 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2681 EXPECT_EQ(xml, gHalManifestConverter(manifest, ~SerializeFlag::NO_SSDK));
2682
2683 EXPECT_TRUE(manifest.checkCompatibility(cm, &error)) << error;
2684 }
2685
2686 {
2687 HalManifest manifest;
2688 xml =
2689 "<manifest version=\"1.0\" type=\"framework\">\n"
2690 " <system-sdk>\n"
2691 " <version>1</version>\n"
2692 " <version>3</version>\n"
2693 " <version>P</version>\n"
2694 " </system-sdk>\n"
2695 "</manifest>\n";
2696 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2697 EXPECT_TRUE(manifest.checkCompatibility(cm, &error));
2698 }
2699
2700 {
2701 HalManifest manifest;
2702 xml =
2703 "<manifest version=\"1.0\" type=\"framework\">\n"
2704 " <system-sdk>\n"
2705 " <version>1</version>\n"
2706 " </system-sdk>\n"
2707 "</manifest>\n";
2708 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2709 EXPECT_FALSE(manifest.checkCompatibility(cm, &error));
2710 EXPECT_TRUE(error.find("System SDK") != std::string::npos) << error;
2711 }
2712}
2713
2392} // namespace vintf 2714} // namespace vintf
2393} // namespace android 2715} // namespace android
2394 2716
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 2dc2d8a..f75baa3 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -175,38 +175,45 @@ void setupMockFetcher(const std::string& vendorManifestXml, const std::string& s
175 MockFileFetcher* fetcher = static_cast<MockFileFetcher*>(gFetcher); 175 MockFileFetcher* fetcher = static_cast<MockFileFetcher*>(gFetcher);
176 176
177 if (!productModel.empty()) { 177 if (!productModel.empty()) {
178 ON_CALL(*fetcher, fetch(StrEq("/odm/etc/manifest_" + productModel + ".xml"), _)) 178 ON_CALL(*fetcher, fetch(StrEq(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml"), _))
179 .WillByDefault(Return(::android::NAME_NOT_FOUND));
180 ON_CALL(*fetcher, fetch(StrEq(kOdmVintfDir + "manifest_" + productModel + ".xml"), _))
179 .WillByDefault(Return(::android::NAME_NOT_FOUND)); 181 .WillByDefault(Return(::android::NAME_NOT_FOUND));
180 } 182 }
181 ON_CALL(*fetcher, fetch(StrEq("/odm/etc/manifest.xml"), _)) 183 ON_CALL(*fetcher, fetch(StrEq(kOdmLegacyManifest), _))
184 .WillByDefault(Return(::android::NAME_NOT_FOUND));
185 ON_CALL(*fetcher, fetch(StrEq(kOdmManifest), _))
186 .WillByDefault(Return(::android::NAME_NOT_FOUND));
187 ON_CALL(*fetcher, fetch(StrEq(kVendorManifest), _))
182 .WillByDefault(Return(::android::NAME_NOT_FOUND)); 188 .WillByDefault(Return(::android::NAME_NOT_FOUND));
183 ON_CALL(*fetcher, fetch(StrEq("/vendor/manifest.xml"), _)) 189 ON_CALL(*fetcher, fetch(StrEq(kVendorLegacyManifest), _))
184 .WillByDefault(Invoke([vendorManifestXml](const std::string& path, std::string& fetched) { 190 .WillByDefault(Invoke([vendorManifestXml](const std::string& path, std::string& fetched) {
185 (void)path; 191 (void)path;
186 fetched = vendorManifestXml; 192 fetched = vendorManifestXml;
187 return 0; 193 return 0;
188 })); 194 }));
189 ON_CALL(*fetcher, fetch(StrEq("/system/manifest.xml"), _)) 195 ON_CALL(*fetcher, fetch(StrEq(kSystemManifest), _))
190 .WillByDefault(Invoke([systemManifestXml](const std::string& path, std::string& fetched) { 196 .WillByDefault(Invoke([systemManifestXml](const std::string& path, std::string& fetched) {
191 (void)path; 197 (void)path;
192 fetched = systemManifestXml; 198 fetched = systemManifestXml;
193 return 0; 199 return 0;
194 })); 200 }));
195 ON_CALL(*fetcher, fetch(StrEq("/vendor/compatibility_matrix.xml"), _)) 201 ON_CALL(*fetcher, fetch(StrEq(kVendorMatrix), _))
202 .WillByDefault(Return(::android::NAME_NOT_FOUND));
203 ON_CALL(*fetcher, fetch(StrEq(kVendorLegacyMatrix), _))
196 .WillByDefault(Invoke([vendorMatrixXml](const std::string& path, std::string& fetched) { 204 .WillByDefault(Invoke([vendorMatrixXml](const std::string& path, std::string& fetched) {
197 (void)path; 205 (void)path;
198 fetched = vendorMatrixXml; 206 fetched = vendorMatrixXml;
199 return 0; 207 return 0;
200 })); 208 }));
201 ON_CALL(*fetcher, fetch(StrEq("/system/compatibility_matrix.xml"), _)) 209 ON_CALL(*fetcher, fetch(StrEq(kSystemLegacyMatrix), _))
202 .WillByDefault(Invoke([systemMatrixXml](const std::string& path, std::string& fetched) { 210 .WillByDefault(Invoke([systemMatrixXml](const std::string& path, std::string& fetched) {
203 (void)path; 211 (void)path;
204 fetched = systemMatrixXml; 212 fetched = systemMatrixXml;
205 return 0; 213 return 0;
206 })); 214 }));
207 // Don't list /system/etc/vintf unless otherwise specified. 215 // Don't list /system/etc/vintf unless otherwise specified.
208 ON_CALL(*fetcher, listFiles(StrEq("/system/etc/vintf/"), _, _)) 216 ON_CALL(*fetcher, listFiles(StrEq(kSystemVintfDir), _, _)).WillByDefault(Return(::android::OK));
209 .WillByDefault(Return(::android::OK));
210} 217}
211 218
212static MockPartitionMounter &mounter() { 219static MockPartitionMounter &mounter() {
@@ -215,37 +222,92 @@ static MockPartitionMounter &mounter() {
215static MockFileFetcher &fetcher() { 222static MockFileFetcher &fetcher() {
216 return *static_cast<MockFileFetcher*>(gFetcher); 223 return *static_cast<MockFileFetcher*>(gFetcher);
217} 224}
218// Test fixture that provides compatible metadata from the mock device. 225
219class VintfObjectCompatibleTest : public testing::Test { 226class VintfObjectTestBase : public testing::Test {
220 protected: 227 protected:
221 virtual void SetUp() { 228 virtual void SetUp() {
222 mounter().reset();
223#ifdef LIBVINTF_TARGET 229#ifdef LIBVINTF_TARGET
224 productModel = android::base::GetProperty("ro.boot.product.hardware.sku", ""); 230 productModel = android::base::GetProperty("ro.boot.product.hardware.sku", "");
225#endif 231#endif
226 setupMockFetcher(vendorManifestXml1, systemMatrixXml1, systemManifestXml1, vendorMatrixXml1,
227 productModel);
228 } 232 }
229 virtual void TearDown() { 233 virtual void TearDown() {
230 Mock::VerifyAndClear(&mounter()); 234 Mock::VerifyAndClear(&mounter());
231 Mock::VerifyAndClear(&fetcher()); 235 Mock::VerifyAndClear(&fetcher());
232 } 236 }
237
238 void expectVendorManifest(size_t times = 1) {
239 EXPECT_CALL(fetcher(), fetch(StrEq(kVendorManifest), _)).Times(times);
240 if (!productModel.empty()) {
241 EXPECT_CALL(fetcher(),
242 fetch(StrEq(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml"), _))
243 .Times(times);
244 EXPECT_CALL(fetcher(),
245 fetch(StrEq(kOdmVintfDir + "manifest_" + productModel + ".xml"), _))
246 .Times(times);
247 }
248 EXPECT_CALL(fetcher(), fetch(StrEq(kOdmLegacyManifest), _)).Times(times);
249 EXPECT_CALL(fetcher(), fetch(StrEq(kOdmManifest), _)).Times(times);
250 EXPECT_CALL(fetcher(), fetch(StrEq(kVendorLegacyManifest), _)).Times(times);
251 }
252
253 void expectSystemManifest(size_t times = 1) {
254 EXPECT_CALL(fetcher(), fetch(StrEq(kSystemManifest), _)).Times(times);
255 }
256
257 void expectVendorMatrix(size_t times = 1) {
258 EXPECT_CALL(fetcher(), fetch(StrEq(kVendorMatrix), _)).Times(times);
259 EXPECT_CALL(fetcher(), fetch(StrEq(kVendorLegacyMatrix), _)).Times(times);
260 }
261
262 void expectSystemMatrix(size_t times = 1) {
263 EXPECT_CALL(fetcher(), fetch(StrEq(kSystemLegacyMatrix), _)).Times(times);
264 }
265
266 // Expect that a file exist and should be fetched once.
267 void expectFetch(const std::string& path, const std::string& content) {
268 EXPECT_CALL(fetcher(), fetch(StrEq(path), _))
269 .WillOnce(Invoke([content](const auto&, auto& out) {
270 out = content;
271 return ::android::OK;
272 }));
273 }
274
275 // Expect that the file should never be fetched (whether it exists or not).
276 void expectNeverFetch(const std::string& path) {
277 EXPECT_CALL(fetcher(), fetch(StrEq(path), _)).Times(0);
278 }
279
280 // Expect that the file does not exist, and can be fetched 0 or more times.
281 template <typename Matcher>
282 void expectFileNotExist(const Matcher& matcher) {
283 EXPECT_CALL(fetcher(), fetch(matcher, _))
284 .Times(AnyNumber())
285 .WillRepeatedly(Return(::android::NAME_NOT_FOUND));
286 }
287
233 std::string productModel; 288 std::string productModel;
234}; 289};
235 290
291// Test fixture that provides compatible metadata from the mock device.
292class VintfObjectCompatibleTest : public VintfObjectTestBase {
293 protected:
294 virtual void SetUp() {
295 VintfObjectTestBase::SetUp();
296 mounter().reset();
297 setupMockFetcher(vendorManifestXml1, systemMatrixXml1, systemManifestXml1, vendorMatrixXml1,
298 productModel);
299 }
300};
301
236// Tests that local info is checked. 302// Tests that local info is checked.
237TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibility) { 303TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibility) {
238 std::string error; 304 std::string error;
239 std::vector<std::string> packageInfo; 305 std::vector<std::string> packageInfo;
240 306
241 if (!productModel.empty()) { 307 expectVendorManifest();
242 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest_" + productModel + ".xml"), _)); 308 expectSystemManifest();
243 } 309 expectVendorMatrix();
244 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest.xml"), _)); 310 expectSystemMatrix();
245 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
246 EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
247 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
248 EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _));
249 EXPECT_CALL(mounter(), mountSystem()).Times(0); 311 EXPECT_CALL(mounter(), mountSystem()).Times(0);
250 EXPECT_CALL(mounter(), umountSystem()).Times(0); 312 EXPECT_CALL(mounter(), umountSystem()).Times(0);
251 EXPECT_CALL(mounter(), mountVendor()).Times(0); 313 EXPECT_CALL(mounter(), mountVendor()).Times(0);
@@ -281,14 +343,10 @@ TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceSuccess) {
281 std::string error; 343 std::string error;
282 std::vector<std::string> packageInfo = {systemMatrixXml1}; 344 std::vector<std::string> packageInfo = {systemMatrixXml1};
283 345
284 if (!productModel.empty()) { 346 expectVendorManifest();
285 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest_" + productModel + ".xml"), _)); 347 expectSystemManifest();
286 } 348 expectVendorMatrix();
287 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest.xml"), _)); 349 expectSystemMatrix(0);
288 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
289 EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
290 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
291 EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
292 EXPECT_CALL(mounter(), mountSystem()).Times(0); 350 EXPECT_CALL(mounter(), mountSystem()).Times(0);
293 EXPECT_CALL(mounter(), umountSystem()).Times(0); 351 EXPECT_CALL(mounter(), umountSystem()).Times(0);
294 EXPECT_CALL(mounter(), mountVendor()).Times(0); 352 EXPECT_CALL(mounter(), mountVendor()).Times(0);
@@ -346,14 +404,10 @@ TEST_F(VintfObjectCompatibleTest, TestFrameworkOnlyOta) {
346 std::string error; 404 std::string error;
347 std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1}; 405 std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1};
348 406
349 if (!productModel.empty()) { 407 expectVendorManifest();
350 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest_" + productModel + ".xml"), _)); 408 expectSystemManifest(0);
351 } 409 expectVendorMatrix();
352 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest.xml"), _)); 410 expectSystemMatrix(0);
353 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
354 EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _)).Times(0);
355 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
356 EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
357 EXPECT_CALL(mounter(), mountSystem()).Times(0); 411 EXPECT_CALL(mounter(), mountSystem()).Times(0);
358 EXPECT_CALL(mounter(), umountSystem()).Times(0); 412 EXPECT_CALL(mounter(), umountSystem()).Times(0);
359 EXPECT_CALL(mounter(), mountVendor()).Times(0); 413 EXPECT_CALL(mounter(), mountVendor()).Times(0);
@@ -388,15 +442,10 @@ TEST_F(VintfObjectCompatibleTest, TestFullOta) {
388 std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1, 442 std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1,
389 vendorMatrixXml1, vendorManifestXml1}; 443 vendorMatrixXml1, vendorManifestXml1};
390 444
391 if (!productModel.empty()) { 445 expectVendorManifest(0);
392 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest_" + productModel + ".xml"), _)) 446 expectSystemManifest(0);
393 .Times(0); 447 expectVendorMatrix(0);
394 } 448 expectSystemMatrix(0);
395 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest.xml"), _)).Times(0);
396 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _)).Times(0);
397 EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _)).Times(0);
398 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _)).Times(0);
399 EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
400 EXPECT_CALL(mounter(), mountSystem()).Times(0); 449 EXPECT_CALL(mounter(), mountSystem()).Times(0);
401 EXPECT_CALL(mounter(), umountSystem()).Times(0); 450 EXPECT_CALL(mounter(), umountSystem()).Times(0);
402 EXPECT_CALL(mounter(), mountVendor()).Times(0); 451 EXPECT_CALL(mounter(), mountVendor()).Times(0);
@@ -428,21 +477,14 @@ TEST_F(VintfObjectCompatibleTest, TestFullOnlyOtaMount) {
428} 477}
429 478
430// Test fixture that provides incompatible metadata from the mock device. 479// Test fixture that provides incompatible metadata from the mock device.
431class VintfObjectIncompatibleTest : public testing::Test { 480class VintfObjectIncompatibleTest : public VintfObjectTestBase {
432 protected: 481 protected:
433 virtual void SetUp() { 482 virtual void SetUp() {
483 VintfObjectTestBase::SetUp();
434 mounter().reset(); 484 mounter().reset();
435#ifdef LIBVINTF_TARGET
436 productModel = android::base::GetProperty("ro.boot.product.hardware.sku", "");
437#endif
438 setupMockFetcher(vendorManifestXml1, systemMatrixXml2, systemManifestXml1, vendorMatrixXml1, 485 setupMockFetcher(vendorManifestXml1, systemMatrixXml2, systemManifestXml1, vendorMatrixXml1,
439 productModel); 486 productModel);
440 } 487 }
441 virtual void TearDown() {
442 Mock::VerifyAndClear(&mounter());
443 Mock::VerifyAndClear(&fetcher());
444 }
445 std::string productModel;
446}; 488};
447 489
448// Fetch all metadata from device and ensure that it fails. 490// Fetch all metadata from device and ensure that it fails.
@@ -450,14 +492,10 @@ TEST_F(VintfObjectIncompatibleTest, TestDeviceCompatibility) {
450 std::string error; 492 std::string error;
451 std::vector<std::string> packageInfo; 493 std::vector<std::string> packageInfo;
452 494
453 if (!productModel.empty()) { 495 expectVendorManifest();
454 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest_" + productModel + ".xml"), _)); 496 expectSystemManifest();
455 } 497 expectVendorMatrix();
456 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest.xml"), _)); 498 expectSystemMatrix();
457 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
458 EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
459 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
460 EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _));
461 499
462 int result = VintfObject::CheckCompatibility(packageInfo, &error); 500 int result = VintfObject::CheckCompatibility(packageInfo, &error);
463 501
@@ -469,14 +507,10 @@ TEST_F(VintfObjectIncompatibleTest, TestInputVsDeviceSuccess) {
469 std::string error; 507 std::string error;
470 std::vector<std::string> packageInfo = {systemMatrixXml1}; 508 std::vector<std::string> packageInfo = {systemMatrixXml1};
471 509
472 if (!productModel.empty()) { 510 expectVendorManifest();
473 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest_" + productModel + ".xml"), _)); 511 expectSystemManifest();
474 } 512 expectVendorMatrix();
475 EXPECT_CALL(fetcher(), fetch(StrEq("/odm/etc/manifest.xml"), _)); 513 expectSystemMatrix(0);
476 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
477 EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
478 EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
479 EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
480 514
481 int result = VintfObject::CheckCompatibility(packageInfo, &error); 515 int result = VintfObject::CheckCompatibility(packageInfo, &error);
482 516
@@ -525,18 +559,14 @@ TEST_F(VintfObjectRuntimeInfoTest, GetRuntimeInfo) {
525} 559}
526 560
527// Test fixture that provides incompatible metadata from the mock device. 561// Test fixture that provides incompatible metadata from the mock device.
528class VintfObjectTest : public testing::Test { 562class VintfObjectTest : public VintfObjectTestBase {
529 protected: 563 protected:
530 virtual void SetUp() {} 564 virtual void SetUp() {}
531 virtual void TearDown() {
532 Mock::VerifyAndClear(&fetcher());
533 Mock::VerifyAndClear(&mounter());
534 }
535}; 565};
536 566
537// Test framework compatibility matrix is combined at runtime 567// Test framework compatibility matrix is combined at runtime
538TEST_F(VintfObjectTest, FrameworkCompatibilityMatrixCombine) { 568TEST_F(VintfObjectTest, FrameworkCompatibilityMatrixCombine) {
539 EXPECT_CALL(fetcher(), listFiles(StrEq("/system/etc/vintf/"), _, _)) 569 EXPECT_CALL(fetcher(), listFiles(StrEq(kSystemVintfDir), _, _))
540 .WillOnce(Invoke([](const auto&, auto* out, auto*) { 570 .WillOnce(Invoke([](const auto&, auto* out, auto*) {
541 *out = { 571 *out = {
542 "compatibility_matrix.1.xml", 572 "compatibility_matrix.1.xml",
@@ -544,21 +574,208 @@ TEST_F(VintfObjectTest, FrameworkCompatibilityMatrixCombine) {
544 }; 574 };
545 return ::android::OK; 575 return ::android::OK;
546 })); 576 }));
547 EXPECT_CALL(fetcher(), fetch(StrEq("/system/etc/vintf/compatibility_matrix.1.xml"), _)) 577 expectFetch(kSystemVintfDir + "compatibility_matrix.1.xml",
548 .WillOnce(Invoke([](const auto&, auto& out) { 578 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\"/>");
549 out = "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\"/>"; 579 expectFetch(kSystemVintfDir + "compatibility_matrix.empty.xml",
550 return ::android::OK; 580 "<compatibility-matrix version=\"1.0\" type=\"framework\"/>");
551 })); 581 expectSystemMatrix(0);
552 EXPECT_CALL(fetcher(), fetch(StrEq("/system/etc/vintf/compatibility_matrix.empty.xml"), _))
553 .WillOnce(Invoke([](const auto&, auto& out) {
554 out = "<compatibility-matrix version=\"1.0\" type=\"framework\"/>";
555 return ::android::OK;
556 }));
557 EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
558 582
559 EXPECT_NE(nullptr, VintfObject::GetFrameworkCompatibilityMatrix(true /* skipCache */)); 583 EXPECT_NE(nullptr, VintfObject::GetFrameworkCompatibilityMatrix(true /* skipCache */));
560} 584}
561 585
586const std::string vendorEtcManifest =
587 "<manifest version=\"1.0\" type=\"device\">\n"
588 " <hal format=\"hidl\">\n"
589 " <name>android.hardware.foo</name>\n"
590 " <transport>hwbinder</transport>\n"
591 " <version>1.0</version>\n"
592 " <version>2.0</version>\n"
593 " <interface>\n"
594 " <name>IVendorEtc</name>\n"
595 " <instance>default</instance>\n"
596 " </interface>\n"
597 " </hal>\n"
598 "</manifest>\n";
599
600const std::string vendorManifest =
601 "<manifest version=\"1.0\" type=\"device\">\n"
602 " <hal format=\"hidl\">\n"
603 " <name>android.hardware.foo</name>\n"
604 " <transport>hwbinder</transport>\n"
605 " <version>1.0</version>\n"
606 " <interface>\n"
607 " <name>IVendor</name>\n"
608 " <instance>default</instance>\n"
609 " </interface>\n"
610 " </hal>\n"
611 "</manifest>\n";
612
613const std::string odmProductManifest =
614 "<manifest version=\"1.0\" type=\"device\">\n"
615 " <hal format=\"hidl\" override=\"true\">\n"
616 " <name>android.hardware.foo</name>\n"
617 " <transport>hwbinder</transport>\n"
618 " <version>1.1</version>\n"
619 " <interface>\n"
620 " <name>IOdmProduct</name>\n"
621 " <instance>default</instance>\n"
622 " </interface>\n"
623 " </hal>\n"
624 "</manifest>\n";
625
626const std::string odmManifest =
627 "<manifest version=\"1.0\" type=\"device\">\n"
628 " <hal format=\"hidl\" override=\"true\">\n"
629 " <name>android.hardware.foo</name>\n"
630 " <transport>hwbinder</transport>\n"
631 " <version>1.1</version>\n"
632 " <interface>\n"
633 " <name>IOdm</name>\n"
634 " <instance>default</instance>\n"
635 " </interface>\n"
636 " </hal>\n"
637 "</manifest>\n";
638
639bool containsVendorManifest(const std::shared_ptr<const HalManifest>& p) {
640 return !p->getInstances("android.hardware.foo", {1, 0}, "IVendor").empty();
641}
642
643bool containsVendorEtcManifest(const std::shared_ptr<const HalManifest>& p) {
644 return !p->getInstances("android.hardware.foo", {2, 0}, "IVendorEtc").empty();
645}
646
647bool vendorEtcManifestOverridden(const std::shared_ptr<const HalManifest>& p) {
648 return p->getInstances("android.hardware.foo", {1, 0}, "IVendorEtc").empty();
649}
650
651bool containsOdmManifest(const std::shared_ptr<const HalManifest>& p) {
652 return !p->getInstances("android.hardware.foo", {1, 1}, "IOdm").empty();
653}
654
655bool containsOdmProductManifest(const std::shared_ptr<const HalManifest>& p) {
656 return !p->getInstances("android.hardware.foo", {1, 1}, "IOdmProduct").empty();
657}
658
659class DeviceManifestTest : public VintfObjectTestBase {
660 protected:
661 virtual void SetUp() override {}
662
663 // Expect that /vendor/etc/vintf/manifest.xml is fetched.
664 void expectVendorManifest() { expectFetch(kVendorManifest, vendorEtcManifest); }
665 // /vendor/etc/vintf/manifest.xml does not exist.
666 void noVendorManifest() { expectFileNotExist(StrEq(kVendorManifest)); }
667 // Expect some ODM manifest is fetched.
668 void expectOdmManifest() {
669 if (!productModel.empty()) {
670 expectFileNotExist(StrEq(kOdmVintfDir + "manifest_" + productModel + ".xml"));
671 }
672 expectFetch(kOdmManifest, odmManifest);
673 }
674 void noOdmManifest() { expectFileNotExist(StartsWith("/odm/")); }
675 std::shared_ptr<const HalManifest> get() {
676 return VintfObject::GetDeviceHalManifest(true /* skipCache */);
677 }
678};
679
680// Test /vendor/etc/vintf/manifest.xml + ODM manifest
681TEST_F(DeviceManifestTest, Combine1) {
682 expectVendorManifest();
683 expectOdmManifest();
684 auto p = get();
685 ASSERT_NE(nullptr, p);
686 EXPECT_TRUE(containsVendorEtcManifest(p));
687 EXPECT_TRUE(vendorEtcManifestOverridden(p));
688 EXPECT_TRUE(containsOdmManifest(p));
689 EXPECT_FALSE(containsVendorManifest(p));
690}
691
692// Test /vendor/etc/vintf/manifest.xml
693TEST_F(DeviceManifestTest, Combine2) {
694 expectVendorManifest();
695 noOdmManifest();
696 auto p = get();
697 ASSERT_NE(nullptr, p);
698 EXPECT_TRUE(containsVendorEtcManifest(p));
699 EXPECT_FALSE(vendorEtcManifestOverridden(p));
700 EXPECT_FALSE(containsOdmManifest(p));
701 EXPECT_FALSE(containsVendorManifest(p));
702}
703
704// Test ODM manifest
705TEST_F(DeviceManifestTest, Combine3) {
706 noVendorManifest();
707 expectOdmManifest();
708 auto p = get();
709 ASSERT_NE(nullptr, p);
710 EXPECT_FALSE(containsVendorEtcManifest(p));
711 EXPECT_TRUE(vendorEtcManifestOverridden(p));
712 EXPECT_TRUE(containsOdmManifest(p));
713 EXPECT_FALSE(containsVendorManifest(p));
714}
715
716// Test /vendor/manifest.xml
717TEST_F(DeviceManifestTest, Combine4) {
718 noVendorManifest();
719 noOdmManifest();
720 expectFetch(kVendorLegacyManifest, vendorManifest);
721 auto p = get();
722 ASSERT_NE(nullptr, p);
723 EXPECT_FALSE(containsVendorEtcManifest(p));
724 EXPECT_TRUE(vendorEtcManifestOverridden(p));
725 EXPECT_FALSE(containsOdmManifest(p));
726 EXPECT_TRUE(containsVendorManifest(p));
727}
728
729class OdmManifestTest : public VintfObjectTestBase {
730 protected:
731 virtual void SetUp() override {
732 // Assume /vendor/etc/vintf/manifest.xml does not exist to simplify
733 // testing logic.
734 expectFileNotExist(StrEq(kVendorManifest));
735 // Expect that the legacy /vendor/manifest.xml is never fetched.
736 expectNeverFetch(kVendorLegacyManifest);
737 // Assume no files exist under /odm/ unless otherwise specified.
738 expectFileNotExist(StartsWith("/odm/"));
739 }
740 std::shared_ptr<const HalManifest> get() {
741 return VintfObject::GetDeviceHalManifest(true /* skipCache */);
742 }
743};
744
745TEST_F(OdmManifestTest, OdmProductManifest) {
746 if (productModel.empty()) return;
747 expectFetch(kOdmVintfDir + "manifest_" + productModel + ".xml", odmProductManifest);
748 // /odm/etc/vintf/manifest.xml should not be fetched when the product variant exists.
749 expectNeverFetch(kOdmManifest);
750 auto p = get();
751 ASSERT_NE(nullptr, p);
752 EXPECT_TRUE(containsOdmProductManifest(p));
753}
754
755TEST_F(OdmManifestTest, OdmManifest) {
756 expectFetch(kOdmManifest, odmManifest);
757 auto p = get();
758 ASSERT_NE(nullptr, p);
759 EXPECT_TRUE(containsOdmManifest(p));
760}
761
762TEST_F(OdmManifestTest, OdmLegacyProductManifest) {
763 if (productModel.empty()) return;
764 expectFetch(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml", odmProductManifest);
765 // /odm/manifest.xml should not be fetched when the product variant exists.
766 expectNeverFetch(kOdmLegacyManifest);
767 auto p = get();
768 ASSERT_NE(nullptr, p);
769 EXPECT_TRUE(containsOdmProductManifest(p));
770}
771
772TEST_F(OdmManifestTest, OdmLegacyManifest) {
773 expectFetch(kOdmLegacyManifest, odmManifest);
774 auto p = get();
775 ASSERT_NE(nullptr, p);
776 EXPECT_TRUE(containsOdmManifest(p));
777}
778
562int main(int argc, char** argv) { 779int main(int argc, char** argv) {
563 ::testing::InitGoogleMock(&argc, argv); 780 ::testing::InitGoogleMock(&argc, argv);
564 781
diff --git a/utils.h b/utils.h
index c3dcd53..3779614 100644
--- a/utils.h
+++ b/utils.h
@@ -46,7 +46,7 @@ class FileFetcher {
46 if (error) { 46 if (error) {
47 *error = "Cannot open " + path; 47 *error = "Cannot open " + path;
48 } 48 }
49 return INVALID_OPERATION; 49 return NAME_NOT_FOUND;
50 } 50 }
51 51
52 std::stringstream ss; 52 std::stringstream ss;