Add <fqname> to manifests.
The format of <fqname> is:
<hal>
<name>android.hardware.foo</name>
<!-- transport, etc. -->
<fqname>@1.0::IFoo/default</fqname>
</hal>
It is possible to mix <fqname> and <version>
x <interface> x <instance> ; see tests for details.
This allows instances at different versions. For example,
it is now allowed to serve @1.0::IFoo/default, @1.1::IFoo/custom
simultaneously without serving @1.1::IFoo/default.
If override="true" and no <version>x<interface>x<instance> nor
<fqname>, the HAL tag is disabled. (Previously, the HAL tag
is disabled iff no <version> exists).
Bug: 73556059
Test: libvintf_test
Test: vintf_object_test
Change-Id: I80cb9ccdeec708c2c5530812913b37f8b3cc3ffa
diff --git a/ManifestHal.cpp b/ManifestHal.cpp
index cd30f16..1576c80 100644
--- a/ManifestHal.cpp
+++ b/ManifestHal.cpp
@@ -18,6 +18,7 @@
#include <unordered_set>
#include "MapValueIterator.h"
+#include "parse_string.h"
namespace android {
namespace vintf {
@@ -43,11 +44,11 @@
if (!(transportArch == other.transportArch)) return false;
if (interfaces != other.interfaces) return false;
if (isOverride() != other.isOverride()) return false;
+ if (mAdditionalInstances != other.mAdditionalInstances) return false;
return true;
}
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) {
@@ -62,6 +63,13 @@
}
}
}
+
+ for (const auto& manifestInstance : mAdditionalInstances) {
+ if (!func(manifestInstance)) {
+ return false;
+ }
+ }
+
return true;
}
@@ -83,5 +91,49 @@
});
}
+static bool verifyInstances(const std::set<FqInstance>& fqInstances, std::string* error) {
+ for (const FqInstance& fqInstance : fqInstances) {
+ if (fqInstance.hasPackage()) {
+ if (error) *error = "Should not specify package: \"" + fqInstance.string() + "\"";
+ return false;
+ }
+ if (!fqInstance.hasVersion()) {
+ if (error) *error = "Should specify version: \"" + fqInstance.string() + "\"";
+ return false;
+ }
+ if (!fqInstance.hasInterface()) {
+ if (error) *error = "Should specify interface: \"" + fqInstance.string() + "\"";
+ return false;
+ }
+ if (!fqInstance.hasInstance()) {
+ if (error) *error = "Should specify instance: \"" + fqInstance.string() + "\"";
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ManifestHal::insertInstances(const std::set<FqInstance>& fqInstances, std::string* error) {
+ if (!verifyInstances(fqInstances, error)) {
+ return false;
+ }
+
+ for (const FqInstance& e : fqInstances) {
+ FqInstance withPackage;
+ if (!withPackage.setTo(this->getName(), e.getMajorVersion(), e.getMinorVersion(),
+ e.getInterface(), e.getInstance())) {
+ if (error) {
+ *error = "Cannot create FqInstance with package='" + this->getName() +
+ "', version='" + to_string(Version(e.getVersion())) + "', interface='" +
+ e.getInterface() + "', instance='" + e.getInstance() + "'";
+ }
+ return false;
+ }
+ mAdditionalInstances.emplace(std::move(withPackage), this->transportArch);
+ }
+
+ return true;
+}
+
} // namespace vintf
} // namespace android