VintfObject: load ODM manifest and override vendor manifest
Priority for loading vendor manifest:
1. If {sku} sysprop is set and both files exist,
/vendor/etc/manifest.xml + /odm/etc/manifest_{sku}.xml
2. If both files exist,
/vendor/etc/manifest.xml + /odm/etc/manifest.xml
3. If file exists, /vendor/etc/manifest.xml
4. If {sku} sysprop is set and file exists,
/odm/etc/manifest_{sku}.xml
5. If file exists, /odm/etc/manifest.xml
6. If file exists, /vendor/manifest.xml
Test: vintf_object_tests
Bug: 69051162
Change-Id: Icf9e0353ad9da51f6105ee05fc07fa2348c5afa2
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 24694cd..ee834eb 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -74,34 +74,7 @@
// static
std::shared_ptr<const HalManifest> VintfObject::GetDeviceHalManifest(bool skipCache) {
static LockedSharedPtr<HalManifest> gVendorManifest;
- static LockedSharedPtr<HalManifest> gOdmManifest;
-#ifdef LIBVINTF_TARGET
- static LockedSharedPtr<HalManifest> gProductManifest;
-#endif
- static std::mutex gDeviceManifestMutex;
-
- std::unique_lock<std::mutex> _lock(gDeviceManifestMutex);
-
-#ifdef LIBVINTF_TARGET
- std::string productModel = android::base::GetProperty("ro.boot.product.hardware.sku", "");
- if (!productModel.empty()) {
- auto product = Get(&gProductManifest, skipCache,
- std::bind(&HalManifest::fetchAllInformation, _1,
- "/odm/etc/manifest_" + productModel + ".xml", _2));
- if (product != nullptr) {
- return product;
- }
- }
-#endif
-
- auto odm = Get(&gOdmManifest, skipCache,
- std::bind(&HalManifest::fetchAllInformation, _1, "/odm/etc/manifest.xml", _2));
- if (odm != nullptr) {
- return odm;
- }
-
- return Get(&gVendorManifest, skipCache,
- std::bind(&HalManifest::fetchAllInformation, _1, "/vendor/manifest.xml", _2));
+ return Get(&gVendorManifest, skipCache, &VintfObject::FetchDeviceHalManifest);
}
// static
@@ -198,6 +171,71 @@
return OK;
}
+// Priority for loading vendor manifest:
+// 1. If {sku} sysprop is set and both files exist,
+// /vendor/etc/manifest.xml + /odm/etc/manifest_{sku}.xml
+// 2. If both files exist,
+// /vendor/etc/manifest.xml + /odm/etc/manifest.xml
+// 3. If file exists, /vendor/etc/manifest.xml
+// 4. If {sku} sysprop is set and file exists,
+// /odm/etc/manifest_{sku}.xml
+// 5. If file exists, /odm/etc/manifest.xml
+// 6. If file exists, /vendor/manifest.xml
+// where:
+// {sku} is the value of ro.boot.product.hardware.sku
+// A + B means adding <hal> tags from B to A (so that <hal>s from B can override A)
+status_t VintfObject::FetchDeviceHalManifest(HalManifest* out, std::string* error) {
+ // fetchAllInformation returns NAME_NOT_FOUND if file is missing.
+ HalManifest vendorManifest;
+ status_t vendorStatus = vendorManifest.fetchAllInformation("/vendor/etc/manifest.xml", error);
+ if (vendorStatus != OK && vendorStatus != NAME_NOT_FOUND) {
+ return vendorStatus;
+ }
+
+ HalManifest odmManifest;
+ status_t odmStatus = NAME_NOT_FOUND;
+
+#ifdef LIBVINTF_TARGET
+ std::string productModel = android::base::GetProperty("ro.boot.product.hardware.sku", "");
+ if (!productModel.empty()) {
+ odmStatus =
+ odmManifest.fetchAllInformation("/odm/etc/manifest_" + productModel + ".xml", error);
+ if (odmStatus != OK && odmStatus != NAME_NOT_FOUND) {
+ return odmStatus;
+ }
+ }
+#endif
+
+ if (odmStatus == NAME_NOT_FOUND) {
+ odmStatus = odmManifest.fetchAllInformation("/odm/etc/manifest.xml", error);
+ if (odmStatus != OK && odmStatus != NAME_NOT_FOUND) {
+ return odmStatus;
+ }
+ }
+
+ // Both files exist. Use vendor manifest as base manifest and let ODM manifest override it.
+ if (vendorStatus == OK && odmStatus == OK) {
+ *out = std::move(vendorManifest);
+ out->addAllHals(&odmManifest);
+ return OK;
+ }
+
+ // Only vendor manifest exists. Use it.
+ if (vendorStatus == OK) {
+ *out = std::move(vendorManifest);
+ return OK;
+ }
+
+ // Only ODM manifest exists. use it.
+ if (odmStatus == OK) {
+ *out = std::move(odmManifest);
+ return OK;
+ }
+
+ // Use legacy /vendor/manifest.xml
+ return out->fetchAllInformation("/vendor/manifest.xml", error);
+}
+
std::vector<Named<CompatibilityMatrix>> VintfObject::GetAllFrameworkMatrixLevels(
std::string* error) {
std::vector<std::string> fileNames;