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
18 #define LOG_TAG "libvintf"
19
20 #include "RuntimeInfo.h"
21
22 #include "CompatibilityMatrix.h"
23 #include "parse_string.h"
24
25 namespace android {
26 namespace vintf {
27
osName() const28 const std::string &RuntimeInfo::osName() const {
29 return mOsName;
30 }
31
nodeName() const32 const std::string &RuntimeInfo::nodeName() const {
33 return mNodeName;
34 }
35
osRelease() const36 const std::string &RuntimeInfo::osRelease() const {
37 return mOsRelease;
38 }
39
osVersion() const40 const std::string &RuntimeInfo::osVersion() const {
41 return mOsVersion;
42 }
43
hardwareId() const44 const std::string &RuntimeInfo::hardwareId() const {
45 return mHardwareId;
46 }
47
kernelVersion() const48 const KernelVersion &RuntimeInfo::kernelVersion() const {
49 return mKernelVersion;
50 }
51
kernelConfigs() const52 const std::map<std::string, std::string> &RuntimeInfo::kernelConfigs() const {
53 return mKernelConfigs;
54 }
55
kernelSepolicyVersion() const56 size_t RuntimeInfo::kernelSepolicyVersion() const {
57 return mKernelSepolicyVersion;
58 }
59
cpuInfo() const60 const std::string &RuntimeInfo::cpuInfo() const {
61 return mCpuInfo;
62 }
63
bootVbmetaAvbVersion() const64 const Version &RuntimeInfo::bootVbmetaAvbVersion() const {
65 return mBootVbmetaAvbVersion;
66 }
67
bootAvbVersion() const68 const Version &RuntimeInfo::bootAvbVersion() const {
69 return mBootAvbVersion;
70 }
71
matchKernelConfigs(const std::vector<KernelConfig> & matrixConfigs,std::string * error) const72 bool RuntimeInfo::matchKernelConfigs(const std::vector<KernelConfig>& matrixConfigs,
73 std::string* error) const {
74 for (const KernelConfig& matrixConfig : matrixConfigs) {
75 const std::string& key = matrixConfig.first;
76 auto it = this->mKernelConfigs.find(key);
77 if (it == this->mKernelConfigs.end()) {
78 // special case: <value type="tristate">n</value> matches if the config doesn't exist.
79 if (matrixConfig.second == KernelConfigTypedValue::gMissingConfig) {
80 continue;
81 }
82 if (error != nullptr) {
83 *error = "Missing config " + key;
84 }
85 return false;
86 }
87 const std::string& kernelValue = it->second;
88 if (!matrixConfig.second.matchValue(kernelValue)) {
89 if (error != nullptr) {
90 *error = "For config " + key + ", value = " + kernelValue + " but required " +
91 to_string(matrixConfig.second);
92 }
93 return false;
94 }
95 }
96 return true;
97 }
98
matchKernelVersion(const KernelVersion & minLts) const99 bool RuntimeInfo::matchKernelVersion(const KernelVersion& minLts) const {
100 return minLts.version == mKernelVersion.version && minLts.majorRev == mKernelVersion.majorRev &&
101 minLts.minorRev <= mKernelVersion.minorRev;
102 }
103
checkCompatibility(const CompatibilityMatrix & mat,std::string * error,DisabledChecks disabledChecks) const104 bool RuntimeInfo::checkCompatibility(const CompatibilityMatrix& mat, std::string* error,
105 DisabledChecks disabledChecks) const {
106 if (mat.mType != SchemaType::FRAMEWORK) {
107 if (error != nullptr) {
108 *error = "Should not check runtime info against " + to_string(mat.mType)
109 + " compatibility matrix.";
110 }
111 return false;
112 }
113 if (kernelSepolicyVersion() != mat.framework.mSepolicy.kernelSepolicyVersion()) {
114 if (error != nullptr) {
115 *error = "kernelSepolicyVersion = " + to_string(kernelSepolicyVersion())
116 + " but required " + to_string(mat.framework.mSepolicy.kernelSepolicyVersion());
117 }
118 return false;
119 }
120
121 // mat.mSepolicy.sepolicyVersion() is checked against static
122 // HalManifest.device.mSepolicyVersion in HalManifest::checkCompatibility.
123
124 bool foundMatchedKernelVersion = false;
125 bool foundMatchedConditions = false;
126 for (const MatrixKernel& matrixKernel : mat.framework.mKernels) {
127 if (!matchKernelVersion(matrixKernel.minLts())) {
128 continue;
129 }
130 foundMatchedKernelVersion = true;
131 // ignore this fragment if not all conditions are met.
132 if (!matchKernelConfigs(matrixKernel.conditions(), error)) {
133 continue;
134 }
135 foundMatchedConditions = true;
136 if (!matchKernelConfigs(matrixKernel.configs(), error)) {
137 return false;
138 }
139 }
140 if (!foundMatchedKernelVersion) {
141 if (error != nullptr) {
142 std::stringstream ss;
143 ss << "Framework is incompatible with kernel version " << mKernelVersion
144 << ", compatible kernel versions are";
145 for (const MatrixKernel& matrixKernel : mat.framework.mKernels)
146 ss << " " << matrixKernel.minLts();
147 *error = ss.str();
148 }
149 return false;
150 }
151 if (!foundMatchedConditions) {
152 // This should not happen because first <conditions> for each <kernel> must be
153 // empty. Reject here for inconsistency.
154 if (error != nullptr) {
155 error->insert(0, "Framework match kernel version with unmet conditions:");
156 }
157 return false;
158 }
159 if (error != nullptr) {
160 error->clear();
161 }
162
163 if ((disabledChecks & DISABLE_AVB_CHECK) == 0) {
164 const Version& matAvb = mat.framework.mAvbMetaVersion;
165 if (mBootAvbVersion.majorVer != matAvb.majorVer ||
166 mBootAvbVersion.minorVer < matAvb.minorVer) {
167 if (error != nullptr) {
168 std::stringstream ss;
169 ss << "AVB version " << mBootAvbVersion << " does not match framework matrix "
170 << matAvb;
171 *error = ss.str();
172 }
173 return false;
174 }
175 if (mBootVbmetaAvbVersion.majorVer != matAvb.majorVer ||
176 mBootVbmetaAvbVersion.minorVer < matAvb.minorVer) {
177 if (error != nullptr) {
178 std::stringstream ss;
179 ss << "Vbmeta version " << mBootVbmetaAvbVersion
180 << " does not match framework matrix " << matAvb;
181 *error = ss.str();
182 }
183 return false;
184 }
185 }
186
187 return true;
188 }
189
190 } // namespace vintf
191 } // namespace android
192