Add VintfObjectRecovery.
This is a special VintfObject for recovery ramdisk. In
recovery ramdisk, there's no Treble split, and all
manifests are stored under /system/etc/vintf.
Also add vintf_object_recovery_test, which is a host test that
mocks the recovery file system.
Test: vintf_object_recovery_test
Bug: 206888109
Change-Id: Ifc88329832fafaace073dd814fd24b638845f807
diff --git a/VintfObject.cpp b/VintfObject.cpp
index c9460a0..8d9df31 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -30,6 +30,7 @@
#include <hidl/metadata.h>
#include "CompatibilityMatrix.h"
+#include "VintfObjectUtils.h"
#include "constants-private.h"
#include "parse_string.h"
#include "parse_xml.h"
@@ -50,29 +51,6 @@
static constexpr bool kIsTarget = false;
#endif
-template <typename T, typename F>
-static std::shared_ptr<const T> Get(const char* id, LockedSharedPtr<T>* ptr,
- const F& fetchAllInformation) {
- std::unique_lock<std::mutex> _lock(ptr->mutex);
- if (!ptr->fetchedOnce) {
- LOG(INFO) << id << ": Reading VINTF information.";
- ptr->object = std::make_unique<T>();
- std::string error;
- status_t status = fetchAllInformation(ptr->object.get(), &error);
- if (status == OK) {
- ptr->fetchedOnce = true;
- LOG(INFO) << id << ": Successfully processed VINTF information";
- } else {
- // Doubled because a malformed error std::string might cause us to
- // lose the status.
- LOG(ERROR) << id << ": status from fetching VINTF information: " << status;
- LOG(ERROR) << id << ": " << status << " VINTF parse error: " << error;
- ptr->object = nullptr; // frees the old object
- }
- }
- return ptr->object;
-}
-
static std::unique_ptr<FileSystem> createDefaultFileSystem() {
std::unique_ptr<FileSystem> fileSystem;
if (kIsTarget) {
@@ -215,8 +193,9 @@
}
// Load and combine all of the manifests in a directory
+// If forceSchemaType, all fragment manifests are coerced into manifest->type().
status_t VintfObject::addDirectoryManifests(const std::string& directory, HalManifest* manifest,
- std::string* error) {
+ bool forceSchemaType, std::string* error) {
std::vector<std::string> fileNames;
status_t err = getFileSystem()->listFiles(directory, &fileNames, error);
// if the directory isn't there, that's okay
@@ -235,6 +214,10 @@
err = fetchOneHalManifest(directory + file, &fragmentManifest, error);
if (err != OK) return err;
+ if (forceSchemaType) {
+ fragmentManifest.setType(manifest->type());
+ }
+
if (!manifest->addAll(&fragmentManifest, error)) {
if (error) {
error->insert(0, "Cannot add manifest fragment " + directory + file + ": ");
@@ -263,7 +246,8 @@
if (vendorStatus == OK) {
*out = std::move(vendorManifest);
- status_t fragmentStatus = addDirectoryManifests(kVendorManifestFragmentDir, out, error);
+ status_t fragmentStatus = addDirectoryManifests(kVendorManifestFragmentDir, out,
+ false /* forceSchemaType*/, error);
if (fragmentStatus != OK) {
return fragmentStatus;
}
@@ -284,13 +268,15 @@
return UNKNOWN_ERROR;
}
}
- return addDirectoryManifests(kOdmManifestFragmentDir, out, error);
+ return addDirectoryManifests(kOdmManifestFragmentDir, out, false /* forceSchemaType */,
+ error);
}
// vendorStatus != OK, "out" is not changed.
if (odmStatus == OK) {
*out = std::move(odmManifest);
- return addDirectoryManifests(kOdmManifestFragmentDir, out, error);
+ return addDirectoryManifests(kOdmManifestFragmentDir, out, false /* forceSchemaType */,
+ error);
}
// Use legacy /vendor/manifest.xml
@@ -397,7 +383,8 @@
status_t VintfObject::fetchUnfilteredFrameworkHalManifest(HalManifest* out, std::string* error) {
auto systemEtcStatus = fetchOneHalManifest(kSystemManifest, out, error);
if (systemEtcStatus == OK) {
- auto dirStatus = addDirectoryManifests(kSystemManifestFragmentDir, out, error);
+ auto dirStatus = addDirectoryManifests(kSystemManifestFragmentDir, out,
+ false /* forceSchemaType */, error);
if (dirStatus != OK) {
return dirStatus;
}
@@ -421,7 +408,8 @@
}
}
- auto fragmentStatus = addDirectoryManifests(frags, out, error);
+ auto fragmentStatus =
+ addDirectoryManifests(frags, out, false /* forceSchemaType */, error);
if (fragmentStatus != OK) {
return fragmentStatus;
}