diff options
-rw-r--r-- | Android.bp | 50 | ||||
-rw-r--r-- | AssembleVintf.cpp | 27 | ||||
-rw-r--r-- | CompatibilityMatrix.cpp | 3 | ||||
-rw-r--r-- | HalManifest.cpp | 70 | ||||
-rw-r--r-- | SystemSdk.cpp | 36 | ||||
-rw-r--r-- | VintfObject.cpp | 172 | ||||
-rw-r--r-- | include/vintf/CompatibilityMatrix.h | 2 | ||||
-rw-r--r-- | include/vintf/HalGroup.h | 5 | ||||
-rw-r--r-- | include/vintf/HalManifest.h | 6 | ||||
-rw-r--r-- | include/vintf/ManifestHal.h | 1 | ||||
-rw-r--r-- | include/vintf/SystemSdk.h | 50 | ||||
-rw-r--r-- | include/vintf/VintfObject.h | 19 | ||||
-rw-r--r-- | include/vintf/parse_string.h | 1 | ||||
-rw-r--r-- | include/vintf/parse_xml.h | 1 | ||||
-rw-r--r-- | parse_xml.cpp | 37 | ||||
-rw-r--r-- | test/AssembleVintfTest.cpp | 31 | ||||
-rw-r--r-- | test/LibVintfTest.cpp | 322 | ||||
-rw-r--r-- | test/vintf_object_tests.cpp | 393 | ||||
-rw-r--r-- | utils.h | 2 |
19 files changed, 1061 insertions, 167 deletions
@@ -24,34 +24,41 @@ cc_defaults { | |||
24 | ], | 24 | ], |
25 | } | 25 | } |
26 | 26 | ||
27 | cc_library { | 27 | cc_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 | |||
47 | cc_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 | ||
137 | cc_library_static { | 144 | cc_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. | ||
62 | template <typename List, typename Predicate> | ||
63 | static 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 | |||
73 | void 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 | |||
87 | bool 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 | |||
56 | bool HalManifest::shouldAddXmlFile(const ManifestXmlFile& xmlFile) const { | 103 | bool 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 | ||
304 | static 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 | |||
257 | bool HalManifest::checkCompatibility(const CompatibilityMatrix &mat, std::string *error) const { | 320 | bool 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 | |||
21 | namespace android { | ||
22 | namespace vintf { | ||
23 | |||
24 | SystemSdk 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 | |||
31 | bool 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 | |||
37 | using std::placeholders::_1; | 35 | using std::placeholders::_1; |
38 | using std::placeholders::_2; | 36 | using std::placeholders::_2; |
39 | 37 | ||
40 | namespace android { | 38 | namespace android { |
41 | namespace vintf { | 39 | namespace vintf { |
42 | 40 | ||
41 | using namespace details; | ||
42 | |||
43 | template <typename T> | 43 | template <typename T> |
44 | struct LockedSharedPtr { | 44 | struct 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 |
75 | std::shared_ptr<const HalManifest> VintfObject::GetDeviceHalManifest(bool skipCache) { | 75 | std::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 |
108 | std::shared_ptr<const HalManifest> VintfObject::GetFrameworkHalManifest(bool skipCache) { | 81 | std::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 |
116 | std::shared_ptr<const CompatibilityMatrix> VintfObject::GetDeviceCompatibilityMatrix(bool skipCache) { | 89 | std::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 | ||
146 | status_t VintfObject::GetCombinedFrameworkMatrix( | 116 | status_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) | ||
178 | status_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 | ||
215 | status_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. | ||
256 | status_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 | |||
266 | status_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 | |||
201 | std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels( | 275 | std::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 | ||
546 | const std::string kSystemVintfDir = "/system/etc/vintf/"; | ||
547 | const std::string kVendorVintfDir = "/vendor/etc/vintf/"; | ||
548 | const std::string kOdmVintfDir = "/odm/etc/vintf/"; | ||
549 | |||
550 | const std::string kVendorManifest = kVendorVintfDir + "manifest.xml"; | ||
551 | const std::string kSystemManifest = kSystemVintfDir + "manifest.xml"; | ||
552 | const std::string kVendorMatrix = kVendorVintfDir + "compatibility_matrix.xml"; | ||
553 | const std::string kOdmManifest = kOdmVintfDir + "manifest.xml"; | ||
554 | |||
555 | const std::string kVendorLegacyManifest = "/vendor/manifest.xml"; | ||
556 | const std::string kVendorLegacyMatrix = "/vendor/compatibility_matrix.xml"; | ||
557 | const std::string kSystemLegacyMatrix = "/system/compatibility_matrix.xml"; | ||
558 | const std::string kOdmLegacyVintfDir = "/odm/etc/"; | ||
559 | const 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 | |||
25 | namespace android { | ||
26 | namespace vintf { | ||
27 | |||
28 | // System SDK versions provided for vendor apps. | ||
29 | class 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 | ||
123 | enum : int32_t { | 128 | enum : int32_t { |
@@ -131,6 +136,20 @@ class PartitionMounter; | |||
131 | int32_t checkCompatibility(const std::vector<std::string>& xmls, bool mount, | 136 | int32_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 | |||
140 | extern const std::string kSystemVintfDir; | ||
141 | extern const std::string kVendorVintfDir; | ||
142 | extern const std::string kOdmVintfDir; | ||
143 | extern const std::string kOdmLegacyVintfDir; | ||
144 | extern const std::string kOdmLegacyManifest; | ||
145 | extern const std::string kVendorManifest; | ||
146 | extern const std::string kSystemManifest; | ||
147 | extern const std::string kVendorMatrix; | ||
148 | extern const std::string kOdmManifest; | ||
149 | extern const std::string kVendorLegacyManifest; | ||
150 | extern const std::string kVendorLegacyMatrix; | ||
151 | extern 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); | |||
36 | std::ostream &operator<<(std::ostream &os, SchemaType ksv); | 36 | std::ostream &operator<<(std::ostream &os, SchemaType ksv); |
37 | std::ostream& operator<<(std::ostream& os, XmlSchemaFormat f); | 37 | std::ostream& operator<<(std::ostream& os, XmlSchemaFormat f); |
38 | std::ostream& operator<<(std::ostream& os, Level l); | 38 | std::ostream& operator<<(std::ostream& os, Level l); |
39 | std::ostream& operator<<(std::ostream& os, KernelSepolicyVersion v); | ||
39 | std::ostream &operator<<(std::ostream &os, const ManifestHal &hal); | 40 | std::ostream &operator<<(std::ostream &os, const ManifestHal &hal); |
40 | std::ostream &operator<<(std::ostream &os, const Version &ver); | 41 | std::ostream &operator<<(std::ostream &os, const Version &ver); |
41 | std::ostream &operator<<(std::ostream &os, const VersionRange &vr); | 42 | std::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 | ||
738 | const VendorNdkConverter vendorNdkConverter{}; | 742 | const VendorNdkConverter vendorNdkConverter{}; |
739 | 743 | ||
744 | const XmlTextConverter<std::string> systemSdkVersionConverter{"version"}; | ||
745 | |||
746 | struct 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 | |||
756 | const SystemSdkConverter systemSdkConverter{}; | ||
757 | |||
740 | struct HalManifestSepolicyConverter : public XmlNodeConverter<Version> { | 758 | struct 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 | ||
359 | TEST_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 | |||
375 | TEST_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 | ||
2392 | TEST_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 | ||
2417 | TEST_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 | |||
2441 | TEST_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. | ||
2473 | TEST_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 | |||
2542 | TEST_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>. | ||
2580 | TEST_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. | ||
2639 | TEST_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 | |||
2655 | TEST_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 | ||
212 | static MockPartitionMounter &mounter() { | 219 | static MockPartitionMounter &mounter() { |
@@ -215,37 +222,92 @@ static MockPartitionMounter &mounter() { | |||
215 | static MockFileFetcher &fetcher() { | 222 | static 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 | |
219 | class VintfObjectCompatibleTest : public testing::Test { | 226 | class 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. | ||
292 | class 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. |
237 | TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibility) { | 303 | TEST_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. |
431 | class VintfObjectIncompatibleTest : public testing::Test { | 480 | class 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. |
528 | class VintfObjectTest : public testing::Test { | 562 | class 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 |
538 | TEST_F(VintfObjectTest, FrameworkCompatibilityMatrixCombine) { | 568 | TEST_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 | ||
586 | const 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 | |||
600 | const 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 | |||
613 | const 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 | |||
626 | const 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 | |||
639 | bool containsVendorManifest(const std::shared_ptr<const HalManifest>& p) { | ||
640 | return !p->getInstances("android.hardware.foo", {1, 0}, "IVendor").empty(); | ||
641 | } | ||
642 | |||
643 | bool containsVendorEtcManifest(const std::shared_ptr<const HalManifest>& p) { | ||
644 | return !p->getInstances("android.hardware.foo", {2, 0}, "IVendorEtc").empty(); | ||
645 | } | ||
646 | |||
647 | bool vendorEtcManifestOverridden(const std::shared_ptr<const HalManifest>& p) { | ||
648 | return p->getInstances("android.hardware.foo", {1, 0}, "IVendorEtc").empty(); | ||
649 | } | ||
650 | |||
651 | bool containsOdmManifest(const std::shared_ptr<const HalManifest>& p) { | ||
652 | return !p->getInstances("android.hardware.foo", {1, 1}, "IOdm").empty(); | ||
653 | } | ||
654 | |||
655 | bool containsOdmProductManifest(const std::shared_ptr<const HalManifest>& p) { | ||
656 | return !p->getInstances("android.hardware.foo", {1, 1}, "IOdmProduct").empty(); | ||
657 | } | ||
658 | |||
659 | class 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 | ||
681 | TEST_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 | ||
693 | TEST_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 | ||
705 | TEST_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 | ||
717 | TEST_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 | |||
729 | class 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 | |||
745 | TEST_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 | |||
755 | TEST_F(OdmManifestTest, OdmManifest) { | ||
756 | expectFetch(kOdmManifest, odmManifest); | ||
757 | auto p = get(); | ||
758 | ASSERT_NE(nullptr, p); | ||
759 | EXPECT_TRUE(containsOdmManifest(p)); | ||
760 | } | ||
761 | |||
762 | TEST_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 | |||
772 | TEST_F(OdmManifestTest, OdmLegacyManifest) { | ||
773 | expectFetch(kOdmLegacyManifest, odmManifest); | ||
774 | auto p = get(); | ||
775 | ASSERT_NE(nullptr, p); | ||
776 | EXPECT_TRUE(containsOdmManifest(p)); | ||
777 | } | ||
778 | |||
562 | int main(int argc, char** argv) { | 779 | int main(int argc, char** argv) { |
563 | ::testing::InitGoogleMock(&argc, argv); | 780 | ::testing::InitGoogleMock(&argc, argv); |
564 | 781 | ||
@@ -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; |