Home | History | Annotate | Download | only in libvintf
      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 
     28 const std::string &RuntimeInfo::osName() const {
     29     return mOsName;
     30 }
     31 
     32 const std::string &RuntimeInfo::nodeName() const {
     33     return mNodeName;
     34 }
     35 
     36 const std::string &RuntimeInfo::osRelease() const {
     37     return mOsRelease;
     38 }
     39 
     40 const std::string &RuntimeInfo::osVersion() const {
     41     return mOsVersion;
     42 }
     43 
     44 const std::string &RuntimeInfo::hardwareId() const {
     45     return mHardwareId;
     46 }
     47 
     48 const KernelVersion &RuntimeInfo::kernelVersion() const {
     49     return mKernelVersion;
     50 }
     51 
     52 const std::map<std::string, std::string> &RuntimeInfo::kernelConfigs() const {
     53     return mKernelConfigs;
     54 }
     55 
     56 size_t RuntimeInfo::kernelSepolicyVersion() const {
     57     return mKernelSepolicyVersion;
     58 }
     59 
     60 const std::string &RuntimeInfo::cpuInfo() const {
     61     return mCpuInfo;
     62 }
     63 
     64 const Version &RuntimeInfo::bootVbmetaAvbVersion() const {
     65     return mBootVbmetaAvbVersion;
     66 }
     67 
     68 const Version &RuntimeInfo::bootAvbVersion() const {
     69     return mBootAvbVersion;
     70 }
     71 
     72 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 
     99 bool RuntimeInfo::matchKernelVersion(const KernelVersion& minLts) const {
    100     return minLts.version == mKernelVersion.version && minLts.majorRev == mKernelVersion.majorRev &&
    101            minLts.minorRev <= mKernelVersion.minorRev;
    102 }
    103 
    104 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 =
    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