• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
20 namespace android {
21 namespace vintf {
22 
version() const23 const KernelVersion& KernelInfo::version() const {
24     return mVersion;
25 }
26 
configs() const27 const std::map<std::string, std::string>& KernelInfo::configs() const {
28     return mConfigs;
29 }
30 
matchKernelConfigs(const std::vector<KernelConfig> & matrixConfigs,std::string * error) const31 bool 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 
matchKernelVersion(const KernelVersion & minLts) const58 bool KernelInfo::matchKernelVersion(const KernelVersion& minLts) const {
59     return minLts.version == mVersion.version && minLts.majorRev == mVersion.majorRev &&
60            minLts.minorRev <= mVersion.minorRev;
61 }
62 
matchKernelRequirements(const std::vector<MatrixKernel> & kernels,std::string * error) const63 bool 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 
operator ==(const KernelInfo & other) const105 bool KernelInfo::operator==(const KernelInfo& other) const {
106     return mVersion == other.mVersion && mConfigs == other.mConfigs;
107 }
108 
109 }  // namespace vintf
110 }  // namespace android
111