blob: b9dfd9c63ca31076ebf2d300415f9514f1587c01 [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
63bool KernelInfo::matchKernelRequirements(const std::vector<MatrixKernel>& kernels,
64 std::string* error) const {
65 bool foundMatchedKernelVersion = false;
66 bool foundMatchedConditions = false;
67 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 }
76 foundMatchedConditions = true;
77 if (!matchKernelConfigs(matrixKernel.configs(), error)) {
78 return false;
79 }
80 }
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 }
89 return false;
90 }
91 if (!foundMatchedConditions) {
92 // This should not happen because first <conditions> for each <kernel> must be
93 // empty. Reject here for inconsistency.
94 if (error != nullptr) {
95 error->insert(0, "Framework match kernel version with unmet conditions:");
96 }
97 return false;
98 }
99 if (error != nullptr) {
100 error->clear();
101 }
102 return true;
103}
104
105} // namespace vintf
106} // namespace android