Add <vndk> entry to framework manifest and device comp-mat.
Bug: 36400653
Test: libvintf_test
Change-Id: Ie727d4806ad74a72511354a901fca09ea9ae67c4
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h
index 007471a..262b4da 100644
--- a/include/vintf/CompatibilityMatrix.h
+++ b/include/vintf/CompatibilityMatrix.h
@@ -25,6 +25,7 @@
#include "MapValueIterator.h"
#include "Sepolicy.h"
#include "SchemaType.h"
+#include "Vndk.h"
namespace android {
namespace vintf {
@@ -64,6 +65,11 @@
std::vector<MatrixKernel> mKernels;
Sepolicy mSepolicy;
} framework;
+
+ // entries only for device compatibility matrix.
+ struct {
+ Vndk mVndk;
+ } device;
};
} // namespace vintf
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h
index 7618a1e..493936e 100644
--- a/include/vintf/HalManifest.h
+++ b/include/vintf/HalManifest.h
@@ -27,6 +27,7 @@
#include "MapValueIterator.h"
#include "SchemaType.h"
#include "Version.h"
+#include "Vndk.h"
namespace android {
namespace vintf {
@@ -116,6 +117,11 @@
struct {
Version mSepolicyVersion;
} device;
+
+ // entries for framework hal manifest only
+ struct {
+ std::vector<Vndk> mVndks;
+ } framework;
};
diff --git a/include/vintf/Vndk.h b/include/vintf/Vndk.h
new file mode 100644
index 0000000..3288b40
--- /dev/null
+++ b/include/vintf/Vndk.h
@@ -0,0 +1,56 @@
+/*
+ * 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_VNDK_H
+#define ANDROID_VINTF_VNDK_H
+
+#include <set>
+#include <string>
+
+namespace android {
+namespace vintf {
+
+struct VndkVersionRange {
+
+ VndkVersionRange() : VndkVersionRange(0u, 0u, 0u) {}
+ VndkVersionRange(size_t s, size_t v, size_t p)
+ : VndkVersionRange(s, v, p, p) {}
+ VndkVersionRange(size_t s, size_t v, size_t pi, size_t pa)
+ : sdk(s), vndk(v), patchMin(pi), patchMax(pa) {}
+
+ inline bool isSingleVersion() const { return patchMin == patchMax; };
+
+ size_t sdk;
+ size_t vndk;
+ size_t patchMin;
+ size_t patchMax;
+};
+
+struct Vndk {
+
+private:
+ friend struct VndkConverter;
+ friend struct HalManifestConverter;
+ friend struct LibVintfTest;
+ VndkVersionRange mVersionRange;
+ std::set<std::string> mLibraries;
+};
+
+} // namespace vintf
+} // namespace android
+
+#endif // ANDROID_VINTF_VNDK_H
diff --git a/include/vintf/parse_string.h b/include/vintf/parse_string.h
index 15775e4..d816908 100644
--- a/include/vintf/parse_string.h
+++ b/include/vintf/parse_string.h
@@ -37,6 +37,7 @@
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 VndkVersionRange &vr);
std::ostream &operator<<(std::ostream &os, const KernelVersion &ver);
std::ostream &operator<<(std::ostream &os, const TransportArch &ta);
std::ostream &operator<<(std::ostream &os, const ManifestHal &hal);
@@ -61,6 +62,7 @@
bool parse(const std::string &s, KernelSepolicyVersion *ksv);
bool parse(const std::string &s, Version *ver);
bool parse(const std::string &s, VersionRange *vr);
+bool parse(const std::string &s, VndkVersionRange *vr);
bool parse(const std::string &s, KernelVersion *ver);
// if return true, ta->isValid() must be true.
bool parse(const std::string &s, TransportArch *ta);
diff --git a/parse_string.cpp b/parse_string.cpp
index 20daad9..4c1e9a1 100644
--- a/parse_string.cpp
+++ b/parse_string.cpp
@@ -215,6 +215,36 @@
return os << vr.minVer() << "-" << vr.maxMinor;
}
+bool parse(const std::string &s, VndkVersionRange *vr) {
+ std::vector<std::string> v = SplitString(s, '-');
+ if (v.size() != 1 && v.size() != 2) {
+ return false;
+ }
+ std::vector<std::string> minVector = SplitString(v[0], '.');
+ if (minVector.size() != 3) {
+ return false;
+ }
+ if (!ParseUint(minVector[0], &vr->sdk) ||
+ !ParseUint(minVector[1], &vr->vndk) ||
+ !ParseUint(minVector[2], &vr->patchMin)) {
+ return false;
+ }
+ if (v.size() == 1) {
+ vr->patchMax = vr->patchMin;
+ return true;
+ } else {
+ return ParseUint(v[1], &vr->patchMax);
+ }
+}
+
+std::ostream &operator<<(std::ostream &os, const VndkVersionRange &vr) {
+ os << vr.sdk << "." << vr.vndk << "." << vr.patchMin;
+ if (!vr.isSingleVersion()) {
+ os << "-" << vr.patchMax;
+ }
+ return os;
+}
+
bool parse(const std::string &s, KernelVersion *kernelVersion) {
std::vector<std::string> v = SplitString(s, '.');
if (v.size() != 3) {
diff --git a/parse_xml.cpp b/parse_xml.cpp
index 1d2acbd..1435c4e 100644
--- a/parse_xml.cpp
+++ b/parse_xml.cpp
@@ -316,6 +316,23 @@
return true;
}
+ template <typename T>
+ inline bool parseChildren(NodeType *root, const XmlNodeConverter<T> &conv, std::set<T> *s) const {
+ std::vector<T> vec;
+ if (!parseChildren(root, conv, &vec)) {
+ return false;
+ }
+ s->clear();
+ s->insert(vec.begin(), vec.end());
+ if (s->size() != vec.size()) {
+ mLastError = "Duplicated elements <" + conv.elementName() + "> in element <"
+ + this->elementName() + ">";
+ s->clear();
+ return false;
+ }
+ return true;
+ }
+
inline bool parseText(NodeType *node, std::string *s) const {
*s = getText(node);
return true;
@@ -544,6 +561,26 @@
};
const SepolicyConverter sepolicyConverter{};
+const XmlTextConverter<VndkVersionRange> vndkVersionRangeConverter{"version"};
+const XmlTextConverter<std::string> vndkLibraryConverter{"library"};
+
+struct VndkConverter : public XmlNodeConverter<Vndk> {
+ std::string elementName() const override { return "vndk"; }
+ void mutateNode(const Vndk &object, NodeType *root, DocType *d) const override {
+ appendChild(root, vndkVersionRangeConverter(object.mVersionRange, d));
+ appendChildren(root, vndkLibraryConverter, object.mLibraries, d);
+ }
+ bool buildObject(Vndk *object, NodeType *root) const override {
+ if (!parseChild(root, vndkVersionRangeConverter, &object->mVersionRange) ||
+ !parseChildren(root, vndkLibraryConverter, &object->mLibraries)) {
+ return false;
+ }
+ return true;
+ }
+};
+
+const VndkConverter vndkConverter{};
+
struct HalManifestSepolicyConverter : public XmlNodeConverter<Version> {
std::string elementName() const override { return "sepolicy"; }
void mutateNode(const Version &m, NodeType *root, DocType *d) const override {
@@ -563,6 +600,8 @@
appendChildren(root, manifestHalConverter, m.getHals(), d);
if (m.mType == SchemaType::DEVICE) {
appendChild(root, halManifestSepolicyConverter(m.device.mSepolicyVersion, d));
+ } else if (m.mType == SchemaType::FRAMEWORK) {
+ appendChildren(root, vndkConverter, m.framework.mVndks, d);
}
}
bool buildObject(HalManifest *object, NodeType *root) const override {
@@ -584,6 +623,17 @@
&object->device.mSepolicyVersion)) {
return false;
}
+ } else if (object->mType == SchemaType::FRAMEWORK) {
+ if (!parseChildren(root, vndkConverter, &object->framework.mVndks)) {
+ return false;
+ }
+ for (const auto &vndk : object->framework.mVndks) {
+ if (!vndk.mVersionRange.isSingleVersion()) {
+ this->mLastError = "vndk.version " + to_string(vndk.mVersionRange)
+ + " cannot be a range for manifests";
+ return false;
+ }
+ }
}
for (auto &&hal : hals) {
if (!object->add(std::move(hal))) {
@@ -622,6 +672,10 @@
!parseChild(root, sepolicyConverter, &object->framework.mSepolicy)) {
return false;
}
+ } else if (object->mType == SchemaType::DEVICE) {
+ if (!parseChild(root, vndkConverter, &object->device.mVndk)) {
+ return false;
+ }
}
if (version != CompatibilityMatrix::kVersion) {
diff --git a/test/main.cpp b/test/main.cpp
index f73c2db..0a636c8 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -66,7 +66,7 @@
bool isValid(const ManifestHal &mh) {
return mh.isValid();
}
- HalManifest testHalManifest() {
+ HalManifest testDeviceManifest() {
HalManifest vm;
vm.mType = SchemaType::DEVICE;
vm.device.mSepolicyVersion = {25, 0};
@@ -92,6 +92,28 @@
return vm;
}
+ HalManifest testFrameworkManfiest() {
+ HalManifest vm;
+ vm.mType = SchemaType::FRAMEWORK;
+ vm.add(ManifestHal{
+ .format = HalFormat::HIDL,
+ .name = "android.hidl.manager",
+ .versions = {Version(1, 0)},
+ .transportArch = {Transport::HWBINDER, Arch::ARCH_EMPTY},
+ .interfaces = {
+ {"IServiceManager", {"IServiceManager", {"default"}}},
+ }
+ });
+ Vndk vndk2505;
+ vndk2505.mVersionRange = {25, 0, 5};
+ vndk2505.mLibraries = { "libjpeg.so", "libbase.so" };
+ Vndk vndk2513;
+ vndk2513.mVersionRange = {25, 1, 3};
+ vndk2513.mLibraries = { "libjpeg.so", "libbase.so", "libtinyxml2.so" };
+ vm.framework.mVndks = { std::move(vndk2505), std::move(vndk2513) };
+
+ return vm;
+ }
RuntimeInfo testRuntimeInfo() {
RuntimeInfo info;
info.mOsName = "Linux";
@@ -114,7 +136,7 @@
TEST_F(LibVintfTest, Stringify) {
- HalManifest vm = testHalManifest();
+ HalManifest vm = testDeviceManifest();
EXPECT_EQ(dump(vm), "hidl/android.hardware.camera/hwbinder/2.0:"
"hidl/android.hardware.nfc/passthrough32+64/1.0");
@@ -129,7 +151,7 @@
}
TEST_F(LibVintfTest, HalManifestConverter) {
- HalManifest vm = testHalManifest();
+ HalManifest vm = testDeviceManifest();
std::string xml = gHalManifestConverter(vm);
EXPECT_EQ(xml,
"<manifest version=\"1.0\" type=\"device\">\n"
@@ -162,6 +184,36 @@
"</manifest>\n");
}
+TEST_F(LibVintfTest, HalManifestConverterFramework) {
+ HalManifest vm = testFrameworkManfiest();
+ std::string xml = gHalManifestConverter(vm);
+ EXPECT_EQ(xml,
+ "<manifest version=\"1.0\" type=\"framework\">\n"
+ " <hal format=\"hidl\">\n"
+ " <name>android.hidl.manager</name>\n"
+ " <transport>hwbinder</transport>\n"
+ " <version>1.0</version>\n"
+ " <interface>\n"
+ " <name>IServiceManager</name>\n"
+ " <instance>default</instance>\n"
+ " </interface>\n"
+ " </hal>\n"
+ " <vndk>\n"
+ " <version>25.0.5</version>\n"
+ " <library>libbase.so</library>\n"
+ " <library>libjpeg.so</library>\n"
+ " </vndk>\n"
+ " <vndk>\n"
+ " <version>25.1.3</version>\n"
+ " <library>libbase.so</library>\n"
+ " <library>libjpeg.so</library>\n"
+ " <library>libtinyxml2.so</library>\n"
+ " </vndk>\n"
+ "</manifest>\n");
+ HalManifest vm2;
+ EXPECT_TRUE(gHalManifestConverter(&vm2, xml));
+}
+
TEST_F(LibVintfTest, HalManifestOptional) {
HalManifest vm;
EXPECT_TRUE(gHalManifestConverter(&vm,
@@ -184,7 +236,7 @@
}
TEST_F(LibVintfTest, HalManifestInstances) {
- HalManifest vm = testHalManifest();
+ HalManifest vm = testDeviceManifest();
EXPECT_EQ(vm.getInstances("android.hardware.camera", "ICamera"),
std::set<std::string>({"default", "legacy/0"}));
EXPECT_EQ(vm.getInstances("android.hardware.camera", "IBetterCamera"),
@@ -387,13 +439,13 @@
}
TEST_F(LibVintfTest, HalManifestGetHalNames) {
- HalManifest vm = testHalManifest();
+ HalManifest vm = testDeviceManifest();
EXPECT_EQ(vm.getHalNames(), std::set<std::string>(
{"android.hardware.camera", "android.hardware.nfc"}));
}
TEST_F(LibVintfTest, HalManifestGetInterfaceNames) {
- HalManifest vm = testHalManifest();
+ HalManifest vm = testDeviceManifest();
EXPECT_EQ(vm.getInterfaceNames("android.hardware.camera"),
std::set<std::string>({"ICamera", "IBetterCamera"}));
EXPECT_EQ(vm.getInterfaceNames("android.hardware.nfc"),
@@ -401,7 +453,7 @@
}
TEST_F(LibVintfTest, HalManifestGetHal) {
- HalManifest vm = testHalManifest();
+ HalManifest vm = testDeviceManifest();
EXPECT_NE(getHal(vm, "android.hardware.camera"), nullptr);
EXPECT_EQ(getHal(vm, "non-existent"), nullptr);