Add manifest/compatibility-matrix.type attribute
to distinguish device and framework HAL manifest, and
device and framework compatibility matrix.
Add .device / .framework entries to HalManifest and
CompatibilityMatrix class for device-only / fwk-only
entries. Access to these fields should be guarded with
a check to mType.
Test: libvintf_test
Test: boots
Change-Id: Id9c93c1e6bb585234a9ae6d9296f5a10582ef58f
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp
index aba4efc..f27a019 100644
--- a/CompatibilityMatrix.cpp
+++ b/CompatibilityMatrix.cpp
@@ -26,13 +26,16 @@
}
bool CompatibilityMatrix::add(MatrixKernel &&kernel) {
- mKernels.push_back(std::move(kernel));
+ if (mType != SchemaType::FRAMEWORK) {
+ return false;
+ }
+ framework.mKernels.push_back(std::move(kernel));
return true;
}
void CompatibilityMatrix::clear() {
mHals.clear();
- mKernels.clear();
+ framework.mKernels.clear();
}
ConstMapValueIterable<std::string, MatrixHal> CompatibilityMatrix::getHals() const {
@@ -40,7 +43,10 @@
}
const MatrixKernel *CompatibilityMatrix::findKernel(const KernelVersion &v) const {
- for (const MatrixKernel &matrixKernel : mKernels) {
+ if (mType != SchemaType::FRAMEWORK) {
+ return nullptr;
+ }
+ for (const MatrixKernel &matrixKernel : framework.mKernels) {
if (matrixKernel.minLts().version == v.version &&
matrixKernel.minLts().majorRev == v.majorRev) {
return matrixKernel.minLts().minorRev <= v.minorRev ? &matrixKernel : nullptr;
diff --git a/RuntimeInfo.cpp b/RuntimeInfo.cpp
index 6b09a7c..c14ea95 100644
--- a/RuntimeInfo.cpp
+++ b/RuntimeInfo.cpp
@@ -242,10 +242,17 @@
bool RuntimeInfo::checkCompatibility(const CompatibilityMatrix &mat,
std::string *error) const {
- if (kernelSepolicyVersion() != mat.mSepolicy.kernelSepolicyVersion()) {
+ if (mat.mType != SchemaType::FRAMEWORK) {
+ if (error != nullptr) {
+ *error = "Should not check runtime info against " + to_string(mat.mType)
+ + " compatibility matrix.";
+ }
+ return false;
+ }
+ if (kernelSepolicyVersion() != mat.framework.mSepolicy.kernelSepolicyVersion()) {
if (error != nullptr) {
*error = "kernelSepolicyVersion = " + to_string(kernelSepolicyVersion())
- + " but required " + to_string(mat.mSepolicy.kernelSepolicyVersion());
+ + " but required " + to_string(mat.framework.mSepolicy.kernelSepolicyVersion());
}
return false;
}
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 515c2b8..007471a 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -24,12 +24,17 @@
#include "MatrixKernel.h"
#include "MapValueIterator.h"
#include "Sepolicy.h"
+#include "SchemaType.h"
namespace android {
namespace vintf {
// Compatibility matrix defines what hardware does the framework requires.
struct CompatibilityMatrix {
+
+ // Create a framework compatibility matrix.
+ CompatibilityMatrix() : mType(SchemaType::FRAMEWORK) {};
+
constexpr static Version kVersion{1, 0};
private:
@@ -49,12 +54,16 @@
friend struct CompatibilityMatrixConverter;
friend struct LibVintfTest;
+ SchemaType mType;
+
// sorted map from component name to the entry.
std::map<std::string, MatrixHal> mHals;
- std::vector<MatrixKernel> mKernels;
-
- Sepolicy mSepolicy;
+ // entries only for framework compatibility matrix.
+ struct {
+ std::vector<MatrixKernel> mKernels;
+ Sepolicy mSepolicy;
+ } framework;
};
} // namespace vintf
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index 91a2e08..a260d00 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -25,6 +25,7 @@
#include "ManifestHal.h"
#include "MapValueIterator.h"
+#include "SchemaType.h"
#include "Version.h"
namespace android {
@@ -40,7 +41,8 @@
// manifest.version
constexpr static Version kVersion{1, 0};
- HalManifest() {}
+ // Construct a device HAL manifest.
+ HalManifest() : mType(SchemaType::DEVICE) {}
// Given a component name (e.g. "android.hardware.camera"),
// return getHal(name)->transport if the component exist and v exactly matches
@@ -91,6 +93,7 @@
private:
friend struct HalManifestConverter;
friend class VintfObject;
+ friend class AssembleVintf;
friend struct LibVintfTest;
friend std::string dump(const HalManifest &vm);
@@ -103,9 +106,15 @@
status_t fetchAllInformation(const std::string &path);
+ SchemaType mType;
+
// sorted map from component name to the component.
// The component name looks like: android.hardware.foo
std::map<std::string, ManifestHal> mHals;
+
+ // entries for device hal manifest only
+ struct {
+ } device;
};
diff --git a/include/vintf/SchemaType.h b/include/vintf/SchemaType.h
new file mode 100644
index 0000000..4254957
--- /dev/null
+++ b/include/vintf/SchemaType.h
@@ -0,0 +1,42 @@
+/*
+ * 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_MANIFEST_TYPE_H
+#define ANDROID_VINTF_MANIFEST_TYPE_H
+
+#include <stdint.h>
+#include <string>
+#include <array>
+
+namespace android {
+namespace vintf {
+
+enum class SchemaType : size_t {
+ DEVICE = 0,
+ FRAMEWORK,
+};
+
+static const std::array<std::string, 2> gSchemaTypeStrings = {
+ {
+ "device",
+ "framework",
+ }
+};
+
+} // namespace vintf
+} // namespace android
+
+#endif // ANDROID_VINTF_MANIFEST_TYPE_H
diff --git a/include/vintf/parse_string.h b/include/vintf/parse_string.h
index 8c81de4..15775e4 100644
--- a/include/vintf/parse_string.h
+++ b/include/vintf/parse_string.h
@@ -33,7 +33,8 @@
std::ostream &operator<<(std::ostream &os, Arch ar);
std::ostream &operator<<(std::ostream &os, KernelConfigType il);
std::ostream &operator<<(std::ostream &os, Tristate tr);
-std::ostream &operator<<(std::ostream &os, KernelSepolicyVersion ksv);
+std::ostream &operator<<(std::ostream &os, SchemaType ksv);
+std::ostream &operator<<(std::ostream &os, const ManifestHal &hal);
std::ostream &operator<<(std::ostream &os, const Version &ver);
std::ostream &operator<<(std::ostream &os, const VersionRange &vr);
std::ostream &operator<<(std::ostream &os, const KernelVersion &ver);
@@ -56,6 +57,7 @@
bool parse(const std::string &s, KernelConfigType *il);
bool parse(const std::string &s, KernelConfigKey *key);
bool parse(const std::string &s, Tristate *tr);
+bool parse(const std::string &s, SchemaType *ver);
bool parse(const std::string &s, KernelSepolicyVersion *ksv);
bool parse(const std::string &s, Version *ver);
bool parse(const std::string &s, VersionRange *vr);
diff --git a/parse_string.cpp b/parse_string.cpp
index cec3adf..20daad9 100644
--- a/parse_string.cpp
+++ b/parse_string.cpp
@@ -96,6 +96,7 @@
DEFINE_PARSE_STREAMIN_FOR_ENUM(Arch);
DEFINE_PARSE_STREAMIN_FOR_ENUM(KernelConfigType);
DEFINE_PARSE_STREAMIN_FOR_ENUM(Tristate);
+DEFINE_PARSE_STREAMIN_FOR_ENUM(SchemaType);
std::ostream &operator<<(std::ostream &os, const KernelConfigTypedValue &kctv) {
switch (kctv.mType) {
diff --git a/parse_xml.cpp b/parse_xml.cpp
index f52f849..7500797 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -543,11 +543,19 @@
std::string elementName() const override { return "manifest"; }
void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override {
appendAttr(root, "version", HalManifest::kVersion);
+ appendAttr(root, "type", m.mType);
appendChildren(root, manifestHalConverter, m.getHals(), d);
}
bool buildObject(HalManifest *object, NodeType *root) const override {
+ Version version;
std::vector<ManifestHal> hals;
- if (!parseChildren(root, manifestHalConverter, &hals)) {
+ if (!parseAttr(root, "version", &version) ||
+ !parseAttr(root, "type", &object->mType) ||
+ !parseChildren(root, manifestHalConverter, &hals)) {
+ return false;
+ }
+ if (version != HalManifest::kVersion) {
+ this->mLastError = "Unrecognized manifest.version";
return false;
}
for (auto &&hal : hals) {
@@ -566,15 +574,31 @@
std::string elementName() const override { return "compatibility-matrix"; }
void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override {
appendAttr(root, "version", CompatibilityMatrix::kVersion);
+ appendAttr(root, "type", m.mType);
appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d);
- appendChildren(root, matrixKernelConverter, m.mKernels, d);
- appendChild(root, sepolicyConverter(m.mSepolicy, d));
+ if (m.mType == SchemaType::FRAMEWORK) {
+ appendChildren(root, matrixKernelConverter, m.framework.mKernels, d);
+ appendChild(root, sepolicyConverter(m.framework.mSepolicy, d));
+ }
}
bool buildObject(CompatibilityMatrix *object, NodeType *root) const override {
+ Version version;
std::vector<MatrixHal> hals;
- if (!parseChildren(root, matrixHalConverter, &hals) ||
- !parseChildren(root, matrixKernelConverter, &object->mKernels) ||
- !parseChild(root, sepolicyConverter, &object->mSepolicy)) {
+ if (!parseAttr(root, "version", &version) ||
+ !parseAttr(root, "type", &object->mType) ||
+ !parseChildren(root, matrixHalConverter, &hals)) {
+ return false;
+ }
+
+ if (object->mType == SchemaType::FRAMEWORK) {
+ if (!parseChildren(root, matrixKernelConverter, &object->framework.mKernels) ||
+ !parseChild(root, sepolicyConverter, &object->framework.mSepolicy)) {
+ return false;
+ }
+ }
+
+ if (version != CompatibilityMatrix::kVersion) {
+ this->mLastError = "Unrecognized compatibility-matrix.version";
return false;
}
for (auto &&hal : hals) {
diff --git a/test/main.cpp b/test/main.cpp
index 61b6bd9..582ac19 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -52,7 +52,7 @@
return vm.add(std::move(hal));
}
void set(CompatibilityMatrix &cm, Sepolicy &&sepolicy) {
- cm.mSepolicy = sepolicy;
+ cm.framework.mSepolicy = sepolicy;
}
const ManifestHal *getHal(HalManifest &vm, const std::string &name) {
return vm.getHal(name);
@@ -61,13 +61,14 @@
return vm.getHals();
}
bool isEqual(const CompatibilityMatrix &cm1, const CompatibilityMatrix &cm2) {
- return cm1.mHals == cm2.mHals && cm1.mKernels == cm2.mKernels;
+ return cm1.mHals == cm2.mHals && cm1.framework.mKernels == cm2.framework.mKernels;
}
bool isValid(const ManifestHal &mh) {
return mh.isValid();
}
HalManifest testHalManifest() {
HalManifest vm;
+ vm.mType = SchemaType::DEVICE;
vm.add(ManifestHal{
.format = HalFormat::HIDL,
.name = "android.hardware.camera",
@@ -130,7 +131,7 @@
HalManifest vm = testHalManifest();
std::string xml = gHalManifestConverter(vm);
EXPECT_EQ(xml,
- "<manifest version=\"1.0\">\n"
+ "<manifest version=\"1.0\" type=\"device\">\n"
" <hal format=\"hidl\">\n"
" <name>android.hardware.camera</name>\n"
" <transport>hwbinder</transport>\n"
@@ -160,9 +161,9 @@
TEST_F(LibVintfTest, HalManifestOptional) {
HalManifest vm;
EXPECT_TRUE(gHalManifestConverter(&vm,
- "<manifest version=\"1.0\"></manifest>"));
+ "<manifest version=\"1.0\" type=\"device\"></manifest>"));
EXPECT_TRUE(gHalManifestConverter(&vm,
- "<manifest version=\"1.0\">"
+ "<manifest version=\"1.0\" type=\"device\">"
" <hal>"
" <name>android.hidl.manager</name>"
" <transport>hwbinder</transport>"
@@ -170,7 +171,7 @@
" </hal>"
"</manifest>"));
EXPECT_FALSE(gHalManifestConverter(&vm,
- "<manifest version=\"1.0\">"
+ "<manifest version=\"1.0\" type=\"device\">"
" <hal>"
" <name>android.hidl.manager</name>"
" <version>1.0</version>"
@@ -325,7 +326,7 @@
set(cm, Sepolicy(30, {1, 3}));
std::string xml = gCompatibilityMatrixConverter(cm);
EXPECT_EQ(xml,
- "<compatibility-matrix version=\"1.0\">\n"
+ "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
" <hal format=\"native\" optional=\"false\">\n"
" <name>android.hardware.camera</name>\n"
" <version>1.2-3</version>\n"