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::checkCompatibility(const CompatibilityMatrix &mat,
73            std::string *error) const {
74    if (mat.mType != SchemaType::FRAMEWORK) {
75        if (error != nullptr) {
76            *error = "Should not check runtime info against " + to_string(mat.mType)
77                    + " compatibility matrix.";
78        }
79        return false;
80    }
81    if (kernelSepolicyVersion() != mat.framework.mSepolicy.kernelSepolicyVersion()) {
82        if (error != nullptr) {
83            *error = "kernelSepolicyVersion = " + to_string(kernelSepolicyVersion())
84                     + " but required " + to_string(mat.framework.mSepolicy.kernelSepolicyVersion());
85        }
86        return false;
87    }
88
89    // mat.mSepolicy.sepolicyVersion() is checked against static HalManifest.device.mSepolicyVersion
90
91    const MatrixKernel *matrixKernel = mat.findKernel(this->mKernelVersion);
92    if (matrixKernel == nullptr) {
93        if (error != nullptr) {
94            *error = "Cannot find suitable kernel entry for " + to_string(mKernelVersion);
95        }
96        return false;
97    }
98    for (const KernelConfig &matrixConfig : matrixKernel->configs()) {
99        const std::string &key = matrixConfig.first;
100        auto it = this->mKernelConfigs.find(key);
101        if (it == this->mKernelConfigs.end()) {
102            // special case: <value type="tristate">n</value> matches if the config doesn't exist.
103            if (matrixConfig.second == KernelConfigTypedValue::gMissingConfig) {
104                continue;
105            }
106            if (error != nullptr) {
107                *error = "Missing config " + key;
108            }
109            return false;
110        }
111        const std::string &kernelValue = it->second;
112        if (!matrixConfig.second.matchValue(kernelValue)) {
113            if (error != nullptr) {
114                *error = "For config " + key + ", value = " + kernelValue
115                        + " but required " + to_string(matrixConfig.second);
116            }
117            return false;
118        }
119    }
120
121    const Version &matAvb = mat.framework.mAvbMetaVersion;
122    if (mBootAvbVersion.majorVer != matAvb.majorVer || mBootAvbVersion.minorVer < matAvb.minorVer) {
123        if (error != nullptr) {
124            std::stringstream ss;
125            ss << "AVB version " << mBootAvbVersion << " does not match framework matrix "
126               << matAvb;
127            *error = ss.str();
128        }
129        return false;
130    }
131    if (mBootVbmetaAvbVersion.majorVer != matAvb.majorVer ||
132        mBootVbmetaAvbVersion.minorVer < matAvb.minorVer) {
133        if (error != nullptr) {
134            std::stringstream ss;
135            ss << "Vbmeta version " << mBootVbmetaAvbVersion << " does not match framework matrix "
136               << matAvb;
137            *error = ss.str();
138        }
139        return false;
140    }
141
142    return true;
143}
144
145} // namespace vintf
146} // namespace android
147