libvintf: Allow runtime configuration of vendor manifest

Single vendor can support multiple skus with different
capabilities. Add support to load sku based vendor manifest
in below order.

1. If {vendorSku} is defined,
       /vendor/etc/vintf/manifest_{vendorSku}.xml
2. /vendor/etc/vintf/manifest.xml

{vendorSku} is the value of ro.boot.product.vendor.sku

Bug : 148601741

Change-Id: I394c55807a71d8d23dd56a7dbed2100c298eb3a3
Merged-In: I394c55807a71d8d23dd56a7dbed2100c298eb3a3
diff --git a/VintfObject.cpp b/VintfObject.cpp
index c13dc64..1b2c621 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -227,20 +227,22 @@
 }
 
 // Priority for loading vendor manifest:
-// 1. /vendor/etc/vintf/manifest.xml + device fragments + ODM manifest (optional) + odm fragments
-// 2. /vendor/etc/vintf/manifest.xml + device fragments
+// 1. Vendor manifest + device fragments + ODM manifest (optional) + odm fragments
+// 2. Vendor manifest + device fragments
 // 3. ODM manifest (optional) + odm fragments
 // 4. /vendor/manifest.xml (legacy, no fragments)
 // where:
 // A + B means unioning <hal> tags from A and B. If B declares an override, then this takes priority
 // over A.
 status_t VintfObject::fetchDeviceHalManifest(HalManifest* out, std::string* error) {
-    status_t vendorStatus = fetchOneHalManifest(kVendorManifest, out, error);
+    HalManifest vendorManifest;
+    status_t vendorStatus = fetchVendorHalManifest(&vendorManifest, error);
     if (vendorStatus != OK && vendorStatus != NAME_NOT_FOUND) {
         return vendorStatus;
     }
 
     if (vendorStatus == OK) {
+        *out = std::move(vendorManifest);
         status_t fragmentStatus = addDirectoryManifests(kVendorManifestFragmentDir, out, error);
         if (fragmentStatus != OK) {
             return fragmentStatus;
@@ -275,6 +277,33 @@
     return out->fetchAllInformation(getFileSystem().get(), kVendorLegacyManifest, error);
 }
 
+// Priority:
+// 1. if {vendorSku} is defined, /vendor/etc/vintf/manifest_{vendorSku}.xml
+// 2. /vendor/etc/vintf/manifest.xml
+// where:
+// {vendorSku} is the value of ro.boot.product.vendor.sku
+status_t VintfObject::fetchVendorHalManifest(HalManifest* out, std::string* error) {
+    status_t status;
+
+    std::string vendorSku;
+    vendorSku = getPropertyFetcher()->getProperty("ro.boot.product.vendor.sku", "");
+
+    if (!vendorSku.empty()) {
+        status =
+            fetchOneHalManifest(kVendorVintfDir + "manifest_" + vendorSku + ".xml", out, error);
+        if (status == OK || status != NAME_NOT_FOUND) {
+            return status;
+        }
+    }
+
+    status = fetchOneHalManifest(kVendorManifest, out, error);
+    if (status == OK || status != NAME_NOT_FOUND) {
+        return status;
+    }
+
+    return NAME_NOT_FOUND;
+}
+
 // "out" is written to iff return status is OK.
 // Priority:
 // 1. if {sku} is defined, /odm/etc/vintf/manifest_{sku}.xml