blob: ec8abacf94561bcf879d2ee2fe056106c29a962a [file] [log] [blame]
Yifan Hong90ed9972018-12-03 15:08:34 -08001/*
2 * Copyright (C) 2019 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#include "KernelInfo.h"
17
18#include "parse_string.h"
19
20namespace android {
21namespace vintf {
22
23const KernelVersion& KernelInfo::version() const {
24 return mVersion;
25}
26
27const std::map<std::string, std::string>& KernelInfo::configs() const {
28 return mConfigs;
29}
30
Yifan Honge6248442019-12-11 13:33:00 -080031Level KernelInfo::level() const {
32 return mLevel;
33}
34
Yifan Hong90ed9972018-12-03 15:08:34 -080035bool KernelInfo::matchKernelConfigs(const std::vector<KernelConfig>& matrixConfigs,
36 std::string* error) const {
37 for (const KernelConfig& matrixConfig : matrixConfigs) {
38 const std::string& key = matrixConfig.first;
39 auto it = this->mConfigs.find(key);
40 if (it == this->mConfigs.end()) {
41 // special case: <value type="tristate">n</value> matches if the config doesn't exist.
42 if (matrixConfig.second == KernelConfigTypedValue::gMissingConfig) {
43 continue;
44 }
45 if (error != nullptr) {
46 *error = "Missing config " + key;
47 }
48 return false;
49 }
50 const std::string& kernelValue = it->second;
51 if (!matrixConfig.second.matchValue(kernelValue)) {
52 if (error != nullptr) {
53 *error = "For config " + key + ", value = " + kernelValue + " but required " +
54 to_string(matrixConfig.second);
55 }
56 return false;
57 }
58 }
59 return true;
60}
61
62bool KernelInfo::matchKernelVersion(const KernelVersion& minLts) const {
63 return minLts.version == mVersion.version && minLts.majorRev == mVersion.majorRev &&
64 minLts.minorRev <= mVersion.minorRev;
65}
66
Yifan Hong1e8febd2019-08-07 16:17:19 -070067std::vector<const MatrixKernel*> KernelInfo::getMatchedKernelRequirements(
68 const std::vector<MatrixKernel>& kernels, std::string* error) const {
69 std::vector<const MatrixKernel*> result;
Yifan Hong90ed9972018-12-03 15:08:34 -080070 bool foundMatchedKernelVersion = false;
Yifan Hong90ed9972018-12-03 15:08:34 -080071 for (const MatrixKernel& matrixKernel : kernels) {
72 if (!matchKernelVersion(matrixKernel.minLts())) {
73 continue;
74 }
75 foundMatchedKernelVersion = true;
76 // ignore this fragment if not all conditions are met.
77 if (!matchKernelConfigs(matrixKernel.conditions(), error)) {
78 continue;
79 }
Yifan Hong90ed9972018-12-03 15:08:34 -080080 if (!matchKernelConfigs(matrixKernel.configs(), error)) {
Yifan Hong1e8febd2019-08-07 16:17:19 -070081 return {};
Yifan Hong90ed9972018-12-03 15:08:34 -080082 }
Yifan Hong1e8febd2019-08-07 16:17:19 -070083 result.push_back(&matrixKernel);
Yifan Hong90ed9972018-12-03 15:08:34 -080084 }
85 if (!foundMatchedKernelVersion) {
86 if (error != nullptr) {
87 std::stringstream ss;
88 ss << "Framework is incompatible with kernel version " << version()
89 << ", compatible kernel versions are";
90 for (const MatrixKernel& matrixKernel : kernels) ss << " " << matrixKernel.minLts();
91 *error = ss.str();
92 }
Yifan Hong1e8febd2019-08-07 16:17:19 -070093 return {};
Yifan Hong90ed9972018-12-03 15:08:34 -080094 }
Yifan Hong1e8febd2019-08-07 16:17:19 -070095 if (result.empty()) {
96 // This means matchKernelVersion passes but matchKernelConfigs(conditions) fails.
Yifan Hong90ed9972018-12-03 15:08:34 -080097 // This should not happen because first <conditions> for each <kernel> must be
98 // empty. Reject here for inconsistency.
99 if (error != nullptr) {
100 error->insert(0, "Framework match kernel version with unmet conditions:");
101 }
Yifan Hong1e8febd2019-08-07 16:17:19 -0700102 return {};
Yifan Hong90ed9972018-12-03 15:08:34 -0800103 }
104 if (error != nullptr) {
105 error->clear();
106 }
Yifan Hong1e8febd2019-08-07 16:17:19 -0700107 return result;
Yifan Hong90ed9972018-12-03 15:08:34 -0800108}
109
Yifan Honga45f77d2018-12-03 16:42:52 -0800110bool KernelInfo::operator==(const KernelInfo& other) const {
111 return mVersion == other.mVersion && mConfigs == other.mConfigs;
112}
113
Yifan Hong90ed9972018-12-03 15:08:34 -0800114} // namespace vintf
115} // namespace android