Merge "Native HALs don't require <transport>."
diff --git a/parse_xml.cpp b/parse_xml.cpp
index f12df00..518faec 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -16,10 +16,16 @@
 
 // Convert objects from and to xml.
 
+#define LOG_TAG "libvintf"
+#include <android-base/logging.h>
+
+#include "parse_xml.h"
+
+#include <type_traits>
+
 #include <tinyxml2.h>
 
 #include "parse_string.h"
-#include "parse_xml.h"
 
 namespace android {
 namespace vintf {
@@ -539,11 +545,35 @@
         std::vector<HalInterface> interfaces;
         if (!parseOptionalAttr(root, "format", HalFormat::HIDL, &object->format) ||
             !parseTextElement(root, "name", &object->name) ||
-            !parseChild(root, transportArchConverter, &object->transportArch) ||
+            !parseOptionalChild(root, transportArchConverter, {}, &object->transportArch) ||
             !parseChildren(root, versionConverter, &object->versions) ||
             !parseChildren(root, halInterfaceConverter, &interfaces)) {
             return false;
         }
+
+        switch (object->format) {
+            case HalFormat::HIDL: {
+                if (object->transportArch.empty()) {
+                    this->mLastError =
+                        "HIDL HAL '" + object->name + "' should have <transport> defined.";
+                    return false;
+                }
+            } break;
+            case HalFormat::NATIVE: {
+                if (!object->transportArch.empty()) {
+                    this->mLastError =
+                        "Native HAL '" + object->name + "' should not have <transport> defined.";
+                    return false;
+                }
+            } break;
+            default: {
+                LOG(FATAL) << "Unhandled HalFormat "
+                           << static_cast<typename std::underlying_type<HalFormat>::type>(
+                                  object->format);
+            } break;
+        }
+        if (!object->transportArch.isValid()) return false;
+
         object->interfaces.clear();
         for (auto &&interface : interfaces) {
             auto res = object->interfaces.emplace(interface.name,
diff --git a/test/main.cpp b/test/main.cpp
index 8dc5ddb..42932e5 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -304,6 +304,28 @@
             "</manifest>"));
 }
 
+TEST_F(LibVintfTest, HalManifestNative) {
+    HalManifest vm;
+    EXPECT_TRUE(gHalManifestConverter(&vm,
+                                      "<manifest version=\"1.0\" type=\"device\">"
+                                      "    <hal format=\"native\">"
+                                      "        <name>foo</name>"
+                                      "        <version>1.0</version>"
+                                      "    </hal>"
+                                      "</manifest>"))
+        << gHalManifestConverter.lastError();
+    EXPECT_FALSE(gHalManifestConverter(&vm,
+                                       "<manifest version=\"1.0\" type=\"device\">"
+                                       "    <hal format=\"native\">"
+                                       "        <name>foo</name>"
+                                       "        <version>1.0</version>"
+                                       "        <transport>hwbinder</transport>"
+                                       "    </hal>"
+                                       "</manifest>"));
+    EXPECT_TRUE(gHalManifestConverter.lastError().find(
+                    "Native HAL 'foo' should not have <transport> defined") != std::string::npos);
+}
+
 TEST_F(LibVintfTest, HalManifestDuplicate) {
     HalManifest vm;
     EXPECT_FALSE(gHalManifestConverter(&vm,