blob: 4f3215e752d670b31b7cc810a692136835c5baf3 [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
31bool KernelInfo::matchKernelConfigs(const std::vector<KernelConfig>& matrixConfigs,
32 std::string* error) const {
33 for (const KernelConfig& matrixConfig : matrixConfigs) {
34 const std::string& key = matrixConfig.first;
35 auto it = this->mConfigs.find(key);
36 if (it == this->mConfigs.end()) {
37 // special case: <value type="tristate">n</value> matches if the config doesn't exist.
38 if (matrixConfig.second == KernelConfigTypedValue::gMissingConfig) {
39 continue;
40 }
41 if (error != nullptr) {
42 *error = "Missing config " + key;
43 }
44 return false;
45 }
46 const std::string& kernelValue = it->second;
47 if (!matrixConfig.second.matchValue(kernelValue)) {
48 if (error != nullptr) {
49 *error = "For config " + key + ", value = " + kernelValue + " but required " +
50 to_string(matrixConfig.second);
51 }
52 return false;
53 }
54 }
55 return true;
56}
57
58bool KernelInfo::matchKernelVersion(const KernelVersion& minLts) const {
59 return minLts.version == mVersion.version && minLts.majorRev == mVersion.majorRev &&
60 minLts.minorRev <= mVersion.minorRev;
61}
62
Yifan Hong1e8febd2019-08-07 16:17:19 -070063std::vector<const MatrixKernel*> KernelInfo::getMatchedKernelRequirements(
64 const std::vector<MatrixKernel>& kernels, std::string* error) const {
65 std::vector<const MatrixKernel*> result;
Yifan Hong90ed9972018-12-03 15:08:34 -080066 bool foundMatchedKernelVersion = false;
Yifan Hong90ed9972018-12-03 15:08:34 -080067 for (const MatrixKernel& matrixKernel : kernels) {
68 if (!matchKernelVersion(matrixKernel.minLts())) {
69 continue;
70 }
71 foundMatchedKernelVersion = true;
72 // ignore this fragment if not all conditions are met.
73 if (!matchKernelConfigs(matrixKernel.conditions(), error)) {
74 continue;
75 }
Yifan Hong90ed9972018-12-03 15:08:34 -080076 if (!matchKernelConfigs(matrixKernel.configs(), error)) {
Yifan Hong1e8febd2019-08-07 16:17:19 -070077 return {};
Yifan Hong90ed9972018-12-03 15:08:34 -080078 }
Yifan Hong1e8febd2019-08-07 16:17:19 -070079 result.push_back(&matrixKernel);
Yifan Hong90ed9972018-12-03 15:08:34 -080080 }
81 if (!foundMatchedKernelVersion) {
82 if (error != nullptr) {
83 std::stringstream ss;
84 ss << "Framework is incompatible with kernel version " << version()
85 << ", compatible kernel versions are";
86 for (const MatrixKernel& matrixKernel : kernels) ss << " " << matrixKernel.minLts();
87 *error = ss.str();
88 }
Yifan Hong1e8febd2019-08-07 16:17:19 -070089 return {};
Yifan Hong90ed9972018-12-03 15:08:34 -080090 }
Yifan Hong1e8febd2019-08-07 16:17:19 -070091 if (result.empty()) {
92 // This means matchKernelVersion passes but matchKernelConfigs(conditions) fails.
Yifan Hong90ed9972018-12-03 15:08:34 -080093 // This should not happen because first <conditions> for each <kernel> must be
94 // empty. Reject here for inconsistency.
95 if (error != nullptr) {
96 error->insert(0, "Framework match kernel version with unmet conditions:");
97 }
Yifan Hong1e8febd2019-08-07 16:17:19 -070098 return {};
Yifan Hong90ed9972018-12-03 15:08:34 -080099 }
100 if (error != nullptr) {
101 error->clear();
102 }
Yifan Hong1e8febd2019-08-07 16:17:19 -0700103 return result;
Yifan Hong90ed9972018-12-03 15:08:34 -0800104}
105
Yifan Honga45f77d2018-12-03 16:42:52 -0800106bool KernelInfo::operator==(const KernelInfo& other) const {
107 return mVersion == other.mVersion && mConfigs == other.mConfigs;
108}
109
Yifan Hong90ed9972018-12-03 15:08:34 -0800110} // namespace vintf
111} // namespace android