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 25namespace android { 26namespace vintf { 27 28const std::string &RuntimeInfo::osName() const { 29 return mOsName; 30} 31 32const std::string &RuntimeInfo::nodeName() const { 33 return mNodeName; 34} 35 36const std::string &RuntimeInfo::osRelease() const { 37 return mOsRelease; 38} 39 40const std::string &RuntimeInfo::osVersion() const { 41 return mOsVersion; 42} 43 44const std::string &RuntimeInfo::hardwareId() const { 45 return mHardwareId; 46} 47 48const KernelVersion &RuntimeInfo::kernelVersion() const { 49 return mKernelVersion; 50} 51 52const std::map<std::string, std::string> &RuntimeInfo::kernelConfigs() const { 53 return mKernelConfigs; 54} 55 56size_t RuntimeInfo::kernelSepolicyVersion() const { 57 return mKernelSepolicyVersion; 58} 59 60const std::string &RuntimeInfo::cpuInfo() const { 61 return mCpuInfo; 62} 63 64const Version &RuntimeInfo::bootVbmetaAvbVersion() const { 65 return mBootVbmetaAvbVersion; 66} 67 68const Version &RuntimeInfo::bootAvbVersion() const { 69 return mBootAvbVersion; 70} 71 72bool 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 99bool RuntimeInfo::matchKernelVersion(const KernelVersion& minLts) const { 100 return minLts.version == mKernelVersion.version && minLts.majorRev == mKernelVersion.majorRev && 101 minLts.minorRev <= mKernelVersion.minorRev; 102} 103 104bool 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 = 116 "kernelSepolicyVersion = " + to_string(kernelSepolicyVersion()) + 117 " but required >= " + to_string(mat.framework.mSepolicy.kernelSepolicyVersion()); 118 } 119 return false; 120 } 121 122 // mat.mSepolicy.sepolicyVersion() is checked against static 123 // HalManifest.device.mSepolicyVersion in HalManifest::checkCompatibility. 124 125 bool foundMatchedKernelVersion = false; 126 bool foundMatchedConditions = false; 127 for (const MatrixKernel& matrixKernel : mat.framework.mKernels) { 128 if (!matchKernelVersion(matrixKernel.minLts())) { 129 continue; 130 } 131 foundMatchedKernelVersion = true; 132 // ignore this fragment if not all conditions are met. 133 if (!matchKernelConfigs(matrixKernel.conditions(), error)) { 134 continue; 135 } 136 foundMatchedConditions = true; 137 if (!matchKernelConfigs(matrixKernel.configs(), error)) { 138 return false; 139 } 140 } 141 if (!foundMatchedKernelVersion) { 142 if (error != nullptr) { 143 std::stringstream ss; 144 ss << "Framework is incompatible with kernel version " << mKernelVersion 145 << ", compatible kernel versions are"; 146 for (const MatrixKernel& matrixKernel : mat.framework.mKernels) 147 ss << " " << matrixKernel.minLts(); 148 *error = ss.str(); 149 } 150 return false; 151 } 152 if (!foundMatchedConditions) { 153 // This should not happen because first <conditions> for each <kernel> must be 154 // empty. Reject here for inconsistency. 155 if (error != nullptr) { 156 error->insert(0, "Framework match kernel version with unmet conditions:"); 157 } 158 return false; 159 } 160 if (error != nullptr) { 161 error->clear(); 162 } 163 164 if ((disabledChecks & DISABLE_AVB_CHECK) == 0) { 165 const Version& matAvb = mat.framework.mAvbMetaVersion; 166 if (mBootAvbVersion.majorVer != matAvb.majorVer || 167 mBootAvbVersion.minorVer < matAvb.minorVer) { 168 if (error != nullptr) { 169 std::stringstream ss; 170 ss << "AVB version " << mBootAvbVersion << " does not match framework matrix " 171 << matAvb; 172 *error = ss.str(); 173 } 174 return false; 175 } 176 if (mBootVbmetaAvbVersion.majorVer != matAvb.majorVer || 177 mBootVbmetaAvbVersion.minorVer < matAvb.minorVer) { 178 if (error != nullptr) { 179 std::stringstream ss; 180 ss << "Vbmeta version " << mBootVbmetaAvbVersion 181 << " does not match framework matrix " << matAvb; 182 *error = ss.str(); 183 } 184 return false; 185 } 186 } 187 188 return true; 189} 190 191} // namespace vintf 192} // namespace android 193