Check unused HALs in check_vintf
The check is lost when deleting BUILT_ASSEMBLED_VENDOR_MANIFEST
(see I9791abc44). Re-add the check.
The check is enforced when product matrix or device system matrix is
detected, similar to the condition before I9791abc44.
Also, delete unused check in assemble_vintf when
VINTF_ENFORCE_UNUSED_HALS is set.
Test: builds
Bug: 121287858
Change-Id: Ifc5435e2ef1b4936a488827fe824126bdc50deae
Merged-In: Ifc5435e2ef1b4936a488827fe824126bdc50deae
diff --git a/Android.bp b/Android.bp
index a78a6a3..bfbd353 100644
--- a/Android.bp
+++ b/Android.bp
@@ -67,6 +67,7 @@
local_include_dirs: ["include/vintf"],
export_shared_lib_headers: [
+ "libbase",
"libhidl-gen-utils",
],
diff --git a/AssembleVintf.cpp b/AssembleVintf.cpp
index 1dec7ec..432945c 100644
--- a/AssembleVintf.cpp
+++ b/AssembleVintf.cpp
@@ -265,25 +265,6 @@
return false;
}
}
-
- // Check HALs in device manifest that are not in framework matrix.
- if (getBooleanFlag("VINTF_ENFORCE_NO_UNUSED_HALS")) {
- auto unused = manifest.checkUnusedHals(matrix);
- if (!unused.empty()) {
- std::cerr << "Error: The following instances are in the device manifest but "
- << "not specified in framework compatibility matrix: " << std::endl
- << " " << android::base::Join(unused, "\n ") << std::endl
- << "Suggested fix:" << std::endl
- << "1. Check for any typos in device manifest or framework compatibility "
- << "matrices with FCM version >= " << matrix.level() << "." << std::endl
- << "2. Add them to any framework compatibility matrix with FCM "
- << "version >= " << matrix.level() << " where applicable." << std::endl
- << "3. Add them to DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE "
- << "or DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE." << std::endl;
-
- return false;
- }
- }
return true;
}
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 1f1c0f4..6d86682 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -23,6 +23,7 @@
#include <mutex>
#include <android-base/logging.h>
+#include <android-base/result.h>
#include <android-base/strings.h>
#include "CompatibilityMatrix.h"
@@ -805,6 +806,55 @@
return mRuntimeInfoFactory;
}
+android::base::Result<bool> VintfObject::hasFrameworkCompatibilityMatrixExtensions() {
+ std::vector<Named<CompatibilityMatrix>> matrixFragments;
+ std::string error;
+ status_t status = getAllFrameworkMatrixLevels(&matrixFragments, &error);
+ if (status != OK) {
+ return android::base::Error(-status)
+ << "Cannot get all framework matrix fragments: " << error;
+ }
+ for (const auto& namedMatrix : matrixFragments) {
+ // Returns true if product matrix exists.
+ if (android::base::StartsWith(namedMatrix.name, kProductVintfDir)) {
+ return true;
+ }
+ // Returns true if device system matrix exists.
+ if (android::base::StartsWith(namedMatrix.name, kSystemVintfDir) &&
+ namedMatrix.object.level() == Level::UNSPECIFIED &&
+ !namedMatrix.object.getHals().empty()) {
+ return true;
+ }
+ }
+ return false;
+}
+
+android::base::Result<void> VintfObject::checkUnusedHals() {
+ auto matrix = getFrameworkCompatibilityMatrix();
+ if (matrix == nullptr) {
+ return android::base::Error(-NAME_NOT_FOUND) << "Missing framework matrix.";
+ }
+ auto manifest = getDeviceHalManifest();
+ if (manifest == nullptr) {
+ return android::base::Error(-NAME_NOT_FOUND) << "Missing device manifest.";
+ }
+ auto unused = manifest->checkUnusedHals(*matrix);
+ if (!unused.empty()) {
+ return android::base::Error()
+ << "The following instances are in the device manifest but "
+ << "not specified in framework compatibility matrix: \n"
+ << " " << android::base::Join(unused, "\n ") << "\n"
+ << "Suggested fix:\n"
+ << "1. Check for any typos in device manifest or framework compatibility "
+ << "matrices with FCM version >= " << matrix->level() << ".\n"
+ << "2. Add them to any framework compatibility matrix with FCM "
+ << "version >= " << matrix->level() << " where applicable.\n"
+ << "3. Add them to DEVICE_FRAMEWORK_COMPATIBILITY_MATRIX_FILE "
+ << "or DEVICE_PRODUCT_COMPATIBILITY_MATRIX_FILE.";
+ }
+ return {};
+}
+
// make_unique does not work because VintfObject constructor is private.
VintfObject::Builder::Builder() : mObject(std::unique_ptr<VintfObject>(new VintfObject())) {}
diff --git a/assemble_vintf_main.cpp b/assemble_vintf_main.cpp
index b25a477..d74cc03 100644
--- a/assemble_vintf_main.cpp
+++ b/assemble_vintf_main.cpp
@@ -49,7 +49,6 @@
" After writing the output file, the program checks against\n"
" the \"check file\", depending on environment variables.\n"
" - PRODUCT_ENFORCE_VINTF_MANIFEST=true: check compatibility\n"
- " - VINTF_ENFORCE_NO_UNUSED_HALS =true: check unused HALs\n"
" If any check fails, an error message is written to stderr.\n"
" Return 1.\n"
" --kernel=<version>:<android-base.config>[:<android-base-arch.config>[...]]\n"
diff --git a/check_vintf.cpp b/check_vintf.cpp
index d4dc3bc..17e32df 100644
--- a/check_vintf.cpp
+++ b/check_vintf.cpp
@@ -24,6 +24,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
+#include <android-base/result.h>
#include <android-base/strings.h>
#include <utils/Errors.h>
#include <vintf/KernelConfigParser.h>
@@ -345,8 +346,8 @@
return EX_USAGE;
}
-int checkAllFiles(const Dirmap& dirmap, const Properties& props,
- std::shared_ptr<StaticRuntimeInfo> runtimeInfo, std::string* error) {
+android::base::Result<void> checkAllFiles(const Dirmap& dirmap, const Properties& props,
+ std::shared_ptr<StaticRuntimeInfo> runtimeInfo) {
auto hostPropertyFetcher = std::make_unique<PresetPropertyFetcher>();
hostPropertyFetcher->setProperties(props);
@@ -359,7 +360,25 @@
.setPropertyFetcher(std::move(hostPropertyFetcher))
.setRuntimeInfoFactory(std::make_unique<StaticRuntimeInfoFactory>(runtimeInfo))
.build();
- return vintfObject->checkCompatibility(error, flags);
+
+ std::string error;
+ int compatibleResult = vintfObject->checkCompatibility(&error, flags);
+ if (compatibleResult == INCOMPATIBLE) {
+ return android::base::Error() << error;
+ }
+ if (compatibleResult != COMPATIBLE) {
+ return android::base::Error(-compatibleResult) << error;
+ }
+
+ auto hasFcmExt = vintfObject->hasFrameworkCompatibilityMatrixExtensions();
+ if (!hasFcmExt.has_value()) {
+ return hasFcmExt.error();
+ }
+ if (*hasFcmExt) {
+ return vintfObject->checkUnusedHals();
+ }
+ LOG(INFO) << "Skip checking unused HALs.";
+ return {};
}
int checkDirmaps(const Dirmap& dirmap) {
@@ -469,23 +488,22 @@
}
}
- std::string error;
if (dirmap.empty()) {
LOG(ERROR) << "Missing --rootdir or --dirmap option.";
return usage(argv[0]);
}
- int compat = checkAllFiles(dirmap, properties, runtimeInfo, &error);
+ auto compat = checkAllFiles(dirmap, properties, runtimeInfo);
- if (compat == COMPATIBLE) {
+ if (compat.ok()) {
std::cout << "COMPATIBLE" << std::endl;
return EX_OK;
}
- if (compat == INCOMPATIBLE) {
- LOG(ERROR) << "files are incompatible: " << error;
+ if (compat.error().code() == 0) {
+ LOG(ERROR) << "files are incompatible: " << compat.error();
std::cout << "INCOMPATIBLE" << std::endl;
return EX_DATAERR;
}
- LOG(ERROR) << strerror(-compat) << ": " << error;
+ LOG(ERROR) << strerror(compat.error().code()) << ": " << compat.error();
return EX_SOFTWARE;
}
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index ea48676..30d31bb 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -20,6 +20,8 @@
#include <memory>
#include <optional>
+#include <android-base/result.h>
+
#include "CheckFlags.h"
#include "CompatibilityMatrix.h"
#include "FileSystem.h"
@@ -184,6 +186,34 @@
*/
Level getKernelLevel(std::string* error = nullptr);
+ /**
+ * Returns true if the framework compatibility matrix has extensions. In
+ * other words, returns true if any of the following exists on the device:
+ * - device framework compatibility matrix
+ * - product framework compatibility matrix
+ *
+ * Return result:
+ * - true if framework compatibility matrix has extensions
+ * - false if framework compatibility
+ * matrix does not have extensions.
+ * - !result.has_value() if any error. Check
+ * result.error() for detailed message.
+ */
+ android::base::Result<bool> hasFrameworkCompatibilityMatrixExtensions();
+
+ /**
+ * Check that there are no unused HALs in HAL manifests. Currently, only
+ * device manifest is checked against framework compatibility matrix.
+ *
+ * Return result:
+ * - result.ok() if no unused HALs
+ * - !result.ok() && result.error().code() == 0 if with unused HALs. Check
+ * result.error() for detailed message.
+ * - !result.ok() && result.error().code() != 0 if any error. Check
+ * result.error() for detailed message.
+ */
+ android::base::Result<void> checkUnusedHals();
+
private:
std::unique_ptr<FileSystem> mFileSystem;
std::unique_ptr<ObjectFactory<RuntimeInfo>> mRuntimeInfoFactory;
@@ -306,7 +336,6 @@
std::string* error = nullptr);
status_t fetchVendorHalManifest(HalManifest* out, std::string* error = nullptr);
status_t fetchFrameworkHalManifest(HalManifest* out, std::string* error = nullptr);
-
static bool IsHalDeprecated(const MatrixHal& oldMatrixHal,
const CompatibilityMatrix& targetMatrix,
const ListInstances& listInstances, std::string* error);