diff options
author | Yifan Hong | 2017-12-11 17:21:19 -0600 |
---|---|---|
committer | Yifan Hong | 2017-12-14 17:33:59 -0600 |
commit | 2027a49ab65dd24876d30a308beb1500d5123673 (patch) | |
tree | 7e85ce0af2c13c9ff29e678c8b7faed912152047 | |
parent | 405270cfed22533d38a3885cf8c6d9219182b069 (diff) | |
download | platform-system-libvintf-2027a49ab65dd24876d30a308beb1500d5123673.tar.gz platform-system-libvintf-2027a49ab65dd24876d30a308beb1500d5123673.tar.xz platform-system-libvintf-2027a49ab65dd24876d30a308beb1500d5123673.zip |
Implement FCM Version in matrices / manifests.
"level" is an attribute on compatibility matrices / manifests
to specify the FCM Version they declare / implement. Value can
be "legacy" or a positive number, or empty (for old files).
Test: libvintf_test
Test: Built manifests / matrices has not changed (because
value is "unspecified").
Bug: 69854976 device manfiest must specify FCM Version
Bug: 69636193 all matrices should be installed to system image
Bug: 64720381 deprecation schedule
Change-Id: I15d34343fae4ad79d86bd50e9de8c4f6ac09fdfd
Merged-In: I15d34343fae4ad79d86bd50e9de8c4f6ac09fdfd
-rw-r--r-- | CompatibilityMatrix.cpp | 7 | ||||
-rw-r--r-- | HalManifest.cpp | 7 | ||||
-rw-r--r-- | include/vintf/CompatibilityMatrix.h | 3 | ||||
-rw-r--r-- | include/vintf/HalManifest.h | 5 | ||||
-rw-r--r-- | include/vintf/Level.h | 44 | ||||
-rw-r--r-- | include/vintf/parse_string.h | 2 | ||||
-rw-r--r-- | parse_string.cpp | 27 | ||||
-rw-r--r-- | parse_xml.cpp | 12 | ||||
-rw-r--r-- | test/main.cpp | 37 |
9 files changed, 139 insertions, 5 deletions
diff --git a/CompatibilityMatrix.cpp b/CompatibilityMatrix.cpp index 73d0384..f788569 100644 --- a/CompatibilityMatrix.cpp +++ b/CompatibilityMatrix.cpp | |||
@@ -38,6 +38,10 @@ SchemaType CompatibilityMatrix::type() const { | |||
38 | return mType; | 38 | return mType; |
39 | } | 39 | } |
40 | 40 | ||
41 | Level CompatibilityMatrix::level() const { | ||
42 | return mLevel; | ||
43 | } | ||
44 | |||
41 | Version CompatibilityMatrix::getMinimumMetaVersion() const { | 45 | Version CompatibilityMatrix::getMinimumMetaVersion() const { |
42 | // TODO(b/62801658): this needs to depend on whether there are 1.1 requirements | 46 | // TODO(b/62801658): this needs to depend on whether there are 1.1 requirements |
43 | // (e.g. required <xmlfile> entry) | 47 | // (e.g. required <xmlfile> entry) |
@@ -68,7 +72,8 @@ std::string CompatibilityMatrix::getXmlSchemaPath(const std::string& xmlFileName | |||
68 | } | 72 | } |
69 | 73 | ||
70 | bool operator==(const CompatibilityMatrix &lft, const CompatibilityMatrix &rgt) { | 74 | bool operator==(const CompatibilityMatrix &lft, const CompatibilityMatrix &rgt) { |
71 | return lft.mType == rgt.mType && lft.mHals == rgt.mHals && lft.mXmlFiles == rgt.mXmlFiles && | 75 | return lft.mType == rgt.mType && lft.mLevel == rgt.mLevel && lft.mHals == rgt.mHals && |
76 | lft.mXmlFiles == rgt.mXmlFiles && | ||
72 | (lft.mType != SchemaType::DEVICE || (lft.device.mVndk == rgt.device.mVndk)) && | 77 | (lft.mType != SchemaType::DEVICE || (lft.device.mVndk == rgt.device.mVndk)) && |
73 | (lft.mType != SchemaType::FRAMEWORK || | 78 | (lft.mType != SchemaType::FRAMEWORK || |
74 | (lft.framework.mKernels == rgt.framework.mKernels && | 79 | (lft.framework.mKernels == rgt.framework.mKernels && |
diff --git a/HalManifest.cpp b/HalManifest.cpp index c633a7a..9683729 100644 --- a/HalManifest.cpp +++ b/HalManifest.cpp | |||
@@ -319,6 +319,10 @@ SchemaType HalManifest::type() const { | |||
319 | return mType; | 319 | return mType; |
320 | } | 320 | } |
321 | 321 | ||
322 | Level HalManifest::level() const { | ||
323 | return mLevel; | ||
324 | } | ||
325 | |||
322 | Version HalManifest::getMetaVersion() const { | 326 | Version HalManifest::getMetaVersion() const { |
323 | return mMetaVersion; | 327 | return mMetaVersion; |
324 | } | 328 | } |
@@ -352,7 +356,8 @@ std::string HalManifest::getXmlFilePath(const std::string& xmlFileName, | |||
352 | } | 356 | } |
353 | 357 | ||
354 | bool operator==(const HalManifest &lft, const HalManifest &rgt) { | 358 | bool operator==(const HalManifest &lft, const HalManifest &rgt) { |
355 | return lft.mType == rgt.mType && lft.mHals == rgt.mHals && lft.mXmlFiles == rgt.mXmlFiles && | 359 | return lft.mType == rgt.mType && lft.mLevel == rgt.mLevel && lft.mHals == rgt.mHals && |
360 | lft.mXmlFiles == rgt.mXmlFiles && | ||
356 | (lft.mType != SchemaType::DEVICE || | 361 | (lft.mType != SchemaType::DEVICE || |
357 | (lft.device.mSepolicyVersion == rgt.device.mSepolicyVersion)) && | 362 | (lft.device.mSepolicyVersion == rgt.device.mSepolicyVersion)) && |
358 | (lft.mType != SchemaType::FRAMEWORK || (lft.framework.mVndks == rgt.framework.mVndks)); | 363 | (lft.mType != SchemaType::FRAMEWORK || (lft.framework.mVndks == rgt.framework.mVndks)); |
diff --git a/include/vintf/CompatibilityMatrix.h b/include/vintf/CompatibilityMatrix.h index bc3fbf4..c9a8a9f 100644 --- a/include/vintf/CompatibilityMatrix.h +++ b/include/vintf/CompatibilityMatrix.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <utils/Errors.h> | 23 | #include <utils/Errors.h> |
24 | 24 | ||
25 | #include "HalGroup.h" | 25 | #include "HalGroup.h" |
26 | #include "Level.h" | ||
26 | #include "MapValueIterator.h" | 27 | #include "MapValueIterator.h" |
27 | #include "MatrixHal.h" | 28 | #include "MatrixHal.h" |
28 | #include "MatrixKernel.h" | 29 | #include "MatrixKernel.h" |
@@ -40,6 +41,7 @@ struct CompatibilityMatrix : public HalGroup<MatrixHal>, public XmlFileGroup<Mat | |||
40 | CompatibilityMatrix() : mType(SchemaType::FRAMEWORK) {}; | 41 | CompatibilityMatrix() : mType(SchemaType::FRAMEWORK) {}; |
41 | 42 | ||
42 | SchemaType type() const; | 43 | SchemaType type() const; |
44 | Level level() const; | ||
43 | Version getMinimumMetaVersion() const; | 45 | Version getMinimumMetaVersion() const; |
44 | 46 | ||
45 | // If the corresponding <xmlfile> with the given version exists, for the first match, | 47 | // If the corresponding <xmlfile> with the given version exists, for the first match, |
@@ -68,6 +70,7 @@ struct CompatibilityMatrix : public HalGroup<MatrixHal>, public XmlFileGroup<Mat | |||
68 | friend bool operator==(const CompatibilityMatrix &, const CompatibilityMatrix &); | 70 | friend bool operator==(const CompatibilityMatrix &, const CompatibilityMatrix &); |
69 | 71 | ||
70 | SchemaType mType; | 72 | SchemaType mType; |
73 | Level mLevel = Level::UNSPECIFIED; | ||
71 | 74 | ||
72 | // entries only for framework compatibility matrix. | 75 | // entries only for framework compatibility matrix. |
73 | struct { | 76 | struct { |
diff --git a/include/vintf/HalManifest.h b/include/vintf/HalManifest.h index b553371..46657de 100644 --- a/include/vintf/HalManifest.h +++ b/include/vintf/HalManifest.h | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <vector> | 24 | #include <vector> |
25 | 25 | ||
26 | #include "HalGroup.h" | 26 | #include "HalGroup.h" |
27 | #include "Level.h" | ||
27 | #include "ManifestHal.h" | 28 | #include "ManifestHal.h" |
28 | #include "MapValueIterator.h" | 29 | #include "MapValueIterator.h" |
29 | #include "SchemaType.h" | 30 | #include "SchemaType.h" |
@@ -93,6 +94,9 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX | |||
93 | // Type of the manifest. FRAMEWORK or DEVICE. | 94 | // Type of the manifest. FRAMEWORK or DEVICE. |
94 | SchemaType type() const; | 95 | SchemaType type() const; |
95 | 96 | ||
97 | // FCM version that it implements. | ||
98 | Level level() const; | ||
99 | |||
96 | // device.mSepolicyVersion. Assume type == device. | 100 | // device.mSepolicyVersion. Assume type == device. |
97 | // Abort if type != device. | 101 | // Abort if type != device. |
98 | const Version &sepolicyVersion() const; | 102 | const Version &sepolicyVersion() const; |
@@ -132,6 +136,7 @@ struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestX | |||
132 | bool includeOptional = true) const; | 136 | bool includeOptional = true) const; |
133 | 137 | ||
134 | SchemaType mType; | 138 | SchemaType mType; |
139 | Level mLevel = Level::UNSPECIFIED; | ||
135 | // version attribute. Default is 1.0 for manifests created programatically. | 140 | // version attribute. Default is 1.0 for manifests created programatically. |
136 | Version mMetaVersion{1, 0}; | 141 | Version mMetaVersion{1, 0}; |
137 | 142 | ||
diff --git a/include/vintf/Level.h b/include/vintf/Level.h new file mode 100644 index 0000000..49dad0b --- /dev/null +++ b/include/vintf/Level.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2017 The Android Open Source Project | ||
3 | * | ||
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | * you may not use this file except in compliance with the License. | ||
6 | * You may obtain a copy of the License at | ||
7 | * | ||
8 | * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | * | ||
10 | * Unless required by applicable law or agreed to in writing, software | ||
11 | * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | * See the License for the specific language governing permissions and | ||
14 | * limitations under the License. | ||
15 | */ | ||
16 | |||
17 | #ifndef ANDROID_VINTF_LEVEL_H | ||
18 | #define ANDROID_VINTF_LEVEL_H | ||
19 | |||
20 | #include <stdint.h> | ||
21 | |||
22 | namespace android { | ||
23 | namespace vintf { | ||
24 | |||
25 | // Manifest and Compatibility Matrix Level, a.k.a FCM Version, is a number assigned to each | ||
26 | // manifest / matrix. | ||
27 | // - For manifest, the FCM Version that it implements | ||
28 | // - For matrix, the single FCM Version that this matrix file details. | ||
29 | // This is not a strong-typed enum because Level can be any integer value. Listed are some | ||
30 | // special values. | ||
31 | enum Level : size_t { | ||
32 | // Non-Treble devices. | ||
33 | LEGACY = 0, | ||
34 | // Actual values starts from 1. Following are some historic values for convenience. | ||
35 | O = 1, | ||
36 | O_MR1 = 2, | ||
37 | // For older manifests and compatibility matrices, "level" is not specified. | ||
38 | UNSPECIFIED = SIZE_MAX, | ||
39 | }; | ||
40 | |||
41 | } // namespace vintf | ||
42 | } // namespace android | ||
43 | |||
44 | #endif // ANDROID_VINTF_LEVEL_H | ||
diff --git a/include/vintf/parse_string.h b/include/vintf/parse_string.h index 77d1830..00844d7 100644 --- a/include/vintf/parse_string.h +++ b/include/vintf/parse_string.h | |||
@@ -35,6 +35,7 @@ std::ostream &operator<<(std::ostream &os, KernelConfigType il); | |||
35 | std::ostream &operator<<(std::ostream &os, Tristate tr); | 35 | std::ostream &operator<<(std::ostream &os, Tristate tr); |
36 | std::ostream &operator<<(std::ostream &os, SchemaType ksv); | 36 | std::ostream &operator<<(std::ostream &os, SchemaType ksv); |
37 | std::ostream& operator<<(std::ostream& os, XmlSchemaFormat f); | 37 | std::ostream& operator<<(std::ostream& os, XmlSchemaFormat f); |
38 | std::ostream& operator<<(std::ostream& os, Level l); | ||
38 | std::ostream &operator<<(std::ostream &os, const ManifestHal &hal); | 39 | std::ostream &operator<<(std::ostream &os, const ManifestHal &hal); |
39 | std::ostream &operator<<(std::ostream &os, const Version &ver); | 40 | std::ostream &operator<<(std::ostream &os, const Version &ver); |
40 | std::ostream &operator<<(std::ostream &os, const VersionRange &vr); | 41 | std::ostream &operator<<(std::ostream &os, const VersionRange &vr); |
@@ -60,6 +61,7 @@ bool parse(const std::string &s, KernelConfigKey *key); | |||
60 | bool parse(const std::string &s, Tristate *tr); | 61 | bool parse(const std::string &s, Tristate *tr); |
61 | bool parse(const std::string &s, SchemaType *ver); | 62 | bool parse(const std::string &s, SchemaType *ver); |
62 | bool parse(const std::string& s, XmlSchemaFormat* ver); | 63 | bool parse(const std::string& s, XmlSchemaFormat* ver); |
64 | bool parse(const std::string& s, Level* l); | ||
63 | bool parse(const std::string &s, KernelSepolicyVersion *ksv); | 65 | bool parse(const std::string &s, KernelSepolicyVersion *ksv); |
64 | bool parse(const std::string &s, Version *ver); | 66 | bool parse(const std::string &s, Version *ver); |
65 | bool parse(const std::string &s, VersionRange *vr); | 67 | bool parse(const std::string &s, VersionRange *vr); |
diff --git a/parse_string.cpp b/parse_string.cpp index a6bb418..7e23f5f 100644 --- a/parse_string.cpp +++ b/parse_string.cpp | |||
@@ -113,6 +113,33 @@ std::ostream &operator<<(std::ostream &os, const KernelConfigTypedValue &kctv) { | |||
113 | } | 113 | } |
114 | } | 114 | } |
115 | 115 | ||
116 | bool parse(const std::string& s, Level* l) { | ||
117 | if (s.empty()) { | ||
118 | *l = Level::UNSPECIFIED; | ||
119 | return true; | ||
120 | } | ||
121 | if (s == "legacy") { | ||
122 | *l = Level::LEGACY; | ||
123 | return true; | ||
124 | } | ||
125 | size_t value; | ||
126 | if (!ParseUint(s, &value)) { | ||
127 | return false; | ||
128 | } | ||
129 | *l = static_cast<Level>(value); | ||
130 | return true; | ||
131 | } | ||
132 | |||
133 | std::ostream& operator<<(std::ostream& os, Level l) { | ||
134 | if (l == Level::UNSPECIFIED) { | ||
135 | return os; | ||
136 | } | ||
137 | if (l == Level::LEGACY) { | ||
138 | return os << "legacy"; | ||
139 | } | ||
140 | return os << static_cast<size_t>(l); | ||
141 | } | ||
142 | |||
116 | // Notice that strtoull is used even though KernelConfigIntValue is signed int64_t, | 143 | // Notice that strtoull is used even though KernelConfigIntValue is signed int64_t, |
117 | // because strtoull can accept negative values as well. | 144 | // because strtoull can accept negative values as well. |
118 | // Notice that according to man strtoul, strtoull can actually accept | 145 | // Notice that according to man strtoul, strtoull can actually accept |
diff --git a/parse_xml.cpp b/parse_xml.cpp index 1a0626a..350d10b 100644 --- a/parse_xml.cpp +++ b/parse_xml.cpp | |||
@@ -748,7 +748,9 @@ struct HalManifestConverter : public XmlNodeConverter<HalManifest> { | |||
748 | void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override { | 748 | void mutateNode(const HalManifest &m, NodeType *root, DocType *d) const override { |
749 | appendAttr(root, "version", m.getMetaVersion()); | 749 | appendAttr(root, "version", m.getMetaVersion()); |
750 | appendAttr(root, "type", m.mType); | 750 | appendAttr(root, "type", m.mType); |
751 | 751 | if (m.mLevel != Level::UNSPECIFIED) { | |
752 | this->appendAttr(root, "target-level", m.mLevel); | ||
753 | } | ||
752 | appendChildren(root, manifestHalConverter, m.getHals(), d); | 754 | appendChildren(root, manifestHalConverter, m.getHals(), d); |
753 | if (m.mType == SchemaType::DEVICE) { | 755 | if (m.mType == SchemaType::DEVICE) { |
754 | appendChild(root, halManifestSepolicyConverter(m.device.mSepolicyVersion, d)); | 756 | appendChild(root, halManifestSepolicyConverter(m.device.mSepolicyVersion, d)); |
@@ -762,6 +764,7 @@ struct HalManifestConverter : public XmlNodeConverter<HalManifest> { | |||
762 | std::vector<ManifestHal> hals; | 764 | std::vector<ManifestHal> hals; |
763 | if (!parseAttr(root, "version", &object->mMetaVersion) || | 765 | if (!parseAttr(root, "version", &object->mMetaVersion) || |
764 | !parseAttr(root, "type", &object->mType) || | 766 | !parseAttr(root, "type", &object->mType) || |
767 | !parseOptionalAttr(root, "target-level", Level::UNSPECIFIED, &object->mLevel) || | ||
765 | !parseChildren(root, manifestHalConverter, &hals)) { | 768 | !parseChildren(root, manifestHalConverter, &hals)) { |
766 | return false; | 769 | return false; |
767 | } | 770 | } |
@@ -858,6 +861,9 @@ struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatri | |||
858 | void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override { | 861 | void mutateNode(const CompatibilityMatrix &m, NodeType *root, DocType *d) const override { |
859 | appendAttr(root, "version", m.getMinimumMetaVersion()); | 862 | appendAttr(root, "version", m.getMinimumMetaVersion()); |
860 | appendAttr(root, "type", m.mType); | 863 | appendAttr(root, "type", m.mType); |
864 | if (m.mLevel != Level::UNSPECIFIED) { | ||
865 | this->appendAttr(root, "level", m.mLevel); | ||
866 | } | ||
861 | appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d); | 867 | appendChildren(root, matrixHalConverter, iterateValues(m.mHals), d); |
862 | if (m.mType == SchemaType::FRAMEWORK) { | 868 | if (m.mType == SchemaType::FRAMEWORK) { |
863 | appendChildren(root, matrixKernelConverter, m.framework.mKernels, d); | 869 | appendChildren(root, matrixKernelConverter, m.framework.mKernels, d); |
@@ -872,8 +878,8 @@ struct CompatibilityMatrixConverter : public XmlNodeConverter<CompatibilityMatri | |||
872 | bool buildObject(CompatibilityMatrix *object, NodeType *root) const override { | 878 | bool buildObject(CompatibilityMatrix *object, NodeType *root) const override { |
873 | Version version; | 879 | Version version; |
874 | std::vector<MatrixHal> hals; | 880 | std::vector<MatrixHal> hals; |
875 | if (!parseAttr(root, "version", &version) || | 881 | if (!parseAttr(root, "version", &version) || !parseAttr(root, "type", &object->mType) || |
876 | !parseAttr(root, "type", &object->mType) || | 882 | !parseOptionalAttr(root, "level", Level::UNSPECIFIED, &object->mLevel) || |
877 | !parseChildren(root, matrixHalConverter, &hals)) { | 883 | !parseChildren(root, matrixHalConverter, &hals)) { |
878 | return false; | 884 | return false; |
879 | } | 885 | } |
diff --git a/test/main.cpp b/test/main.cpp index 8ec02a8..b8a25a2 100644 --- a/test/main.cpp +++ b/test/main.cpp | |||
@@ -2047,6 +2047,43 @@ TEST_P(KernelConfigParserInvalidTest, InvalidLine2) { | |||
2047 | 2047 | ||
2048 | INSTANTIATE_TEST_CASE_P(KernelConfigParser, KernelConfigParserInvalidTest, ::testing::Bool()); | 2048 | INSTANTIATE_TEST_CASE_P(KernelConfigParser, KernelConfigParserInvalidTest, ::testing::Bool()); |
2049 | 2049 | ||
2050 | TEST_F(LibVintfTest, MatrixLevel) { | ||
2051 | CompatibilityMatrix cm; | ||
2052 | std::string xml; | ||
2053 | |||
2054 | xml = "<compatibility-matrix version=\"1.0\" type=\"framework\"/>"; | ||
2055 | EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml)) | ||
2056 | << gCompatibilityMatrixConverter.lastError(); | ||
2057 | EXPECT_EQ(Level::UNSPECIFIED, cm.level()); | ||
2058 | |||
2059 | xml = "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"legacy\"/>"; | ||
2060 | EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml)) | ||
2061 | << gCompatibilityMatrixConverter.lastError(); | ||
2062 | EXPECT_EQ(Level::LEGACY, cm.level()); | ||
2063 | |||
2064 | xml = "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\"/>"; | ||
2065 | EXPECT_TRUE(gCompatibilityMatrixConverter(&cm, xml)) | ||
2066 | << gCompatibilityMatrixConverter.lastError(); | ||
2067 | EXPECT_EQ(1u, cm.level()); | ||
2068 | } | ||
2069 | |||
2070 | TEST_F(LibVintfTest, ManifestLevel) { | ||
2071 | HalManifest manifest; | ||
2072 | std::string xml; | ||
2073 | |||
2074 | xml = "<manifest version=\"1.0\" type=\"device\"/>"; | ||
2075 | EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError(); | ||
2076 | EXPECT_EQ(Level::UNSPECIFIED, manifest.level()); | ||
2077 | |||
2078 | xml = "<manifest version=\"1.0\" type=\"device\" target-level=\"legacy\"/>"; | ||
2079 | EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError(); | ||
2080 | EXPECT_EQ(Level::LEGACY, manifest.level()); | ||
2081 | |||
2082 | xml = "<manifest version=\"1.0\" type=\"device\" target-level=\"1\"/>"; | ||
2083 | EXPECT_TRUE(gHalManifestConverter(&manifest, xml)) << gHalManifestConverter.lastError(); | ||
2084 | EXPECT_EQ(1u, manifest.level()); | ||
2085 | } | ||
2086 | |||
2050 | } // namespace vintf | 2087 | } // namespace vintf |
2051 | } // namespace android | 2088 | } // namespace android |
2052 | 2089 | ||