Instance is the smallest unit of manifests/matrices.
Introduce forEachInstance on HalManifest and CompatibilityMatrix,
because <hal> are no longer the smallest unit of tests, but
rather a ManifestInstance / MatrixInstance object.
Bug: 73556059
Bug: 74247301
Test: libvintf_test
Test: vintf_object_test
Change-Id: If7186617db52acd67f255ac6e6c99f34a7570206
Merged-In: If7186617db52acd67f255ac6e6c99f34a7570206
diff --git a/Android.bp b/Android.bp
index 1c7a420..03267a5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -38,7 +38,9 @@
"KernelConfigParser.cpp",
"RuntimeInfo.cpp",
"ManifestHal.cpp",
+ "ManifestInstance.cpp",
"MatrixHal.cpp",
+ "MatrixInstance.cpp",
"MatrixKernel.cpp",
"SystemSdk.cpp",
"TransportArch.cpp",
@@ -48,6 +50,7 @@
],
shared_libs: [
"libbase",
+ "libhidl-gen-utils",
"liblog",
"libselinux",
"libtinyxml2",
@@ -56,6 +59,10 @@
export_include_dirs: ["include", "."],
local_include_dirs: ["include/vintf"],
+ export_shared_lib_headers: [
+ "libhidl-gen-utils",
+ ],
+
target: {
host: {
srcs: [
@@ -78,6 +85,7 @@
defaults: ["libvintf-defaults"],
shared_libs: [
"libbase",
+ "libhidl-gen-utils",
"liblog",
"libselinux",
"libtinyxml2",
@@ -90,6 +98,10 @@
"utils.cpp",
],
+ export_shared_lib_headers: [
+ "libhidl-gen-utils",
+ ],
+
whole_static_libs: ["libvintf_common"],
}
@@ -98,6 +110,7 @@
defaults: ["libvintf-defaults"],
shared_libs: [
"libbase",
+ "libhidl-gen-utils",
"libvintf",
],
srcs: [
@@ -109,6 +122,7 @@
name: "checkvintf",
defaults: ["libvintf-defaults"],
static_libs: [
+ "libhidl-gen-utils",
"libvintf_common",
"libutils",
"libtinyxml2",
diff --git a/Android.mk b/Android.mk
index b7b2ec0..efe2bea 100644
--- a/Android.mk
+++ b/Android.mk
@@ -23,5 +23,9 @@
LOCAL_STATIC_LIBRARIES := \
libbase \
libvintf \
+ libhidl-gen-utils \
libfs_mgr
+
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := libhidl-gen-utils
+
include $(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 @@
return matrix;
}
-void CompatibilityMatrix::forEachInstance(
- const std::function<void(const std::string&, const VersionRange&, const std::string&,
- const std::string&, bool, bool*)>& f) const {
- bool stop = false;
- for (const auto& hal : getHals()) {
- for (const auto& v : hal.versionRanges) {
- for (const auto& intf : iterateValues(hal.interfaces)) {
- for (const auto& instance : intf.instances) {
- f(hal.name, v, intf.name, instance, hal.optional, &stop);
- if (stop) break;
- }
+bool CompatibilityMatrix::forEachInstanceOfVersion(
+ const std::string& package, const Version& expectVersion,
+ const std::function<bool(const MatrixInstance&)>& func) const {
+ for (const MatrixHal* hal : getHals(package)) {
+ bool cont = hal->forEachInstance([&](const MatrixInstance& matrixInstance) {
+ if (matrixInstance.versionRange().contains(expectVersion)) {
+ return func(matrixInstance);
}
- }
+ return true;
+ });
+ if (!cont) return false;
}
+ return true;
}
} // namespace vintf
diff --git a/HalManifest.cpp b/HalManifest.cpp
index 6f05cab..af163ee 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -184,20 +184,19 @@
return instances.find(instanceName) != instances.end();
}
-void HalManifest::forEachInstance(
- const std::function<void(const std::string&, const Version&, const std::string&,
- const std::string&, bool*)>& f) const {
- bool stop = false;
- for (const auto& hal : getHals()) {
- for (const auto& v : hal.versions) {
- for (const auto& intf : iterateValues(hal.interfaces)) {
- for (const auto& instance : intf.instances) {
- f(hal.name, v, intf.name, instance, &stop);
- if (stop) break;
- }
+bool HalManifest::forEachInstanceOfVersion(
+ const std::string& package, const Version& expectVersion,
+ const std::function<bool(const ManifestInstance&)>& func) const {
+ for (const ManifestHal* hal : getHals(package)) {
+ bool cont = hal->forEachInstance([&](const ManifestInstance& manifestInstance) {
+ if (manifestInstance.version().minorAtLeast(expectVersion)) {
+ return func(manifestInstance);
}
- }
+ return true;
+ });
+ if (!cont) return false;
}
+ return true;
}
static bool satisfyVersion(const MatrixHal& matrixHal, const Version& manifestHalVersion) {
diff --git a/ManifestHal.cpp b/ManifestHal.cpp
index 00d0d95..beffa4d 100644
--- a/ManifestHal.cpp
+++ b/ManifestHal.cpp
@@ -17,6 +17,8 @@
#include "ManifestHal.h"
#include <unordered_set>
+#include "MapValueIterator.h"
+
namespace android {
namespace vintf {
@@ -42,13 +44,6 @@
return true;
}
-bool ManifestHal::containsVersion(const Version& version) const {
- for (Version v : versions) {
- if (v.minorAtLeast(version)) return true;
- }
- return false;
-}
-
std::set<std::string> ManifestHal::getInstances(const std::string& interfaceName) const {
std::set<std::string> ret;
auto it = interfaces.find(interfaceName);
@@ -58,5 +53,24 @@
return ret;
}
+bool ManifestHal::forEachInstance(const std::function<bool(const ManifestInstance&)>& func) const {
+ // TODO(b/73556059): support <fqname> as well.
+ for (const auto& v : versions) {
+ for (const auto& intf : iterateValues(interfaces)) {
+ for (const auto& instance : intf.instances) {
+ // TODO(b/73556059): Store ManifestInstance as well to avoid creating temps
+ FqInstance fqInstance;
+ if (fqInstance.setTo(getName(), v.majorVer, v.minorVer, intf.name, instance)) {
+ if (!func(ManifestInstance(std::move(fqInstance),
+ TransportArch{transportArch}))) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
} // namespace vintf
} // namespace android
diff --git a/ManifestInstance.cpp b/ManifestInstance.cpp
new file mode 100644
index 0000000..66e0cd3
--- /dev/null
+++ b/ManifestInstance.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ManifestInstance.h"
+
+#include <utility>
+
+namespace android {
+namespace vintf {
+
+ManifestInstance::ManifestInstance(FqInstance&& fqInstance, TransportArch&& ta)
+ : mFqInstance(std::move(fqInstance)), mTransportArch(std::move(ta)) {}
+ManifestInstance::ManifestInstance(const FqInstance& fqInstance, const TransportArch& ta)
+ : mFqInstance(fqInstance), mTransportArch(ta) {}
+
+const std::string& ManifestInstance::package() const {
+ return mFqInstance.getPackage();
+}
+
+Version ManifestInstance::version() const {
+ return mFqInstance.getVersion();
+}
+
+const std::string& ManifestInstance::interface() const {
+ return mFqInstance.getInterface();
+}
+
+const std::string& ManifestInstance::instance() const {
+ return mFqInstance.getInstance();
+}
+
+Transport ManifestInstance::transport() const {
+ return mTransportArch.transport;
+}
+
+Arch ManifestInstance::arch() const {
+ return mTransportArch.arch;
+}
+
+} // namespace vintf
+} // namespace android
diff --git a/MatrixHal.cpp b/MatrixHal.cpp
index 96dcf78..fbe9a5f 100644
--- a/MatrixHal.cpp
+++ b/MatrixHal.cpp
@@ -16,6 +16,8 @@
#include "MatrixHal.h"
+#include "MapValueIterator.h"
+
namespace android {
namespace vintf {
@@ -66,5 +68,22 @@
return true;
}
+bool MatrixHal::forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const {
+ for (const auto& vr : versionRanges) {
+ for (const auto& intf : iterateValues(interfaces)) {
+ for (const auto& instance : intf.instances) {
+ // TODO(b/73556059): Store MatrixInstance as well to avoid creating temps
+ FqInstance fqInstance;
+ if (fqInstance.setTo(getName(), vr.majorVer, vr.minMinor, intf.name, instance)) {
+ if (!func(MatrixInstance(std::move(fqInstance), VersionRange(vr), optional))) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+}
+
} // namespace vintf
} // 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 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "MatrixInstance.h"
+
+#include <utility>
+
+namespace android {
+namespace vintf {
+
+MatrixInstance::MatrixInstance(FqInstance&& fqInstance, VersionRange&& range, bool optional)
+ : mFqInstance(std::move(fqInstance)), mRange(std::move(range)), mOptional(optional) {}
+
+MatrixInstance::MatrixInstance(const FqInstance fqInstance, const VersionRange& range,
+ bool optional)
+ : mFqInstance(fqInstance), mRange(range), mOptional(optional) {}
+
+const std::string& MatrixInstance::package() const {
+ return mFqInstance.getPackage();
+}
+
+const VersionRange& MatrixInstance::versionRange() const {
+ return mRange;
+}
+
+const std::string& MatrixInstance::interface() const {
+ return mFqInstance.getInterface();
+}
+
+const std::string& MatrixInstance::instance() const {
+ return mFqInstance.getInstance();
+}
+
+bool MatrixInstance::optional() const {
+ return mOptional;
+}
+
+} // namespace vintf
+} // namespace android
diff --git a/VintfObject.cpp b/VintfObject.cpp
index c10949c..254a0dc 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -691,25 +691,23 @@
}
int32_t VintfObject::CheckDeprecation(std::string* error) {
+ using namespace std::placeholders;
auto deviceManifest = GetDeviceHalManifest();
IsInstanceInUse inManifest = [&deviceManifest](const std::string& package, Version version,
- const std::string& interface,
- const std::string& instance) {
- const ManifestHal* hal = deviceManifest->getHal(package, version);
- if (hal == nullptr) {
- return std::make_pair(false, Version{});
- }
- const auto& instances = hal->getInstances(interface);
- if (instances.find(instance) == instances.end()) {
- return std::make_pair(false, Version{});
- }
-
- for (Version v : hal->versions) {
- if (v.minorAtLeast(version)) {
- return std::make_pair(true, v);
- }
- }
- return std::make_pair(false, Version{});
+ const std::string& interface,
+ const std::string& instance) {
+ std::pair<bool, Version> ret(false, Version{});
+ deviceManifest->forEachInstanceOfInterface(
+ package, version, interface,
+ [&instance, &ret](const ManifestInstance& manifestInstance) {
+ if (manifestInstance.instance() == instance) {
+ ret.first = true;
+ ret.second = manifestInstance.version();
+ return false;
+ }
+ return true;
+ });
+ return ret;
};
return CheckDeprecation(inManifest, error);
}
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 @@
#include "Level.h"
#include "MapValueIterator.h"
#include "MatrixHal.h"
+#include "MatrixInstance.h"
#include "MatrixKernel.h"
#include "Named.h"
#include "SchemaType.h"
@@ -58,9 +59,9 @@
// (Normally, version ranges do not overlap, and the only match is returned.)
std::string getXmlSchemaPath(const std::string& xmlFileName, const Version& version) const;
- void forEachInstance(
- const std::function<void(const std::string&, const VersionRange&, const std::string&,
- const std::string&, bool, bool*)>& f) const;
+ bool forEachInstanceOfVersion(
+ const std::string& package, const Version& expectVersion,
+ const std::function<bool(const MatrixInstance&)>& func) const override;
private:
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 @@
#include <map>
#include <set>
+#include <hidl-util/FqInstance.h>
+
#include "MapValueIterator.h"
#include "Version.h"
@@ -30,6 +32,8 @@
// Hal.getName() must return a string indicating the name.
template <typename Hal>
struct HalGroup {
+ using InstanceType = typename Hal::InstanceType;
+
public:
virtual ~HalGroup() {}
// Move all hals from another HalGroup to this.
@@ -57,6 +61,7 @@
// Get all hals with the given name (e.g "android.hardware.camera").
// There could be multiple hals that matches the same given name.
+ // TODO(b/74247301) Deprecated; use forEachInstance instead.
std::vector<const Hal*> getHals(const std::string& name) const {
std::vector<const Hal*> ret;
auto range = mHals.equal_range(name);
@@ -69,6 +74,7 @@
// Get all hals with the given name (e.g "android.hardware.camera").
// There could be multiple hals that matches the same given name.
// Non-const version of the above getHals() method.
+ // TODO(b/74247301) Deprecated; use forEachInstance instead.
std::vector<Hal*> getHals(const std::string& name) {
std::vector<Hal*> ret;
auto range = mHals.equal_range(name);
@@ -78,29 +84,65 @@
return ret;
}
- // Get the hal that matches the given name and version (e.g.
- // "android.hardware.camera@2.4")
- // There should be a single hal that matches the given name and version.
- const Hal* getHal(const std::string& name, const Version& version) const {
- for (const Hal* hal : getHals(name)) {
- if (hal->containsVersion(version)) return hal;
+ // Apply func to all instances.
+ bool forEachInstance(const std::function<bool(const InstanceType&)>& func) const {
+ for (const auto& hal : getHals()) {
+ bool cont = hal.forEachInstance(func);
+ if (!cont) return false;
}
- return nullptr;
+ return true;
}
- // Get all instance names for hal that matches the given component name, version
- // and interface name (e.g. "android.hardware.camera@2.4::ICameraProvider").
- // * If the component ("android.hardware.camera@2.4") does not exist, return empty set.
- // * If the component ("android.hardware.camera@2.4") does exist,
- // * If the interface (ICameraProvider) does not exist, return empty set.
- // * Else return the list hal.interface.instance.
+ // Apply func to all instances of package@expectVersion::*/*.
+ // For example, if a.h.foo@1.1::IFoo/default is in "this" and getFqInstances
+ // is called with a.h.foo@1.0, then a.h.foo@1.1::IFoo/default is returned.
+ virtual bool forEachInstanceOfVersion(
+ const std::string& package, const Version& expectVersion,
+ const std::function<bool(const InstanceType&)>& func) const = 0;
+
+ // Apply func to instances of package@expectVersion::interface/*.
+ // For example, if a.h.foo@1.1::IFoo/default is in "this" and getFqInstances
+ // is called with a.h.foo@1.0::IFoo, then a.h.foo@1.1::IFoo/default is returned.
+ bool forEachInstanceOfInterface(const std::string& package, const Version& expectVersion,
+ const std::string& interface,
+ const std::function<bool(const InstanceType&)>& func) const {
+ return forEachInstanceOfVersion(package, expectVersion,
+ [&func, &interface](const InstanceType& e) {
+ if (e.interface() == interface) {
+ return func(e);
+ }
+ return true;
+ });
+ }
+
+ // Alternative to forEachInstanceOfInterface if you need a vector instead.
+ // If interface is empty, returns all instances of package@version;
+ // else return all instances of package@version::interface.
+ std::vector<InstanceType> getFqInstances(const std::string& package,
+ const Version& expectVersion,
+ const std::string& interface = "") const {
+ std::vector<InstanceType> v;
+ auto mapToVector = [&v](const auto& e) {
+ v.push_back(e);
+ return true;
+ };
+ if (interface.empty()) {
+ (void)forEachInstanceOfVersion(package, expectVersion, mapToVector);
+ } else {
+ (void)forEachInstanceOfInterface(package, expectVersion, interface, mapToVector);
+ }
+ return v;
+ }
+
+ // Alternative to forEachInstance if you just need a set of instance names instead.
std::set<std::string> getInstances(const std::string& halName, const Version& version,
const std::string& interfaceName) const {
- const Hal* hal = getHal(halName, version);
- if (hal == nullptr) {
- return {};
- }
- return hal->getInstances(interfaceName);
+ std::set<std::string> ret;
+ (void)forEachInstanceOfInterface(halName, version, interfaceName, [&ret](const auto& e) {
+ ret.insert(e.instance());
+ return true;
+ });
+ return ret;
}
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 @@
#ifndef ANDROID_VINTF_HAL_MANIFEST_H
#define ANDROID_VINTF_HAL_MANIFEST_H
+#include <hidl-util/FqInstance.h>
+#include <utils/Errors.h>
#include <map>
#include <string>
-#include <utils/Errors.h>
#include <vector>
#include "HalGroup.h"
#include "Level.h"
#include "ManifestHal.h"
+#include "ManifestInstance.h"
#include "MapValueIterator.h"
#include "SchemaType.h"
#include "SystemSdk.h"
@@ -117,9 +119,9 @@
// Get metaversion of this manifest.
Version getMetaVersion() const;
- void forEachInstance(
- const std::function<void(const std::string&, const Version&, const std::string&,
- const std::string&, bool*)>& f) const;
+ bool forEachInstanceOfVersion(
+ const std::string& package, const Version& expectVersion,
+ const std::function<bool(const ManifestInstance&)>& func) const override;
protected:
// Check before add()
diff --git a/include/vintf/ManifestHal.h b/include/vintf/ManifestHal.h
index e326857..da5a700 100644
--- a/include/vintf/ManifestHal.h
+++ b/include/vintf/ManifestHal.h
@@ -25,6 +25,7 @@
#include "HalFormat.h"
#include "HalInterface.h"
+#include "ManifestInstance.h"
#include "TransportArch.h"
#include "Version.h"
@@ -33,6 +34,7 @@
// A component of HalManifest.
struct ManifestHal {
+ using InstanceType = ManifestInstance;
bool operator==(const ManifestHal &other) const;
// Check whether the ManifestHal contains the given version.
@@ -57,6 +59,7 @@
}
inline const std::string& getName() const { return name; }
+ bool forEachInstance(const std::function<bool(const ManifestInstance&)>& func) const;
private:
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 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VINTF_MANIFEST_INSTANCE_H
+#define ANDROID_VINTF_MANIFEST_INSTANCE_H
+
+#include <string>
+
+#include <hidl-util/FqInstance.h>
+
+#include "TransportArch.h"
+#include "Version.h"
+
+namespace android {
+namespace vintf {
+
+class ManifestInstance {
+ public:
+ using VersionType = Version;
+ ManifestInstance(FqInstance&& fqInstance, TransportArch&& ta);
+ ManifestInstance(const FqInstance& fqInstance, const TransportArch& ta);
+ const std::string& package() const;
+ Version version() const;
+ const std::string& interface() const;
+ const std::string& instance() const;
+ Transport transport() const;
+ Arch arch() const;
+
+ private:
+ FqInstance mFqInstance;
+ TransportArch mTransportArch;
+};
+
+} // namespace vintf
+} // namespace android
+
+#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 @@
#include "HalFormat.h"
#include "HalInterface.h"
+#include "MatrixInstance.h"
#include "VersionRange.h"
namespace android {
@@ -31,6 +32,7 @@
// A HAL entry to a compatibility matrix
struct MatrixHal {
+ using InstanceType = MatrixInstance;
bool operator==(const MatrixHal &other) const;
// Check whether the MatrixHal contains the given version.
@@ -51,6 +53,8 @@
// Return true if "this" contains all interface/instance instances in "other".
bool containsInstances(const MatrixHal& other) const;
+
+ bool forEachInstance(const std::function<bool(const MatrixInstance&)>& func) const;
};
} // 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 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VINTF_MATRIX_INSTANCE_H
+#define ANDROID_VINTF_MATRIX_INSTANCE_H
+
+#include <string>
+
+#include <hidl-util/FqInstance.h>
+
+#include "VersionRange.h"
+
+namespace android {
+namespace vintf {
+
+class MatrixInstance {
+ public:
+ using VersionType = VersionRange;
+ // fqInstance.version is ignored. Version range is provided separately.
+ MatrixInstance(FqInstance&& fqInstance, VersionRange&& range, bool optional);
+ MatrixInstance(const FqInstance fqInstance, const VersionRange& range, bool optional);
+ const std::string& package() const;
+ const VersionRange& versionRange() const;
+ const std::string& interface() const;
+ const std::string& instance() const;
+ bool optional() const;
+
+ private:
+ FqInstance mFqInstance;
+ VersionRange mRange;
+ bool mOptional;
+};
+
+} // namespace vintf
+} // namespace android
+
+#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 @@
constexpr Version() : Version(0u, 0u) {}
constexpr Version(size_t mj, size_t mi) : majorVer(mj), minorVer(mi) {}
+ constexpr Version(const std::pair<size_t, size_t>& pair)
+ : majorVer(pair.first), minorVer(pair.second) {}
size_t majorVer;
size_t minorVer;
diff --git a/main.cpp b/main.cpp
index c4119c9..7843cb5 100644
--- a/main.cpp
+++ b/main.cpp
@@ -188,34 +188,38 @@
// if it does not exist and setting the corresponding indicator (as specified by "mutate").
void insert(const HalManifest* manifest, Table* table, const RowMutator& mutate) {
if (manifest == nullptr) return;
- manifest->forEachInstance([&](const auto& package, const auto& version, const auto& interface,
- const auto& instance, bool* /* stop */) {
- std::string key = toFQNameString(package, VersionRange{version.majorVer, version.minorVer},
- interface, instance);
+ manifest->forEachInstance([&](const auto& manifestInstance) {
+ std::string key = toFQNameString(manifestInstance.package(), manifestInstance.version(),
+ manifestInstance.interface(), manifestInstance.instance());
mutate(&(*table)[key]);
+ return true;
});
}
void insert(const CompatibilityMatrix* matrix, Table* table, const RowMutator& mutate) {
if (matrix == nullptr) return;
- matrix->forEachInstance([&](const auto& package, const auto& range, const auto& interface,
- const auto& instance, bool optional, bool* /* stop */) {
+ matrix->forEachInstance([&](const auto& matrixInstance) {
bool missed = false;
- for (auto minorVer = range.minMinor; minorVer <= range.maxMinor; ++minorVer) {
- std::string key = toFQNameString(package, VersionRange{range.majorVer, minorVer},
- interface, instance);
+ for (auto minorVer = matrixInstance.versionRange().minMinor;
+ minorVer <= matrixInstance.versionRange().maxMinor; ++minorVer) {
+ std::string key = toFQNameString(
+ matrixInstance.package(), Version{matrixInstance.versionRange().majorVer, minorVer},
+ matrixInstance.interface(), matrixInstance.instance());
auto it = table->find(key);
if (it == table->end()) {
missed = true;
} else {
mutate(&it->second);
- it->second.required = !optional;
+ it->second.required = !matrixInstance.optional();
}
}
if (missed) {
- std::string key = toFQNameString(package, range, interface, instance);
+ std::string key =
+ toFQNameString(matrixInstance.package(), matrixInstance.versionRange(),
+ matrixInstance.interface(), matrixInstance.instance());
mutate(&(*table)[key]);
}
+ return true;
});
}
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 @@
static_libs: [
"libgtest",
"libassemblevintf",
+ "libhidl-gen-utils",
],
cflags: [
@@ -65,8 +66,8 @@
static_libs: [
"libgtest",
"libgmock",
- "libhidl-gen-utils",
"libvintf_common",
+ "libhidl-gen-utils",
"libz",
],
cflags: [
diff --git a/test/LibVintfTest.cpp b/test/LibVintfTest.cpp
index 33fd833..ee4a3e2 100644
--- a/test/LibVintfTest.cpp
+++ b/test/LibVintfTest.cpp
@@ -758,18 +758,6 @@
auto nfcHals = vm.getHals("android.hardware.nfc");
EXPECT_EQ((int)nfcHals.size(), 1);
EXPECT_EQ(*nfcHals[0], expectedNfcHal);
-
- EXPECT_EQ(*vm.getHal("android.hardware.camera", {1, 1}), expectedCameraHalV1_2);
- EXPECT_EQ(*vm.getHal("android.hardware.camera", {2, 0}), expectedCameraHalV2_0);
- EXPECT_EQ(*vm.getHal("android.hardware.nfc", {1, 0}), expectedNfcHal);
- EXPECT_EQ(*vm.getHal("android.hardware.nfc", {2, 0}), expectedNfcHal);
- EXPECT_EQ(*vm.getHal("android.hardware.nfc", {2, 1}), expectedNfcHal);
-
- EXPECT_EQ(vm.getHal("non-existent", {1, 0}), nullptr);
- EXPECT_EQ(vm.getHal("android.hardware.camera", {2, 1}), nullptr);
- EXPECT_EQ(vm.getHal("android.hardware.camera", {1, 3}), nullptr);
- EXPECT_EQ(vm.getHal("android.hardware.nfc", {1, 1}), nullptr);
- EXPECT_EQ(vm.getHal("android.hardware.nfc", {3, 0}), nullptr);
}
TEST_F(LibVintfTest, CompatibilityMatrixGetHals) {
@@ -803,18 +791,6 @@
auto nfcHals = cm.getHals("android.hardware.nfc");
EXPECT_EQ((int)nfcHals.size(), 1);
EXPECT_EQ(*nfcHals[0], expectedNfcHal);
-
- EXPECT_EQ(*cm.getHal("android.hardware.camera", {1, 2}), expectedCameraHal);
- EXPECT_EQ(*cm.getHal("android.hardware.camera", {1, 3}), expectedCameraHal);
- EXPECT_EQ(*cm.getHal("android.hardware.camera", {4, 5}), expectedCameraHal);
- EXPECT_EQ(*cm.getHal("android.hardware.nfc", {4, 5}), expectedNfcHal);
- EXPECT_EQ(*cm.getHal("android.hardware.nfc", {10, 12}), expectedNfcHal);
-
- EXPECT_EQ(cm.getHal("non-existent", {1, 0}), nullptr);
- EXPECT_EQ(cm.getHal("android.hardware.camera", {2, 1}), nullptr);
- EXPECT_EQ(cm.getHal("android.hardware.camera", {1, 0}), nullptr);
- EXPECT_EQ(cm.getHal("android.hardware.nfc", {3, 0}), nullptr);
- EXPECT_EQ(cm.getHal("android.hardware.nfc", {4, 7}), nullptr);
}
TEST_F(LibVintfTest, RuntimeInfo) {
@@ -2443,12 +2419,12 @@
" </hal>\n"
"</manifest>\n";
EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError();
- const ManifestHal* foo = manifest.getHal("android.hardware.foo", {1, 0});
- ASSERT_NE(nullptr, foo);
- EXPECT_TRUE(foo->isOverride);
- const ManifestHal* bar = manifest.getHal("android.hardware.bar", {1, 0});
- ASSERT_NE(nullptr, bar);
- EXPECT_FALSE(bar->isOverride);
+ const auto& foo = manifest.getHals("android.hardware.foo");
+ ASSERT_FALSE(foo.empty());
+ EXPECT_TRUE(foo.front()->isOverride);
+ const auto& bar = manifest.getHals("android.hardware.bar");
+ ASSERT_FALSE(bar.empty());
+ EXPECT_FALSE(bar.front()->isOverride);
}
// Test functionality of override="true" tag