Add bitness info to <transport>.
Only valid for transport == passthrough or toggled.
Example:
<transport>hwbinder</transport>
<transport arch="64">passthrough</transport>
<transport arch="32+64">passthrough</transport>
<transport arch="32">passthrough</transport>
Allow transport tag to be missing (for native HALs like GLES).
Bug: 35966597
Test: libvintf_test
Change-Id: I80928a5d46f3097ed18f2894e46762127b29bd4c
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 4004792..d3838f8 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -316,6 +316,10 @@
return true;
}
+ template <typename T>
+ inline bool parseText(NodeType *node, T *s) const {
+ return ::android::vintf::parse(getText(node), s);
+ }
protected:
mutable std::string mLastError;
};
@@ -347,10 +351,33 @@
const XmlTextConverter<VersionRange> versionRangeConverter{"version"};
-const XmlTextConverter<Transport> transportConverter{"transport"};
-
const XmlTextConverter<KernelConfigKey> kernelConfigKeyConverter{"key"};
+struct TransportArchConverter : public XmlNodeConverter<TransportArch> {
+ std::string elementName() const override { return "transport"; }
+ void mutateNode(const TransportArch &object, NodeType *root, DocType *d) const override {
+ if (object.arch != Arch::ARCH_EMPTY) {
+ appendAttr(root, "arch", object.arch);
+ }
+ appendText(root, ::android::vintf::to_string(object.transport), d);
+ }
+ bool buildObject(TransportArch *object, NodeType *root) const override {
+ if (!parseOptionalAttr(root, "arch", Arch::ARCH_EMPTY, &object->arch) ||
+ !parseText(root, &object->transport)) {
+ return false;
+ }
+ if (!object->isValid()) {
+ this->mLastError = "transport == " + ::android::vintf::to_string(object->transport) +
+ " and arch == " + ::android::vintf::to_string(object->arch) +
+ " is not a valid combination.";
+ return false;
+ }
+ return true;
+ }
+};
+
+const TransportArchConverter transportArchConverter{};
+
struct KernelConfigTypedValueConverter : public XmlNodeConverter<KernelConfigTypedValue> {
std::string elementName() const override { return "value"; }
void mutateNode(const KernelConfigTypedValue &object, NodeType *root, DocType *d) const override {
@@ -474,7 +501,9 @@
void mutateNode(const ManifestHal &hal, NodeType *root, DocType *d) const override {
appendAttr(root, "format", hal.format);
appendTextElement(root, "name", hal.name, d);
- appendChild(root, transportConverter(hal.transport, d));
+ if (!hal.transportArch.empty()) {
+ appendChild(root, transportArchConverter(hal.transportArch, d));
+ }
if (hal.impl.implLevel != ImplLevel::EMPTY) {
appendChild(root, halImplementationConverter(hal.impl, d));
}
@@ -485,7 +514,7 @@
std::vector<ManifestHalInterface> interfaces;
if (!parseOptionalAttr(root, "format", HalFormat::HIDL, &object->format) ||
!parseTextElement(root, "name", &object->name) ||
- !parseChild(root, transportConverter, &object->transport) ||
+ !parseChild(root, transportArchConverter, &object->transportArch) ||
!parseOptionalChild(root, halImplementationConverter, {}, &object->impl) ||
!parseChildren(root, versionConverter, &object->versions) ||
!parseChildren(root, manfiestHalInterfaceConverter, &interfaces)) {
@@ -500,7 +529,11 @@
return false;
}
}
- return object->isValid();
+ if (!object->isValid()) {
+ this->mLastError = "'" + object->name + "' is not a valid Manifest HAL.";
+ return false;
+ }
+ return true;
}
};