Add device/fwk compatibility matrix to VintfObject.
For framework compatibility matrix, <sepolicy> sections
is injected in build time.
Test: libvintf_test
Test: adb shell vintf; matrices exist, compatible = true
Bug: 37321309
Bug: 36814503
Change-Id: I997b93456a261f0cdb85997ae88f4ac5a5f36ff3
Merged-In: I997b93456a261f0cdb85997ae88f4ac5a5f36ff3
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index 1f95ada..379fd78 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -16,6 +16,8 @@
#include "CompatibilityMatrix.h"
+#include "utils.h"
+
namespace android {
namespace vintf {
@@ -63,6 +65,11 @@
return mType;
}
+
+status_t CompatibilityMatrix::fetchAllInformation(const std::string &path) {
+ return details::fetchAllInformation(path, gCompatibilityMatrixConverter, this);
+}
+
bool operator==(const CompatibilityMatrix &lft, const CompatibilityMatrix &rgt) {
return lft.mType == rgt.mType &&
lft.mHals == rgt.mHals &&
diff --git a/HalManifest.cpp b/HalManifest.cpp
index 6197ceb..daf35a5 100644
--- a/HalManifest.cpp
+++ b/HalManifest.cpp
@@ -19,16 +19,13 @@
#include "HalManifest.h"
#include <dirent.h>
-
-#include <fstream>
-#include <iostream>
-#include <sstream>
#include <mutex>
#include <android-base/logging.h>
#include "parse_string.h"
#include "parse_xml.h"
+#include "utils.h"
#include "CompatibilityMatrix.h"
namespace android {
@@ -286,21 +283,7 @@
}
status_t HalManifest::fetchAllInformation(const std::string &path) {
- std::ifstream in;
- in.open(path);
- if (!in.is_open()) {
- LOG(WARNING) << "Cannot open " << path;
- return INVALID_OPERATION;
- }
- std::stringstream ss;
- ss << in.rdbuf();
- bool success = gHalManifestConverter(this, ss.str());
- if (!success) {
- LOG(ERROR) << "Illformed vendor manifest: " << path << ": "
- << gHalManifestConverter.lastError();
- return BAD_VALUE;
- }
- return OK;
+ return details::fetchAllInformation(path, gHalManifestConverter, this);
}
SchemaType HalManifest::type() const {
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 674031a..1ef6edc 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -34,6 +34,8 @@
static LockedUniquePtr<HalManifest> gDeviceManifest;
static LockedUniquePtr<HalManifest> gFrameworkManifest;
+static LockedUniquePtr<CompatibilityMatrix> gDeviceMatrix;
+static LockedUniquePtr<CompatibilityMatrix> gFrameworkMatrix;
static LockedUniquePtr<RuntimeInfo> gDeviceRuntimeInfo;
template <typename T, typename F>
@@ -65,6 +67,21 @@
"/system/manifest.xml"));
}
+
+// static
+const CompatibilityMatrix *VintfObject::GetDeviceCompatibilityMatrix(bool skipCache) {
+ return Get(&gDeviceMatrix, skipCache,
+ std::bind(&CompatibilityMatrix::fetchAllInformation, std::placeholders::_1,
+ "/vendor/compatibility_matrix.xml"));
+}
+
+// static
+const CompatibilityMatrix *VintfObject::GetFrameworkCompatibilityMatrix(bool skipCache) {
+ return Get(&gFrameworkMatrix, skipCache,
+ std::bind(&CompatibilityMatrix::fetchAllInformation, std::placeholders::_1,
+ "/system/compatibility_matrix.xml"));
+}
+
// static
const RuntimeInfo *VintfObject::GetRuntimeInfo(bool skipCache) {
return Get(&gDeviceRuntimeInfo, skipCache,
diff --git a/assemble_vintf.cpp b/assemble_vintf.cpp
index b2b0ed1..663b864 100644
--- a/assemble_vintf.cpp
+++ b/assemble_vintf.cpp
@@ -88,7 +88,18 @@
CompatibilityMatrix matrix;
if (gCompatibilityMatrixConverter(&matrix, fileContent)) {
- // TODO (b/37342627): get BOARD_VNDK_VERSION and put it here.
+ KernelSepolicyVersion kernelSepolicyVers;
+ Version sepolicyVers;
+ if (matrix.mType == SchemaType::FRAMEWORK) {
+ if (!getFlag("BOARD_SEPOLICY_VERS", &sepolicyVers)) {
+ return false;
+ }
+ if (!getFlag("POLICYVERS", &kernelSepolicyVers)) {
+ return false;
+ }
+ matrix.framework.mSepolicy = Sepolicy(kernelSepolicyVers,
+ {{sepolicyVers.majorVer,sepolicyVers.minorVer}});
+ }
outFile << gCompatibilityMatrixConverter(matrix);
outFile.flush();
return true;
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 4e86f51..30344dd 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -20,6 +20,8 @@
#include <map>
#include <string>
+#include <utils/Errors.h>
+
#include "MatrixHal.h"
#include "MatrixKernel.h"
#include "MapValueIterator.h"
@@ -54,10 +56,14 @@
// for constructing matrix programitically only.
MatrixHal *getAnyHal(const std::string &name);
+ status_t fetchAllInformation(const std::string &path);
+
friend struct HalManifest;
friend struct RuntimeInfo;
friend struct CompatibilityMatrixConverter;
friend struct LibVintfTest;
+ friend class VintfObject;
+ friend class AssembleVintf;
friend bool operator==(const CompatibilityMatrix &, const CompatibilityMatrix &);
SchemaType mType;
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index 157d00b..4f84a51 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -17,6 +17,7 @@
#ifndef ANDROID_VINTF_VINTF_OBJECT_H_
#define ANDROID_VINTF_VINTF_OBJECT_H_
+#include "CompatibilityMatrix.h"
#include "HalManifest.h"
#include "RuntimeInfo.h"
@@ -61,6 +62,18 @@
static const HalManifest *GetFrameworkHalManifest(bool skipCache = false);
/*
+ * Return the API that access the device-side compatibility matrix stored
+ * in /vendor/compatibility_matrix.xml.
+ */
+ static const CompatibilityMatrix *GetDeviceCompatibilityMatrix(bool skipCache = false);
+
+ /*
+ * Return the API that access the device-side compatibility matrix stored
+ * in /system/compatibility_matrix.xml.
+ */
+ static const CompatibilityMatrix *GetFrameworkCompatibilityMatrix(bool skipCache = false);
+
+ /*
* Return the API that access device runtime info.
*/
static const RuntimeInfo *GetRuntimeInfo(bool skipCache = false);
diff --git a/main.cpp b/main.cpp
index 25a8cc6..0437a64 100644
--- a/main.cpp
+++ b/main.cpp
@@ -19,18 +19,59 @@
#include <vintf/parse_string.h>
#include <vintf/VintfObject.h>
+// A convenience binary to dump information available through libvintf.
int main(int, char **) {
using namespace ::android::vintf;
+ std::cout << "======== Device HAL Manifest =========" << std::endl;
+
const HalManifest *vm = VintfObject::GetDeviceHalManifest();
if (vm != nullptr)
std::cout << gHalManifestConverter(*vm);
+ std::cout << "======== Framework HAL Manifest =========" << std::endl;
+
const HalManifest *fm = VintfObject::GetFrameworkHalManifest();
if (fm != nullptr)
std::cout << gHalManifestConverter(*fm);
- std::cout << std::endl;
+ std::cout << "======== Device Compatibility Matrix =========" << std::endl;
+
+ const CompatibilityMatrix *vcm = VintfObject::GetDeviceCompatibilityMatrix();
+ if (vcm != nullptr)
+ std::cout << gCompatibilityMatrixConverter(*vcm);
+
+ std::cout << "======== Framework Compatibility Matrix =========" << std::endl;
+
+ const CompatibilityMatrix *fcm = VintfObject::GetFrameworkCompatibilityMatrix();
+ if (fcm != nullptr)
+ std::cout << gCompatibilityMatrixConverter(*fcm);
+
+ std::cout << "======== Compatibility check =========" << std::endl;
+ std::cout << "Device HAL Manifest? " << (vm != nullptr) << std::endl
+ << "Device Compatibility Matrix? " << (vcm != nullptr) << std::endl
+ << "Framework HAL Manifest? " << (fm != nullptr) << std::endl
+ << "Framework Compatibility Matrix? " << (fcm != nullptr) << std::endl;
+ std::string error;
+ if (vm && fcm) {
+ bool compatible = vm->checkCompatibility(*fcm, &error);
+ std::cout << "Device HAL Manifest <==> Framework Compatibility Matrix? "
+ << compatible;
+ if (!compatible)
+ std::cout << ", " << error;
+ std::cout << std::endl;
+ }
+ if (fm && vcm) {
+ bool compatible = fm->checkCompatibility(*vcm, &error);
+ std::cout << "Framework HAL Manifest <==> Device Compatibility Matrix? "
+ << compatible;
+ if (!compatible)
+ std::cout << ", " << error;
+ std::cout << std::endl;
+ }
+
+ std::cout << "======== Runtime Info =========" << std::endl;
+
const RuntimeInfo *ki = VintfObject::GetRuntimeInfo();
if (ki != nullptr)
std::cout << dump(*ki);
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 1502011..9f144f4 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -684,8 +684,10 @@
}
if (object->mType == SchemaType::FRAMEWORK) {
+ // <avb> and <sepolicy> can be missing because it can be determined at build time, not
+ // hard-coded in the XML file.
if (!parseChildren(root, matrixKernelConverter, &object->framework.mKernels) ||
- !parseChild(root, sepolicyConverter, &object->framework.mSepolicy) ||
+ !parseOptionalChild(root, sepolicyConverter, {}, &object->framework.mSepolicy) ||
!parseOptionalChild(root, avbConverter, {}, &object->framework.mAvbMetaVersion)) {
return false;
}
diff --git a/utils.h b/utils.h
new file mode 100644
index 0000000..3c06817
--- /dev/null
+++ b/utils.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VINTF_UTILS_H
+#define ANDROID_VINTF_UTILS_H
+
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include <android-base/logging.h>
+#include <utils/Errors.h>
+
+#include "parse_xml.h"
+
+namespace android {
+namespace vintf {
+namespace details {
+
+template<typename T>
+status_t fetchAllInformation(const std::string &path,
+ const XmlConverter<T> &converter, T *outObject) {
+ std::ifstream in;
+ in.open(path);
+ if (!in.is_open()) {
+ LOG(WARNING) << "Cannot open " << path;
+ return INVALID_OPERATION;
+ }
+ std::stringstream ss;
+ ss << in.rdbuf();
+ bool success = converter(outObject, ss.str());
+ if (!success) {
+ LOG(ERROR) << "Illformed file: " << path << ": "
+ << converter.lastError();
+ return BAD_VALUE;
+ }
+ return OK;
+}
+
+} // namespace details
+} // namespace vintf
+} // namespace android
+
+
+
+#endif