summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.bp14
-rw-r--r--Android.mk4
-rw-r--r--CompatibilityMatrix.cpp23
-rw-r--r--HalManifest.cpp30
-rw-r--r--ManifestHal.cpp31
-rw-r--r--ManifestInstance.cpp54
-rw-r--r--MatrixHal.cpp19
-rw-r--r--MatrixInstance.cpp52
-rw-r--r--VintfObject.cpp34
-rw-r--r--include/vintf/CompatibilityMatrix.h7
-rw-r--r--include/vintf/HalGroup.h78
-rw-r--r--include/vintf/HalManifest.h10
-rw-r--r--include/vintf/ManifestHal.h8
-rw-r--r--include/vintf/ManifestInstance.h50
-rw-r--r--include/vintf/MatrixHal.h4
-rw-r--r--include/vintf/MatrixInstance.h50
-rw-r--r--include/vintf/Version.h2
-rw-r--r--main.cpp31
-rw-r--r--test/Android.bp3
-rw-r--r--test/LibVintfTest.cpp42
20 files changed, 411 insertions, 135 deletions
diff --git a/Android.bp b/Android.bp
index 1c7a420..03267a5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -38,7 +38,9 @@ cc_library_static {
38 "KernelConfigParser.cpp", 38 "KernelConfigParser.cpp",
39 "RuntimeInfo.cpp", 39 "RuntimeInfo.cpp",
40 "ManifestHal.cpp", 40 "ManifestHal.cpp",
41 "ManifestInstance.cpp",
41 "MatrixHal.cpp", 42 "MatrixHal.cpp",
43 "MatrixInstance.cpp",
42 "MatrixKernel.cpp", 44 "MatrixKernel.cpp",
43 "SystemSdk.cpp", 45 "SystemSdk.cpp",
44 "TransportArch.cpp", 46 "TransportArch.cpp",
@@ -48,6 +50,7 @@ cc_library_static {
48 ], 50 ],
49 shared_libs: [ 51 shared_libs: [
50 "libbase", 52 "libbase",
53 "libhidl-gen-utils",
51 "liblog", 54 "liblog",
52 "libselinux", 55 "libselinux",
53 "libtinyxml2", 56 "libtinyxml2",
@@ -56,6 +59,10 @@ cc_library_static {
56 export_include_dirs: ["include", "."], 59 export_include_dirs: ["include", "."],
57 local_include_dirs: ["include/vintf"], 60 local_include_dirs: ["include/vintf"],
58 61
62 export_shared_lib_headers: [
63 "libhidl-gen-utils",
64 ],
65
59 target: { 66 target: {
60 host: { 67 host: {
61 srcs: [ 68 srcs: [
@@ -78,6 +85,7 @@ cc_library {
78 defaults: ["libvintf-defaults"], 85 defaults: ["libvintf-defaults"],
79 shared_libs: [ 86 shared_libs: [
80 "libbase", 87 "libbase",
88 "libhidl-gen-utils",
81 "liblog", 89 "liblog",
82 "libselinux", 90 "libselinux",
83 "libtinyxml2", 91 "libtinyxml2",
@@ -90,6 +98,10 @@ cc_library {
90 "utils.cpp", 98 "utils.cpp",
91 ], 99 ],
92 100
101 export_shared_lib_headers: [
102 "libhidl-gen-utils",
103 ],
104
93 whole_static_libs: ["libvintf_common"], 105 whole_static_libs: ["libvintf_common"],
94} 106}
95 107
@@ -98,6 +110,7 @@ cc_binary {
98 defaults: ["libvintf-defaults"], 110 defaults: ["libvintf-defaults"],
99 shared_libs: [ 111 shared_libs: [
100 "libbase", 112 "libbase",
113 "libhidl-gen-utils",
101 "libvintf", 114 "libvintf",
102 ], 115 ],
103 srcs: [ 116 srcs: [
@@ -109,6 +122,7 @@ cc_binary_host {
109 name: "checkvintf", 122 name: "checkvintf",
110 defaults: ["libvintf-defaults"], 123 defaults: ["libvintf-defaults"],
111 static_libs: [ 124 static_libs: [
125 "libhidl-gen-utils",
112 "libvintf_common", 126 "libvintf_common",
113 "libutils", 127 "libutils",
114 "libtinyxml2", 128 "libtinyxml2",
diff --git a/Android.mk b/Android.mk
index b7b2ec0..efe2bea 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,5 +23,9 @@ LOCAL_CFLAGS := -Wall -Werror
23LOCAL_STATIC_LIBRARIES := \ 23LOCAL_STATIC_LIBRARIES := \
24 libbase \ 24 libbase \
25 libvintf \ 25 libvintf \
26 libhidl-gen-utils \
26 libfs_mgr 27 libfs_mgr
28
29LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := libhidl-gen-utils
30
27include $(BUILD_STATIC_LIBRARY) 31include $(BUILD_STATIC_LIBRARY)
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index deb1fa1..bf83a98 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -312,20 +312,19 @@ CompatibilityMatrix* CompatibilityMatrix::combine(Level deviceLevel,
312 return matrix; 312 return matrix;
313} 313}
314 314
315void CompatibilityMatrix::forEachInstance( 315bool CompatibilityMatrix::forEachInstanceOfVersion(
316 const std::function<void(const std::string&, const VersionRange&, const std::string&, 316 const std::string& package, const Version& expectVersion,
317 const std::string&, bool, bool*)>& f) const { 317 const std::function<bool(const MatrixInstance&)>& func) const {
318 bool stop = false; 318 for (const MatrixHal* hal : getHals(package)) {
319 for (const auto& hal : getHals()) { 319 bool cont = hal->forEachInstance([&](const MatrixInstance& matrixInstance) {
320 for (const auto& v : hal.versionRanges) { 320 if (matrixInstance.versionRange().contains(expectVersion)) {
321 for (const auto& intf : iterateValues(hal.interfaces)) { 321 return func(matrixInstance);
322 for (const auto& instance : intf.instances) {
323 f(hal.name, v, intf.name, instance, hal.optional, &stop);
324 if (stop) break;
325 }
326 } 322 }
327 } 323 return true;
324 });
325 if (!cont) return false;
328 } 326 }
327 return true;
329} 328}
330 329
331} // namespace vintf 330} // namespace vintf
diff --git a/HalManifest.cpp b/HalManifest.cpp
index 6f05cab..454e0fc 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -184,20 +184,19 @@ bool HalManifest::hasInstance(const std::string& halName, const Version& version
184 return instances.find(instanceName) != instances.end(); 184 return instances.find(instanceName) != instances.end();
185} 185}
186 186
187void HalManifest::forEachInstance( 187bool HalManifest::forEachInstanceOfVersion(
188 const std::function<void(const std::string&, const Version&, const std::string&, 188 const std::string& package, const Version& expectVersion,
189 const std::string&, bool*)>& f) const { 189 const std::function<bool(const ManifestInstance&)>& func) const {
190 bool stop = false; 190 for (const ManifestHal* hal : getHals(package)) {
191 for (const auto& hal : getHals()) { 191 bool cont = hal->forEachInstance([&](const ManifestInstance& manifestInstance) {
192 for (const auto& v : hal.versions) { 192 if (manifestInstance.version().minorAtLeast(expectVersion)) {
193 for (const auto& intf : iterateValues(hal.interfaces)) { 193 return func(manifestInstance);
194 for (const auto& instance : intf.instances) {
195 f(hal.name, v, intf.name, instance, &stop);
196 if (stop) break;
197 }
198 } 194 }
199 } 195 return true;
196 });
197 if (!cont) return false;
200 } 198 }
199 return true;
201} 200}
202 201
203static bool satisfyVersion(const MatrixHal& matrixHal, const Version& manifestHalVersion) { 202static bool satisfyVersion(const MatrixHal& matrixHal, const Version& manifestHalVersion) {
@@ -381,7 +380,12 @@ bool HalManifest::checkCompatibility(const CompatibilityMatrix &mat, std::string
381 auto incompatibleHals = checkIncompatibleHals(mat); 380 auto incompatibleHals = checkIncompatibleHals(mat);
382 if (!incompatibleHals.empty()) { 381 if (!incompatibleHals.empty()) {
383 if (error != nullptr) { 382 if (error != nullptr) {
384 *error = "HALs incompatible. The following requirements are not met:\n"; 383 *error = "HALs incompatible.";
384 if (mat.level() != Level::UNSPECIFIED)
385 *error += " Matrix level = " + to_string(mat.level()) + ".";
386 if (level() != Level::UNSPECIFIED)
387 *error += " Manifest level = " + to_string(level()) + ".";
388 *error += " The following requirements are not met:\n";
385 for (const auto& e : incompatibleHals) { 389 for (const auto& e : incompatibleHals) {
386 *error += e + "\n"; 390 *error += e + "\n";
387 } 391 }
diff --git a/ManifestHal.cpp b/ManifestHal.cpp
index 00d0d95..d04d3e0 100644
--- a/ManifestHal.cpp
+++ b/ManifestHal.cpp
@@ -17,6 +17,8 @@
17#include "ManifestHal.h" 17#include "ManifestHal.h"
18#include <unordered_set> 18#include <unordered_set>
19 19
20#include "MapValueIterator.h"
21
20namespace android { 22namespace android {
21namespace vintf { 23namespace vintf {
22 24
@@ -42,20 +44,23 @@ bool ManifestHal::operator==(const ManifestHal &other) const {
42 return true; 44 return true;
43} 45}
44 46
45bool ManifestHal::containsVersion(const Version& version) const { 47bool ManifestHal::forEachInstance(const std::function<bool(const ManifestInstance&)>& func) const {
46 for (Version v : versions) { 48 // TODO(b/73556059): support <fqname> as well.
47 if (v.minorAtLeast(version)) return true; 49 for (const auto& v : versions) {
48 } 50 for (const auto& intf : iterateValues(interfaces)) {
49 return false; 51 for (const auto& instance : intf.instances) {
50} 52 // TODO(b/73556059): Store ManifestInstance as well to avoid creating temps
51 53 FqInstance fqInstance;
52std::set<std::string> ManifestHal::getInstances(const std::string& interfaceName) const { 54 if (fqInstance.setTo(getName(), v.majorVer, v.minorVer, intf.name, instance)) {
53 std::set<std::string> ret; 55 if (!func(ManifestInstance(std::move(fqInstance),
54 auto it = interfaces.find(interfaceName); 56 TransportArch{transportArch}))) {
55 if (it != interfaces.end()) { 57 return false;
56 ret.insert(it->second.instances.begin(), it->second.instances.end()); 58 }
59 }
60 }
61 }
57 } 62 }
58 return ret; 63 return true;
59} 64}
60 65
61} // namespace vintf 66} // namespace vintf
diff --git a/ManifestInstance.cpp b/ManifestInstance.cpp
new file mode 100644
index 0000000..66e0cd3
--- /dev/null
+++ b/ManifestInstance.cpp
@@ -0,0 +1,54 @@
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 "ManifestInstance.h"
18
19#include <utility>
20
21namespace android {
22namespace vintf {
23
24ManifestInstance::ManifestInstance(FqInstance&& fqInstance, TransportArch&& ta)
25 : mFqInstance(std::move(fqInstance)), mTransportArch(std::move(ta)) {}
26ManifestInstance::ManifestInstance(const FqInstance& fqInstance, const TransportArch& ta)
27 : mFqInstance(fqInstance), mTransportArch(ta) {}
28
29const std::string& ManifestInstance::package() const {
30 return mFqInstance.getPackage();
31}
32
33Version ManifestInstance::version() const {
34 return mFqInstance.getVersion();
35}
36
37const std::string& ManifestInstance::interface() const {
38 return mFqInstance.getInterface();
39}
40
41const std::string& ManifestInstance::instance() const {
42 return mFqInstance.getInstance();
43}
44
45Transport ManifestInstance::transport() const {
46 return mTransportArch.transport;
47}
48
49Arch ManifestInstance::arch() const {
50 return mTransportArch.arch;
51}
52
53} // namespace vintf
54} // namespace android
diff --git a/MatrixHal.cpp b/MatrixHal.cpp
index 96dcf78..fbe9a5f 100644
--- a/MatrixHal.cpp
+++ b/MatrixHal.cpp
@@ -16,6 +16,8 @@
16 16
17#include "MatrixHal.h" 17#include "MatrixHal.h"
18 18
19#include "MapValueIterator.h"
20
19namespace android { 21namespace android {
20namespace vintf { 22namespace vintf {
21 23
@@ -66,5 +68,22 @@ bool MatrixHal::containsInstances(const MatrixHal& other) const {
66 return true; 68 return true;
67} 69}
68 70
71bool MatrixHal::forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const {
72 for (const auto& vr : versionRanges) {
73 for (const auto& intf : iterateValues(interfaces)) {
74 for (const auto& instance : intf.instances) {
75 // TODO(b/73556059): Store MatrixInstance as well to avoid creating temps
76 FqInstance fqInstance;
77 if (fqInstance.setTo(getName(), vr.majorVer, vr.minMinor, intf.name, instance)) {
78 if (!func(MatrixInstance(std::move(fqInstance), VersionRange(vr), optional))) {
79 return false;
80 }
81 }
82 }
83 }
84 }
85 return true;
86}
87
69} // namespace vintf 88} // namespace vintf
70} // namespace android 89} // namespace android
diff --git a/MatrixInstance.cpp b/MatrixInstance.cpp
new file mode 100644
index 0000000..46c92e0
--- /dev/null
+++ b/MatrixInstance.cpp
@@ -0,0 +1,52 @@
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 "MatrixInstance.h"
18
19#include <utility>
20
21namespace android {
22namespace vintf {
23
24MatrixInstance::MatrixInstance(FqInstance&& fqInstance, VersionRange&& range, bool optional)
25 : mFqInstance(std::move(fqInstance)), mRange(std::move(range)), mOptional(optional) {}
26
27MatrixInstance::MatrixInstance(const FqInstance fqInstance, const VersionRange& range,
28 bool optional)
29 : mFqInstance(fqInstance), mRange(range), mOptional(optional) {}
30
31const std::string& MatrixInstance::package() const {
32 return mFqInstance.getPackage();
33}
34
35const VersionRange& MatrixInstance::versionRange() const {
36 return mRange;
37}
38
39const std::string& MatrixInstance::interface() const {
40 return mFqInstance.getInterface();
41}
42
43const std::string& MatrixInstance::instance() const {
44 return mFqInstance.getInstance();
45}
46
47bool MatrixInstance::optional() const {
48 return mOptional;
49}
50
51} // namespace vintf
52} // namespace android
diff --git a/VintfObject.cpp b/VintfObject.cpp
index c10949c..5c329fa 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -613,7 +613,7 @@ bool VintfObject::isInstanceDeprecated(const std::string& package, Version versi
613 if (targetMatrixHal == nullptr || targetMatrixRange == nullptr) { 613 if (targetMatrixHal == nullptr || targetMatrixRange == nullptr) {
614 if (error) { 614 if (error) {
615 *error = toFQNameString(package, servedVersion) + 615 *error = toFQNameString(package, servedVersion) +
616 "is deprecated in compatibility matrix at FCM Version " + 616 " is deprecated in compatibility matrix at FCM Version " +
617 to_string(targetMatrix.level()) + "; it should not be served."; 617 to_string(targetMatrix.level()) + "; it should not be served.";
618 } 618 }
619 return true; 619 return true;
@@ -691,25 +691,23 @@ int32_t VintfObject::CheckDeprecation(const IsInstanceInUse& isInstanceInUse,
691} 691}
692 692
693int32_t VintfObject::CheckDeprecation(std::string* error) { 693int32_t VintfObject::CheckDeprecation(std::string* error) {
694 using namespace std::placeholders;
694 auto deviceManifest = GetDeviceHalManifest(); 695 auto deviceManifest = GetDeviceHalManifest();
695 IsInstanceInUse inManifest = [&deviceManifest](const std::string& package, Version version, 696 IsInstanceInUse inManifest = [&deviceManifest](const std::string& package, Version version,
696 const std::string& interface, 697 const std::string& interface,
697 const std::string& instance) { 698 const std::string& instance) {
698 const ManifestHal* hal = deviceManifest->getHal(package, version); 699 std::pair<bool, Version> ret(false, Version{});
699 if (hal == nullptr) { 700 deviceManifest->forEachInstanceOfInterface(
700 return std::make_pair(false, Version{}); 701 package, version, interface,
701 } 702 [&instance, &ret](const ManifestInstance& manifestInstance) {
702 const auto& instances = hal->getInstances(interface); 703 if (manifestInstance.instance() == instance) {
703 if (instances.find(instance) == instances.end()) { 704 ret.first = true;
704 return std::make_pair(false, Version{}); 705 ret.second = manifestInstance.version();
705 } 706 return false;
706 707 }
707 for (Version v : hal->versions) { 708 return true;
708 if (v.minorAtLeast(version)) { 709 });
709 return std::make_pair(true, v); 710 return ret;
710 }
711 }
712 return std::make_pair(false, Version{});
713 }; 711 };
714 return CheckDeprecation(inManifest, error); 712 return CheckDeprecation(inManifest, error);
715} 713}
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 9fcaffc..e31917f 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -26,6 +26,7 @@
26#include "Level.h" 26#include "Level.h"
27#include "MapValueIterator.h" 27#include "MapValueIterator.h"
28#include "MatrixHal.h" 28#include "MatrixHal.h"
29#include "MatrixInstance.h"
29#include "MatrixKernel.h" 30#include "MatrixKernel.h"
30#include "Named.h" 31#include "Named.h"
31#include "SchemaType.h" 32#include "SchemaType.h"
@@ -58,9 +59,9 @@ struct CompatibilityMatrix : public HalGroup<MatrixHal>, public XmlFileGroup<Mat
58 // (Normally, version ranges do not overlap, and the only match is returned.) 59 // (Normally, version ranges do not overlap, and the only match is returned.)
59 std::string getXmlSchemaPath(const std::string& xmlFileName, const Version& version) const; 60 std::string getXmlSchemaPath(const std::string& xmlFileName, const Version& version) const;
60 61
61 void forEachInstance( 62 bool forEachInstanceOfVersion(
62 const std::function<void(const std::string&, const VersionRange&, const std::string&, 63 const std::string& package, const Version& expectVersion,
63 const std::string&, bool, bool*)>& f) const; 64 const std::function<bool(const MatrixInstance&)>& func) const override;
64 65
65 private: 66 private:
66 bool add(MatrixHal &&hal); 67 bool add(MatrixHal &&hal);
diff --git a/include/vintf/HalGroup.h b/include/vintf/HalGroup.h
index 10c1eae..bb84423 100644
--- a/include/vintf/HalGroup.h
+++ b/include/vintf/HalGroup.h
@@ -20,6 +20,8 @@
20#include <map> 20#include <map>
21#include <set> 21#include <set>
22 22
23#include <hidl-util/FqInstance.h>
24
23#include "MapValueIterator.h" 25#include "MapValueIterator.h"
24#include "Version.h" 26#include "Version.h"
25 27
@@ -30,6 +32,8 @@ namespace vintf {
30// Hal.getName() must return a string indicating the name. 32// Hal.getName() must return a string indicating the name.
31template <typename Hal> 33template <typename Hal>
32struct HalGroup { 34struct HalGroup {
35 using InstanceType = typename Hal::InstanceType;
36
33 public: 37 public:
34 virtual ~HalGroup() {} 38 virtual ~HalGroup() {}
35 // Move all hals from another HalGroup to this. 39 // Move all hals from another HalGroup to this.
@@ -57,6 +61,7 @@ struct HalGroup {
57 61
58 // Get all hals with the given name (e.g "android.hardware.camera"). 62 // Get all hals with the given name (e.g "android.hardware.camera").
59 // There could be multiple hals that matches the same given name. 63 // There could be multiple hals that matches the same given name.
64 // TODO(b/74247301) Deprecated; use forEachInstance instead.
60 std::vector<const Hal*> getHals(const std::string& name) const { 65 std::vector<const Hal*> getHals(const std::string& name) const {
61 std::vector<const Hal*> ret; 66 std::vector<const Hal*> ret;
62 auto range = mHals.equal_range(name); 67 auto range = mHals.equal_range(name);
@@ -69,6 +74,7 @@ struct HalGroup {
69 // Get all hals with the given name (e.g "android.hardware.camera"). 74 // Get all hals with the given name (e.g "android.hardware.camera").
70 // There could be multiple hals that matches the same given name. 75 // There could be multiple hals that matches the same given name.
71 // Non-const version of the above getHals() method. 76 // Non-const version of the above getHals() method.
77 // TODO(b/74247301) Deprecated; use forEachInstance instead.
72 std::vector<Hal*> getHals(const std::string& name) { 78 std::vector<Hal*> getHals(const std::string& name) {
73 std::vector<Hal*> ret; 79 std::vector<Hal*> ret;
74 auto range = mHals.equal_range(name); 80 auto range = mHals.equal_range(name);
@@ -78,29 +84,65 @@ struct HalGroup {
78 return ret; 84 return ret;
79 } 85 }
80 86
81 // Get the hal that matches the given name and version (e.g. 87 // Apply func to all instances.
82 // "android.hardware.camera@2.4") 88 bool forEachInstance(const std::function<bool(const InstanceType&)>& func) const {
83 // There should be a single hal that matches the given name and version. 89 for (const auto& hal : getHals()) {
84 const Hal* getHal(const std::string& name, const Version& version) const { 90 bool cont = hal.forEachInstance(func);
85 for (const Hal* hal : getHals(name)) { 91 if (!cont) return false;
86 if (hal->containsVersion(version)) return hal; 92 }
93 return true;
94 }
95
96 // Apply func to all instances of package@expectVersion::*/*.
97 // For example, if a.h.foo@1.1::IFoo/default is in "this" and getFqInstances
98 // is called with a.h.foo@1.0, then a.h.foo@1.1::IFoo/default is returned.
99 virtual bool forEachInstanceOfVersion(
100 const std::string& package, const Version& expectVersion,
101 const std::function<bool(const InstanceType&)>& func) const = 0;
102
103 // Apply func to instances of package@expectVersion::interface/*.
104 // For example, if a.h.foo@1.1::IFoo/default is in "this" and getFqInstances
105 // is called with a.h.foo@1.0::IFoo, then a.h.foo@1.1::IFoo/default is returned.
106 bool forEachInstanceOfInterface(const std::string& package, const Version& expectVersion,
107 const std::string& interface,
108 const std::function<bool(const InstanceType&)>& func) const {
109 return forEachInstanceOfVersion(package, expectVersion,
110 [&func, &interface](const InstanceType& e) {
111 if (e.interface() == interface) {
112 return func(e);
113 }
114 return true;
115 });
116 }
117
118 // Alternative to forEachInstanceOfInterface if you need a vector instead.
119 // If interface is empty, returns all instances of package@version;
120 // else return all instances of package@version::interface.
121 std::vector<InstanceType> getFqInstances(const std::string& package,
122 const Version& expectVersion,
123 const std::string& interface = "") const {
124 std::vector<InstanceType> v;
125 auto mapToVector = [&v](const auto& e) {
126 v.push_back(e);
127 return true;
128 };
129 if (interface.empty()) {
130 (void)forEachInstanceOfVersion(package, expectVersion, mapToVector);
131 } else {
132 (void)forEachInstanceOfInterface(package, expectVersion, interface, mapToVector);
87 } 133 }
88 return nullptr; 134 return v;
89 } 135 }
90 136
91 // Get all instance names for hal that matches the given component name, version 137 // Alternative to forEachInstance if you just need a set of instance names instead.
92 // and interface name (e.g. "android.hardware.camera@2.4::ICameraProvider").
93 // * If the component ("android.hardware.camera@2.4") does not exist, return empty set.
94 // * If the component ("android.hardware.camera@2.4") does exist,
95 // * If the interface (ICameraProvider) does not exist, return empty set.
96 // * Else return the list hal.interface.instance.
97 std::set<std::string> getInstances(const std::string& halName, const Version& version, 138 std::set<std::string> getInstances(const std::string& halName, const Version& version,
98 const std::string& interfaceName) const { 139 const std::string& interfaceName) const {
99 const Hal* hal = getHal(halName, version); 140 std::set<std::string> ret;
100 if (hal == nullptr) { 141 (void)forEachInstanceOfInterface(halName, version, interfaceName, [&ret](const auto& e) {
101 return {}; 142 ret.insert(e.instance());
102 } 143 return true;
103 return hal->getInstances(interfaceName); 144 });
145 return ret;
104 } 146 }
105 147
106 protected: 148 protected:
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index e497d42..71f7017 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -18,14 +18,16 @@
18#ifndef ANDROID_VINTF_HAL_MANIFEST_H 18#ifndef ANDROID_VINTF_HAL_MANIFEST_H
19#define ANDROID_VINTF_HAL_MANIFEST_H 19#define ANDROID_VINTF_HAL_MANIFEST_H
20 20
21#include <hidl-util/FqInstance.h>
22#include <utils/Errors.h>
21#include <map> 23#include <map>
22#include <string> 24#include <string>
23#include <utils/Errors.h>
24#include <vector> 25#include <vector>
25 26
26#include "HalGroup.h" 27#include "HalGroup.h"
27#include "Level.h" 28#include "Level.h"
28#include "ManifestHal.h" 29#include "ManifestHal.h"
30#include "ManifestInstance.h"
29#include "MapValueIterator.h" 31#include "MapValueIterator.h"
30#include "SchemaType.h" 32#include "SchemaType.h"
31#include "SystemSdk.h" 33#include "SystemSdk.h"
@@ -117,9 +119,9 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX
117 // Get metaversion of this manifest. 119 // Get metaversion of this manifest.
118 Version getMetaVersion() const; 120 Version getMetaVersion() const;
119 121
120 void forEachInstance( 122 bool forEachInstanceOfVersion(
121 const std::function<void(const std::string&, const Version&, const std::string&, 123 const std::string& package, const Version& expectVersion,
122 const std::string&, bool*)>& f) const; 124 const std::function<bool(const ManifestInstance&)>& func) const override;
123 125
124 protected: 126 protected:
125 // Check before add() 127 // Check before add()
diff --git a/include/vintf/ManifestHal.h b/include/vintf/ManifestHal.h
index 09c6693..a35c49a 100644
--- a/include/vintf/ManifestHal.h
+++ b/include/vintf/ManifestHal.h
@@ -25,6 +25,7 @@
25 25
26#include "HalFormat.h" 26#include "HalFormat.h"
27#include "HalInterface.h" 27#include "HalInterface.h"
28#include "ManifestInstance.h"
28#include "TransportArch.h" 29#include "TransportArch.h"
29#include "Version.h" 30#include "Version.h"
30 31
@@ -33,14 +34,13 @@ namespace vintf {
33 34
34// A component of HalManifest. 35// A component of HalManifest.
35struct ManifestHal { 36struct ManifestHal {
37 using InstanceType = ManifestInstance;
36 38
37 bool operator==(const ManifestHal &other) const; 39 bool operator==(const ManifestHal &other) const;
38 // Check whether the ManifestHal contains the given version. 40 // Check whether the ManifestHal contains the given version.
39 // E.g. if hal has version "1.0" and "2.1", it contains version 41 // E.g. if hal has version "1.0" and "2.1", it contains version
40 // "1.0", "2.0", "2.1". 42 // "1.0", "2.0", "2.1".
41 bool containsVersion(const Version& version) const; 43 bool containsVersion(const Version& version) const;
42 // Get all instances of the ManifestHal with given interface name.
43 std::set<std::string> getInstances(const std::string& interfaceName) const;
44 44
45 HalFormat format = HalFormat::HIDL; 45 HalFormat format = HalFormat::HIDL;
46 std::string name; 46 std::string name;
@@ -52,14 +52,12 @@ struct ManifestHal {
52 inline bool hasInterface(const std::string& interface_name) const { 52 inline bool hasInterface(const std::string& interface_name) const {
53 return interfaces.find(interface_name) != interfaces.end(); 53 return interfaces.find(interface_name) != interfaces.end();
54 } 54 }
55 inline bool hasVersion(Version v) const {
56 return std::find(versions.begin(), versions.end(), v) != versions.end();
57 }
58 inline Transport transport() const { 55 inline Transport transport() const {
59 return transportArch.transport; 56 return transportArch.transport;
60 } 57 }
61 58
62 inline const std::string& getName() const { return name; } 59 inline const std::string& getName() const { return name; }
60 bool forEachInstance(const std::function<bool(const ManifestInstance&)>& func) const;
63 61
64 private: 62 private:
65 friend struct LibVintfTest; 63 friend struct LibVintfTest;
diff --git a/include/vintf/ManifestInstance.h b/include/vintf/ManifestInstance.h
new file mode 100644
index 0000000..a2a89ef
--- /dev/null
+++ b/include/vintf/ManifestInstance.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_MANIFEST_INSTANCE_H
18#define ANDROID_VINTF_MANIFEST_INSTANCE_H
19
20#include <string>
21
22#include <hidl-util/FqInstance.h>
23
24#include "TransportArch.h"
25#include "Version.h"
26
27namespace android {
28namespace vintf {
29
30class ManifestInstance {
31 public:
32 using VersionType = Version;
33 ManifestInstance(FqInstance&& fqInstance, TransportArch&& ta);
34 ManifestInstance(const FqInstance& fqInstance, const TransportArch& ta);
35 const std::string& package() const;
36 Version version() const;
37 const std::string& interface() const;
38 const std::string& instance() const;
39 Transport transport() const;
40 Arch arch() const;
41
42 private:
43 FqInstance mFqInstance;
44 TransportArch mTransportArch;
45};
46
47} // namespace vintf
48} // namespace android
49
50#endif // ANDROID_VINTF_MANIFEST_INSTANCE_H
diff --git a/include/vintf/MatrixHal.h b/include/vintf/MatrixHal.h
index 47094fb..29c44c7 100644
--- a/include/vintf/MatrixHal.h
+++ b/include/vintf/MatrixHal.h
@@ -24,6 +24,7 @@
24 24
25#include "HalFormat.h" 25#include "HalFormat.h"
26#include "HalInterface.h" 26#include "HalInterface.h"
27#include "MatrixInstance.h"
27#include "VersionRange.h" 28#include "VersionRange.h"
28 29
29namespace android { 30namespace android {
@@ -31,6 +32,7 @@ namespace vintf {
31 32
32// A HAL entry to a compatibility matrix 33// A HAL entry to a compatibility matrix
33struct MatrixHal { 34struct MatrixHal {
35 using InstanceType = MatrixInstance;
34 36
35 bool operator==(const MatrixHal &other) const; 37 bool operator==(const MatrixHal &other) const;
36 // Check whether the MatrixHal contains the given version. 38 // Check whether the MatrixHal contains the given version.
@@ -51,6 +53,8 @@ struct MatrixHal {
51 53
52 // Return true if "this" contains all interface/instance instances in "other". 54 // Return true if "this" contains all interface/instance instances in "other".
53 bool containsInstances(const MatrixHal& other) const; 55 bool containsInstances(const MatrixHal& other) const;
56
57 bool forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const;
54}; 58};
55 59
56} // namespace vintf 60} // namespace vintf
diff --git a/include/vintf/MatrixInstance.h b/include/vintf/MatrixInstance.h
new file mode 100644
index 0000000..bbd57dc
--- /dev/null
+++ b/include/vintf/MatrixInstance.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_MATRIX_INSTANCE_H
18#define ANDROID_VINTF_MATRIX_INSTANCE_H
19
20#include <string>
21
22#include <hidl-util/FqInstance.h>
23
24#include "VersionRange.h"
25
26namespace android {
27namespace vintf {
28
29class MatrixInstance {
30 public:
31 using VersionType = VersionRange;
32 // fqInstance.version is ignored. Version range is provided separately.
33 MatrixInstance(FqInstance&& fqInstance, VersionRange&& range, bool optional);
34 MatrixInstance(const FqInstance fqInstance, const VersionRange& range, bool optional);
35 const std::string& package() const;
36 const VersionRange& versionRange() const;
37 const std::string& interface() const;
38 const std::string& instance() const;
39 bool optional() const;
40
41 private:
42 FqInstance mFqInstance;
43 VersionRange mRange;
44 bool mOptional;
45};
46
47} // namespace vintf
48} // namespace android
49
50#endif // ANDROID_VINTF_MATRIX_INSTANCE_H
diff --git a/include/vintf/Version.h b/include/vintf/Version.h
index 5fab0fa..4531f2e 100644
--- a/include/vintf/Version.h
+++ b/include/vintf/Version.h
@@ -29,6 +29,8 @@ struct Version {
29 29
30 constexpr Version() : Version(0u, 0u) {} 30 constexpr Version() : Version(0u, 0u) {}
31 constexpr Version(size_t mj, size_t mi) : majorVer(mj), minorVer(mi) {} 31 constexpr Version(size_t mj, size_t mi) : majorVer(mj), minorVer(mi) {}
32 constexpr Version(const std::pair<size_t, size_t>& pair)
33 : majorVer(pair.first), minorVer(pair.second) {}
32 34
33 size_t majorVer; 35 size_t majorVer;
34 size_t minorVer; 36 size_t minorVer;
diff --git a/main.cpp b/main.cpp
index c4119c9..1c3dfef 100644
--- a/main.cpp
+++ b/main.cpp
@@ -188,34 +188,33 @@ using Table = std::map<std::string, TableRow>;
188// if it does not exist and setting the corresponding indicator (as specified by "mutate"). 188// if it does not exist and setting the corresponding indicator (as specified by "mutate").
189void insert(const HalManifest* manifest, Table* table, const RowMutator& mutate) { 189void insert(const HalManifest* manifest, Table* table, const RowMutator& mutate) {
190 if (manifest == nullptr) return; 190 if (manifest == nullptr) return;
191 manifest->forEachInstance([&](const auto& package, const auto& version, const auto& interface, 191 manifest->forEachInstance([&](const auto& manifestInstance) {
192 const auto& instance, bool* /* stop */) { 192 std::string key = toFQNameString(manifestInstance.package(), manifestInstance.version(),
193 std::string key = toFQNameString(package, VersionRange{version.majorVer, version.minorVer}, 193 manifestInstance.interface(), manifestInstance.instance());
194 interface, instance);
195 mutate(&(*table)[key]); 194 mutate(&(*table)[key]);
195 return true;
196 }); 196 });
197} 197}
198 198
199void insert(const CompatibilityMatrix* matrix, Table* table, const RowMutator& mutate) { 199void insert(const CompatibilityMatrix* matrix, Table* table, const RowMutator& mutate) {
200 if (matrix == nullptr) return; 200 if (matrix == nullptr) return;
201 matrix->forEachInstance([&](const auto& package, const auto& range, const auto& interface, 201 matrix->forEachInstance([&](const auto& matrixInstance) {
202 const auto& instance, bool optional, bool* /* stop */) { 202 for (auto minorVer = matrixInstance.versionRange().minMinor;
203 bool missed = false; 203 minorVer <= matrixInstance.versionRange().maxMinor; ++minorVer) {
204 for (auto minorVer = range.minMinor; minorVer <= range.maxMinor; ++minorVer) { 204 std::string key = toFQNameString(
205 std::string key = toFQNameString(package, VersionRange{range.majorVer, minorVer}, 205 matrixInstance.package(), Version{matrixInstance.versionRange().majorVer, minorVer},
206 interface, instance); 206 matrixInstance.interface(), matrixInstance.instance());
207 auto it = table->find(key); 207 auto it = table->find(key);
208 if (it == table->end()) { 208 if (it == table->end()) {
209 missed = true; 209 mutate(&(*table)[key]);
210 } else { 210 } else {
211 mutate(&it->second); 211 mutate(&it->second);
212 it->second.required = !optional; 212 if (minorVer == matrixInstance.versionRange().minMinor) {
213 it->second.required = !matrixInstance.optional();
214 }
213 } 215 }
214 } 216 }
215 if (missed) { 217 return true;
216 std::string key = toFQNameString(package, range, interface, instance);
217 mutate(&(*table)[key]);
218 }
219 }); 218 });
220} 219}
221 220
diff --git a/test/Android.bp b/test/Android.bp
index 50afb63..4dd6480 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -31,6 +31,7 @@ cc_test {
31 static_libs: [ 31 static_libs: [
32 "libgtest", 32 "libgtest",
33 "libassemblevintf", 33 "libassemblevintf",
34 "libhidl-gen-utils",
34 ], 35 ],
35 36
36 cflags: [ 37 cflags: [
@@ -65,8 +66,8 @@ cc_test {
65 static_libs: [ 66 static_libs: [
66 "libgtest", 67 "libgtest",
67 "libgmock", 68 "libgmock",
68 "libhidl-gen-utils",
69 "libvintf_common", 69 "libvintf_common",
70 "libhidl-gen-utils",
70 "libz", 71 "libz",
71 ], 72 ],
72 cflags: [ 73 cflags: [
diff --git a/test/LibVintfTest.cpp b/test/LibVintfTest.cpp
index 33fd833..ce3a656 100644
--- a/test/LibVintfTest.cpp
+++ b/test/LibVintfTest.cpp
@@ -758,18 +758,6 @@ TEST_F(LibVintfTest, HalManifestGetHals) {
758 auto nfcHals = vm.getHals("android.hardware.nfc"); 758 auto nfcHals = vm.getHals("android.hardware.nfc");
759 EXPECT_EQ((int)nfcHals.size(), 1); 759 EXPECT_EQ((int)nfcHals.size(), 1);
760 EXPECT_EQ(*nfcHals[0], expectedNfcHal); 760 EXPECT_EQ(*nfcHals[0], expectedNfcHal);
761
762 EXPECT_EQ(*vm.getHal("android.hardware.camera", {1, 1}), expectedCameraHalV1_2);
763 EXPECT_EQ(*vm.getHal("android.hardware.camera", {2, 0}), expectedCameraHalV2_0);
764 EXPECT_EQ(*vm.getHal("android.hardware.nfc", {1, 0}), expectedNfcHal);
765 EXPECT_EQ(*vm.getHal("android.hardware.nfc", {2, 0}), expectedNfcHal);
766 EXPECT_EQ(*vm.getHal("android.hardware.nfc", {2, 1}), expectedNfcHal);
767
768 EXPECT_EQ(vm.getHal("non-existent", {1, 0}), nullptr);
769 EXPECT_EQ(vm.getHal("android.hardware.camera", {2, 1}), nullptr);
770 EXPECT_EQ(vm.getHal("android.hardware.camera", {1, 3}), nullptr);
771 EXPECT_EQ(vm.getHal("android.hardware.nfc", {1, 1}), nullptr);
772 EXPECT_EQ(vm.getHal("android.hardware.nfc", {3, 0}), nullptr);
773} 761}
774 762
775TEST_F(LibVintfTest, CompatibilityMatrixGetHals) { 763TEST_F(LibVintfTest, CompatibilityMatrixGetHals) {
@@ -803,18 +791,6 @@ TEST_F(LibVintfTest, CompatibilityMatrixGetHals) {
803 auto nfcHals = cm.getHals("android.hardware.nfc"); 791 auto nfcHals = cm.getHals("android.hardware.nfc");
804 EXPECT_EQ((int)nfcHals.size(), 1); 792 EXPECT_EQ((int)nfcHals.size(), 1);
805 EXPECT_EQ(*nfcHals[0], expectedNfcHal); 793 EXPECT_EQ(*nfcHals[0], expectedNfcHal);
806
807 EXPECT_EQ(*cm.getHal("android.hardware.camera", {1, 2}), expectedCameraHal);
808 EXPECT_EQ(*cm.getHal("android.hardware.camera", {1, 3}), expectedCameraHal);
809 EXPECT_EQ(*cm.getHal("android.hardware.camera", {4, 5}), expectedCameraHal);
810 EXPECT_EQ(*cm.getHal("android.hardware.nfc", {4, 5}), expectedNfcHal);
811 EXPECT_EQ(*cm.getHal("android.hardware.nfc", {10, 12}), expectedNfcHal);
812
813 EXPECT_EQ(cm.getHal("non-existent", {1, 0}), nullptr);
814 EXPECT_EQ(cm.getHal("android.hardware.camera", {2, 1}), nullptr);
815 EXPECT_EQ(cm.getHal("android.hardware.camera", {1, 0}), nullptr);
816 EXPECT_EQ(cm.getHal("android.hardware.nfc", {3, 0}), nullptr);
817 EXPECT_EQ(cm.getHal("android.hardware.nfc", {4, 7}), nullptr);
818} 794}
819 795
820TEST_F(LibVintfTest, RuntimeInfo) { 796TEST_F(LibVintfTest, RuntimeInfo) {
@@ -2443,12 +2419,12 @@ TEST_F(LibVintfTest, ManifestHalOverride) {
2443 " </hal>\n" 2419 " </hal>\n"
2444 "</manifest>\n"; 2420 "</manifest>\n";
2445 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError(); 2421 EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
2446 const ManifestHal* foo = manifest.getHal("android.hardware.foo", {1, 0}); 2422 const auto& foo = manifest.getHals("android.hardware.foo");
2447 ASSERT_NE(nullptr, foo); 2423 ASSERT_FALSE(foo.empty());
2448 EXPECT_TRUE(foo->isOverride); 2424 EXPECT_TRUE(foo.front()->isOverride);
2449 const ManifestHal* bar = manifest.getHal("android.hardware.bar", {1, 0}); 2425 const auto& bar = manifest.getHals("android.hardware.bar");
2450 ASSERT_NE(nullptr, bar); 2426 ASSERT_FALSE(bar.empty());
2451 EXPECT_FALSE(bar->isOverride); 2427 EXPECT_FALSE(bar.front()->isOverride);
2452} 2428}
2453 2429
2454// Test functionality of override="true" tag 2430// Test functionality of override="true" tag
@@ -2782,7 +2758,7 @@ TEST_F(LibVintfTest, MatrixDetailErrorMsg) {
2782 2758
2783 HalManifest manifest; 2759 HalManifest manifest;
2784 xml = 2760 xml =
2785 "<manifest version=\"1.0\" type=\"device\">\n" 2761 "<manifest version=\"1.0\" type=\"device\" target-level=\"103\">\n"
2786 " <hal format=\"hidl\">\n" 2762 " <hal format=\"hidl\">\n"
2787 " <name>android.hardware.foo</name>\n" 2763 " <name>android.hardware.foo</name>\n"
2788 " <transport>hwbinder</transport>\n" 2764 " <transport>hwbinder</transport>\n"
@@ -2798,7 +2774,7 @@ TEST_F(LibVintfTest, MatrixDetailErrorMsg) {
2798 { 2774 {
2799 CompatibilityMatrix cm; 2775 CompatibilityMatrix cm;
2800 xml = 2776 xml =
2801 "<compatibility-matrix version=\"1.0\" type=\"framework\">\n" 2777 "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"100\">\n"
2802 " <hal format=\"hidl\" optional=\"false\">\n" 2778 " <hal format=\"hidl\" optional=\"false\">\n"
2803 " <name>android.hardware.foo</name>\n" 2779 " <name>android.hardware.foo</name>\n"
2804 " <version>1.2-3</version>\n" 2780 " <version>1.2-3</version>\n"
@@ -2816,6 +2792,8 @@ TEST_F(LibVintfTest, MatrixDetailErrorMsg) {
2816 "</compatibility-matrix>\n"; 2792 "</compatibility-matrix>\n";
2817 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml, &error)) << error; 2793 EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml, &error)) << error;
2818 EXPECT_FALSE(manifest.checkCompatibility(cm, &error)); 2794 EXPECT_FALSE(manifest.checkCompatibility(cm, &error));
2795 EXPECT_IN("Manifest level = 103", error)
2796 EXPECT_IN("Matrix level = 100", error)
2819 EXPECT_IN( 2797 EXPECT_IN(
2820 "android.hardware.foo:\n" 2798 "android.hardware.foo:\n"
2821 " required: \n" 2799 " required: \n"