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/parse_xml.cpp b/parse_xml.cpp
index bf8889f..38a09b4 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -230,11 +230,12 @@
}
}
- template<typename T, typename Array>
- inline void appendChildren(NodeType *parent, const XmlNodeConverter<T> &conv,
- const Array &array, DocType *d) const {
+ template <typename T, typename Array>
+ inline void appendChildren(NodeType* parent, const XmlNodeConverter<T>& conv,
+ const Array& array, DocType* d,
+ SerializeFlags flags = SerializeFlag::EVERYTHING) const {
for (const T &t : array) {
- appendChild(parent, conv(t, d));
+ appendChild(parent, conv.serialize(t, d, flags));
}
}
@@ -600,9 +601,15 @@
MatrixKernelConverter matrixKernelConverter{};
+XmlTextConverter<FqInstance> fqInstanceConverter{"fqname"};
+
struct ManifestHalConverter : public XmlNodeConverter<ManifestHal> {
std::string elementName() const override { return "hal"; }
- void mutateNode(const ManifestHal &hal, NodeType *root, DocType *d) const override {
+ void mutateNode(const ManifestHal& m, NodeType* root, DocType* d) const override {
+ mutateNode(m, root, d, SerializeFlag::EVERYTHING);
+ }
+ void mutateNode(const ManifestHal& hal, NodeType* root, DocType* d,
+ SerializeFlags flags) const override {
appendAttr(root, "format", hal.format);
appendTextElement(root, "name", hal.name, d);
appendChild(root, transportArchConverter(hal.transportArch, d));
@@ -611,6 +618,15 @@
if (hal.isOverride()) {
appendAttr(root, "override", hal.isOverride());
}
+
+ if (!(flags & SerializeFlag::NO_FQNAME)) {
+ std::set<FqInstance> fqInstances;
+ hal.forEachInstance([&fqInstances](const auto& manifestInstance) {
+ fqInstances.emplace(manifestInstance.getFqInstanceNoPackage());
+ return true;
+ });
+ appendChildren(root, fqInstanceConverter, fqInstances, d);
+ }
}
bool buildObject(ManifestHal* object, NodeType* root, std::string* error) const override {
std::vector<HalInterface> interfaces;
@@ -666,6 +682,15 @@
return false;
}
#endif
+
+ std::set<FqInstance> fqInstances;
+ if (!parseChildren(root, fqInstanceConverter, &fqInstances, error)) {
+ return false;
+ }
+ if (!object->insertInstances(fqInstances, error)) {
+ return false;
+ }
+
return true;
}
@@ -808,7 +833,7 @@
appendAttr(root, "type", m.mType);
if (!(flags & SerializeFlag::NO_HALS)) {
- appendChildren(root, manifestHalConverter, m.getHals(), d);
+ appendChildren(root, manifestHalConverter, m.getHals(), d, flags);
}
if (m.mType == SchemaType::DEVICE) {
if (!(flags & SerializeFlag::NO_SEPOLICY)) {