summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorandroid-build-team Robot2018-02-27 02:26:34 -0600
committerandroid-build-team Robot2018-02-27 02:26:34 -0600
commit9b84203978f6e2ae65adeaedc942b29ea484bcb6 (patch)
treeeeaa9efd899c6b892a44bac94cf47901904516d4
parentf57fb1b2ee6eed3149b4b2efb58c57baa085f0c0 (diff)
parent6fca7f19e5446451372d5760f67125665b27af52 (diff)
downloadplatform-system-libvintf-9b84203978f6e2ae65adeaedc942b29ea484bcb6.tar.gz
platform-system-libvintf-9b84203978f6e2ae65adeaedc942b29ea484bcb6.tar.xz
platform-system-libvintf-9b84203978f6e2ae65adeaedc942b29ea484bcb6.zip
Snap for 4623514 from 6fca7f19e5446451372d5760f67125665b27af52 to pi-release
Change-Id: I40d0b41e3129c393eda33c1f9954b123ecdd2a16
-rw-r--r--HalManifest.cpp73
-rw-r--r--include/vintf/HalManifest.h22
-rw-r--r--include/vintf/VintfObject.h4
-rw-r--r--include/vintf/parse_string.h2
-rw-r--r--parse_string.cpp30
-rw-r--r--test/LibVintfTest.cpp96
-rw-r--r--test/vintf_object_tests.cpp13
7 files changed, 205 insertions, 35 deletions
diff --git a/HalManifest.cpp b/HalManifest.cpp
index e2ae616..540edee 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -34,6 +34,9 @@
34namespace android { 34namespace android {
35namespace vintf { 35namespace vintf {
36 36
37using details::Instances;
38using details::InstancesOfVersion;
39
37// Check <version> tag for all <hal> with the same name. 40// Check <version> tag for all <hal> with the same name.
38bool HalManifest::shouldAdd(const ManifestHal& hal) const { 41bool HalManifest::shouldAdd(const ManifestHal& hal) const {
39 if (!hal.isValid()) { 42 if (!hal.isValid()) {
@@ -196,10 +199,6 @@ void HalManifest::forEachInstance(
196 } 199 }
197} 200}
198 201
199using InstancesOfVersion = std::map<std::string /* interface */,
200 std::set<std::string /* instance */>>;
201using Instances = std::map<Version, InstancesOfVersion>;
202
203static bool satisfyVersion(const MatrixHal& matrixHal, const Version& manifestHalVersion) { 202static bool satisfyVersion(const MatrixHal& matrixHal, const Version& manifestHalVersion) {
204 for (const VersionRange &matrixVersionRange : matrixHal.versionRanges) { 203 for (const VersionRange &matrixVersionRange : matrixHal.versionRanges) {
205 // If Compatibility Matrix says 2.5-2.7, the "2.7" is purely informational; 204 // If Compatibility Matrix says 2.5-2.7, the "2.7" is purely informational;
@@ -231,12 +230,12 @@ static bool satisfyAllInstances(const MatrixHal& matrixHal,
231 return true; 230 return true;
232} 231}
233 232
234bool HalManifest::isCompatible(const MatrixHal& matrixHal) const { 233Instances HalManifest::expandInstances(const std::string& name) const {
235 Instances instances; 234 Instances instances;
236 // Do the cross product version x interface x instance and sort them, 235 // Do the cross product version x interface x instance and sort them,
237 // because interfaces / instances can span in multiple HALs. 236 // because interfaces / instances can span in multiple HALs.
238 // This is efficient for small <hal> entries. 237 // This is efficient for small <hal> entries.
239 for (const ManifestHal* manifestHal : getHals(matrixHal.name)) { 238 for (const ManifestHal* manifestHal : getHals(name)) {
240 for (const Version& manifestHalVersion : manifestHal->versions) { 239 for (const Version& manifestHalVersion : manifestHal->versions) {
241 instances[manifestHalVersion] = {}; 240 instances[manifestHalVersion] = {};
242 for (const auto& halInterfacePair : manifestHal->interfaces) { 241 for (const auto& halInterfacePair : manifestHal->interfaces) {
@@ -246,6 +245,10 @@ bool HalManifest::isCompatible(const MatrixHal& matrixHal) const {
246 } 245 }
247 } 246 }
248 } 247 }
248 return instances;
249}
250
251bool HalManifest::isCompatible(const Instances& instances, const MatrixHal& matrixHal) const {
249 for (const auto& instanceMapPair : instances) { 252 for (const auto& instanceMapPair : instances) {
250 const Version& manifestHalVersion = instanceMapPair.first; 253 const Version& manifestHalVersion = instanceMapPair.first;
251 const InstancesOfVersion& instancesOfVersion = instanceMapPair.second; 254 const InstancesOfVersion& instancesOfVersion = instanceMapPair.second;
@@ -260,20 +263,53 @@ bool HalManifest::isCompatible(const MatrixHal& matrixHal) const {
260 return false; 263 return false;
261} 264}
262 265
266static std::vector<std::string> toLines(const Instances& allInstances) {
267 std::vector<std::string> lines;
268 for (const auto& pair : allInstances) {
269 const auto& version = pair.first;
270 for (const auto& ifacePair : pair.second) {
271 const auto& interface = ifacePair.first;
272 for (const auto& instance : ifacePair.second) {
273 lines.push_back("@" + to_string(version) + "::" + interface + "/" + instance);
274 }
275 }
276 }
277 return lines;
278}
279
280// indent = 2, {"foo"} => "foo"
281// indent = 2, {"foo", "bar"} => "\n foo\n bar";
282void multilineIndent(std::ostream& os, size_t indent, const std::vector<std::string>& lines) {
283 if (lines.size() == 1) {
284 os << lines.front();
285 return;
286 }
287 for (const auto& line : lines) {
288 os << "\n";
289 for (size_t i = 0; i < indent; ++i) os << " ";
290 os << line;
291 }
292}
293
263// For each hal in mat, there must be a hal in manifest that supports this. 294// For each hal in mat, there must be a hal in manifest that supports this.
264std::vector<std::string> HalManifest::checkIncompatibility(const CompatibilityMatrix &mat, 295std::vector<std::string> HalManifest::checkIncompatibleHals(const CompatibilityMatrix& mat) const {
265 bool includeOptional) const { 296 std::vector<std::string> ret;
266 std::vector<std::string> incompatible;
267 for (const MatrixHal &matrixHal : mat.getHals()) { 297 for (const MatrixHal &matrixHal : mat.getHals()) {
268 if (!includeOptional && matrixHal.optional) { 298 if (matrixHal.optional) {
269 continue; 299 continue;
270 } 300 }
271 // don't check optional; put it in the incompatibility list as well. 301 auto manifestInstances = expandInstances(matrixHal.name);
272 if (!isCompatible(matrixHal)) { 302 if (!isCompatible(manifestInstances, matrixHal)) {
273 incompatible.push_back(matrixHal.name); 303 std::ostringstream oss;
304 oss << matrixHal.name << ":\n required: ";
305 multilineIndent(oss, 8, android::vintf::expandInstances(matrixHal));
306 oss << "\n provided: ";
307 multilineIndent(oss, 8, toLines(manifestInstances));
308
309 ret.insert(ret.end(), oss.str());
274 } 310 }
275 } 311 }
276 return incompatible; 312 return ret;
277} 313}
278 314
279static bool checkVendorNdkCompatibility(const VendorNdk& matVendorNdk, 315static bool checkVendorNdkCompatibility(const VendorNdk& matVendorNdk,
@@ -341,13 +377,12 @@ bool HalManifest::checkCompatibility(const CompatibilityMatrix &mat, std::string
341 } 377 }
342 return false; 378 return false;
343 } 379 }
344 std::vector<std::string> incompatibleHals = 380 auto incompatibleHals = checkIncompatibleHals(mat);
345 checkIncompatibility(mat, false /* includeOptional */);
346 if (!incompatibleHals.empty()) { 381 if (!incompatibleHals.empty()) {
347 if (error != nullptr) { 382 if (error != nullptr) {
348 *error = "HALs incompatible."; 383 *error = "HALs incompatible. The following requirements are not met:\n";
349 for (const auto &name : incompatibleHals) { 384 for (const auto& e : incompatibleHals) {
350 *error += " " + name; 385 *error += e + "\n";
351 } 386 }
352 } 387 }
353 return false; 388 return false;
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index b0c4418..e497d42 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -40,6 +40,12 @@ namespace vintf {
40struct MatrixHal; 40struct MatrixHal;
41struct CompatibilityMatrix; 41struct CompatibilityMatrix;
42 42
43namespace details {
44using InstancesOfVersion =
45 std::map<std::string /* interface */, std::set<std::string /* instance */>>;
46using Instances = std::map<Version, InstancesOfVersion>;
47} // namespace details
48
43// A HalManifest is reported by the hardware and query-able from 49// A HalManifest is reported by the hardware and query-able from
44// framework code. This is the API for the framework. 50// framework code. This is the API for the framework.
45struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> { 51struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> {
@@ -67,14 +73,6 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
67 bool hasInstance(const std::string& halName, const Version& version, 73 bool hasInstance(const std::string& halName, const Version& version,
68 const std::string& interfaceName, const std::string& instanceName) const; 74 const std::string& interfaceName, const std::string& instanceName) const;
69 75
70 // Return a list of component names that does NOT conform to
71 // the given compatibility matrix. It contains components that are optional
72 // for the framework if includeOptional = true.
73 // Note: only HAL entries are checked. To check other entries as well, use
74 // checkCompatibility.
75 std::vector<std::string> checkIncompatibility(const CompatibilityMatrix &mat,
76 bool includeOptional = true) const;
77
78 // Check compatibility against a compatibility matrix. Considered compatible if 76 // Check compatibility against a compatibility matrix. Considered compatible if
79 // - framework manifest vs. device compat-mat 77 // - framework manifest vs. device compat-mat
80 // - checkIncompatibility for HALs returns only optional HALs 78 // - checkIncompatibility for HALs returns only optional HALs
@@ -138,11 +136,13 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
138 136
139 status_t fetchAllInformation(const std::string& path, std::string* error = nullptr); 137 status_t fetchAllInformation(const std::string& path, std::string* error = nullptr);
140 138
139 details::Instances expandInstances(const std::string& name) const;
141 // Check if all instances in matrixHal is supported in this manifest. 140 // Check if all instances in matrixHal is supported in this manifest.
142 bool isCompatible(const MatrixHal& matrixHal) const; 141 bool isCompatible(const details::Instances& instances, const MatrixHal& matrixHal) const;
143 142
144 std::vector<std::string> checkIncompatibleXmlFiles(const CompatibilityMatrix& mat, 143 // Return a list of instance names that does NOT conform to
145 bool includeOptional = true) const; 144 // the given compatibility matrix. It does not contain components that are optional.
145 std::vector<std::string> checkIncompatibleHals(const CompatibilityMatrix& mat) const;
146 146
147 void removeHals(const std::string& name, size_t majorVer); 147 void removeHals(const std::string& name, size_t majorVer);
148 148
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index 656b2b8..7e671f0 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -34,11 +34,11 @@ namespace vintf {
34 * + GetDeviceHalManfiest 34 * + GetDeviceHalManfiest
35 * | + getTransport 35 * | + getTransport
36 * | + getSupportedVersions 36 * | + getSupportedVersions
37 * | + checkIncompatibility 37 * | + checkCompatibility
38 * + GetFrameworkHalManifest 38 * + GetFrameworkHalManifest
39 * | + getTransport 39 * | + getTransport
40 * | + getSupportedVersions 40 * | + getSupportedVersions
41 * | + checkIncompatibility 41 * | + checkCompatibility
42 * + GetRuntimeInfo 42 * + GetRuntimeInfo
43 * + checkCompatibility 43 * + checkCompatibility
44 * 44 *
diff --git a/include/vintf/parse_string.h b/include/vintf/parse_string.h
index 07251aa..7ae45f8 100644
--- a/include/vintf/parse_string.h
+++ b/include/vintf/parse_string.h
@@ -103,6 +103,8 @@ std::string dump(const HalManifest &vm);
103 103
104std::string dump(const RuntimeInfo& ki, bool verbose = true); 104std::string dump(const RuntimeInfo& ki, bool verbose = true);
105 105
106std::vector<std::string> expandInstances(const MatrixHal& req);
107
106} // namespace vintf 108} // namespace vintf
107} // namespace android 109} // namespace android
108 110
diff --git a/parse_string.cpp b/parse_string.cpp
index 697a68f..beca23b 100644
--- a/parse_string.cpp
+++ b/parse_string.cpp
@@ -395,6 +395,36 @@ std::ostream &operator<<(std::ostream &os, const MatrixHal &req) {
395 << (req.optional ? kOptional : kRequired); 395 << (req.optional ? kOptional : kRequired);
396} 396}
397 397
398static std::string expandInstances(const MatrixHal& req, const VersionRange& vr) {
399 std::string s;
400 bool first = true;
401 for (const auto& interface : iterateValues(req.interfaces)) {
402 for (const auto& instance : interface.instances) {
403 if (!first) s += " AND ";
404 s += "@" + to_string(vr) + "::" + interface.name + "/" + instance;
405 first = false;
406 }
407 }
408 return s;
409}
410
411std::vector<std::string> expandInstances(const MatrixHal& req) {
412 if (req.versionRanges.empty()) {
413 return {};
414 }
415 if (req.versionRanges.size() == 1 && req.interfaces.size() == 1 &&
416 req.interfaces.begin()->second.instances.size() == 1) {
417 return {expandInstances(req, req.versionRanges.front())};
418 }
419 std::vector<std::string> ss;
420 for (const auto& vr : req.versionRanges) {
421 if (!ss.empty()) {
422 ss.back() += " OR";
423 }
424 ss.push_back("(" + expandInstances(req, vr) + ")");
425 }
426 return ss;
427}
398 428
399std::ostream &operator<<(std::ostream &os, KernelSepolicyVersion ksv){ 429std::ostream &operator<<(std::ostream &os, KernelSepolicyVersion ksv){
400 return os << ksv.value; 430 return os << ksv.value;
diff --git a/test/LibVintfTest.cpp b/test/LibVintfTest.cpp
index 6eedf01..33fd833 100644
--- a/test/LibVintfTest.cpp
+++ b/test/LibVintfTest.cpp
@@ -2776,6 +2776,102 @@ TEST_F(LibVintfTest, MatrixLastError) {
2776 << "lastError() should not be modified"; 2776 << "lastError() should not be modified";
2777} 2777}
2778 2778
2779TEST_F(LibVintfTest, MatrixDetailErrorMsg) {
2780 std::string error;
2781 std::string xml;
2782
2783 HalManifest manifest;
2784 xml =
2785 "<manifest version=\"1.0\" type=\"device\">\n"
2786 " <hal format=\"hidl\">\n"
2787 " <name>android.hardware.foo</name>\n"
2788 " <transport>hwbinder</transport>\n"
2789 " <version>1.0</version>\n"
2790 " <interface>\n"
2791 " <name>IFoo</name>\n"
2792 " <instance>default</instance>\n"
2793 " </interface>\n"
2794 " </hal>\n"
2795 "</manifest>\n";
2796 ASSERT_TRUE(gHalManifestConverter(&manifest, xml, &error)) << error;
2797
2798 {
2799 CompatibilityMatrix cm;
2800 xml =
2801 "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
2802 " <hal format=\"hidl\" optional=\"false\">\n"
2803 " <name>android.hardware.foo</name>\n"
2804 " <version>1.2-3</version>\n"
2805 " <version>4.5</version>\n"
2806 " <interface>\n"
2807 " <name>IFoo</name>\n"
2808 " <instance>default</instance>\n"
2809 " <instance>slot1</instance>\n"
2810 " </interface>\n"
2811 " <interface>\n"
2812 " <name>IBar</name>\n"
2813 " <instance>default</instance>\n"
2814 " </interface>\n"
2815 " </hal>\n"
2816 "</compatibility-matrix>\n";
2817 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml, &error)) << error;
2818 EXPECT_FALSE(manifest.checkCompatibility(cm, &error));
2819 EXPECT_IN(
2820 "android.hardware.foo:\n"
2821 " required: \n"
2822 " (@1.2-3::IBar/default AND @1.2-3::IFoo/default AND @1.2-3::IFoo/slot1) OR\n"
2823 " (@4.5::IBar/default AND @4.5::IFoo/default AND @4.5::IFoo/slot1)\n"
2824 " provided: @1.0::IFoo/default",
2825 error);
2826 }
2827
2828 {
2829 CompatibilityMatrix cm;
2830 xml =
2831 "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
2832 " <hal format=\"hidl\" optional=\"false\">\n"
2833 " <name>android.hardware.foo</name>\n"
2834 " <version>1.2-3</version>\n"
2835 " <interface>\n"
2836 " <name>IFoo</name>\n"
2837 " <instance>default</instance>\n"
2838 " <instance>slot1</instance>\n"
2839 " </interface>\n"
2840 " </hal>\n"
2841 "</compatibility-matrix>\n";
2842 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml, &error)) << error;
2843 EXPECT_FALSE(manifest.checkCompatibility(cm, &error));
2844 EXPECT_IN(
2845 "android.hardware.foo:\n"
2846 " required: (@1.2-3::IFoo/default AND @1.2-3::IFoo/slot1)\n"
2847 " provided: @1.0::IFoo/default",
2848 error);
2849 }
2850
2851 // the most frequent use case.
2852 {
2853 CompatibilityMatrix cm;
2854 xml =
2855 "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
2856 " <hal format=\"hidl\" optional=\"false\">\n"
2857 " <name>android.hardware.foo</name>\n"
2858 " <version>1.2-3</version>\n"
2859 " <interface>\n"
2860 " <name>IFoo</name>\n"
2861 " <instance>default</instance>\n"
2862 " </interface>\n"
2863 " </hal>\n"
2864 "</compatibility-matrix>\n";
2865 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml, &error)) << error;
2866 EXPECT_FALSE(manifest.checkCompatibility(cm, &error));
2867 EXPECT_IN(
2868 "android.hardware.foo:\n"
2869 " required: @1.2-3::IFoo/default\n"
2870 " provided: @1.0::IFoo/default",
2871 error);
2872 }
2873}
2874
2779} // namespace vintf 2875} // namespace vintf
2780} // namespace android 2876} // namespace android
2781 2877
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 659bd2b..3d834eb 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -38,6 +38,11 @@ using namespace ::android::vintf::details;
38 38
39using android::FQName; 39using android::FQName;
40 40
41static bool In(const std::string& sub, const std::string& str) {
42 return str.find(sub) != std::string::npos;
43}
44#define EXPECT_IN(sub, str) EXPECT_TRUE(In((sub), (str))) << (str);
45
41// 46//
42// Set of Xml1 metadata compatible with each other. 47// Set of Xml1 metadata compatible with each other.
43// 48//
@@ -443,9 +448,11 @@ TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceFail) {
443 int result = VintfObject::CheckCompatibility(packageInfo, &error); 448 int result = VintfObject::CheckCompatibility(packageInfo, &error);
444 449
445 ASSERT_EQ(result, 1) << "Should have failed:" << error.c_str(); 450 ASSERT_EQ(result, 1) << "Should have failed:" << error.c_str();
446 ASSERT_STREQ(error.c_str(), 451 EXPECT_IN(
447 "Device manifest and framework compatibility matrix are incompatible: HALs " 452 "Device manifest and framework compatibility matrix are incompatible: HALs "
448 "incompatible. android.hardware.foo"); 453 "incompatible.",
454 error);
455 EXPECT_IN("android.hardware.foo", error);
449} 456}
450 457
451// Tests that complementary info is checked against itself. 458// Tests that complementary info is checked against itself.