diff options
Diffstat (limited to 'HalManifest.cpp')
-rw-r--r-- | HalManifest.cpp | 127 |
1 files changed, 37 insertions, 90 deletions
diff --git a/HalManifest.cpp b/HalManifest.cpp index a27e935..aee4462 100644 --- a/HalManifest.cpp +++ b/HalManifest.cpp | |||
@@ -177,13 +177,6 @@ std::set<Version> HalManifest::getSupportedVersions(const std::string &name) con | |||
177 | return ret; | 177 | return ret; |
178 | } | 178 | } |
179 | 179 | ||
180 | bool HalManifest::hasInstance(const std::string& halName, const Version& version, | ||
181 | const std::string& interfaceName, | ||
182 | const std::string& instanceName) const { | ||
183 | const auto& instances = getInstances(halName, version, interfaceName); | ||
184 | return instances.find(instanceName) != instances.end(); | ||
185 | } | ||
186 | |||
187 | bool HalManifest::forEachInstanceOfVersion( | 180 | bool HalManifest::forEachInstanceOfVersion( |
188 | const std::string& package, const Version& expectVersion, | 181 | const std::string& package, const Version& expectVersion, |
189 | const std::function<bool(const ManifestInstance&)>& func) const { | 182 | const std::function<bool(const ManifestInstance&)>& func) const { |
@@ -199,89 +192,12 @@ bool HalManifest::forEachInstanceOfVersion( | |||
199 | return true; | 192 | return true; |
200 | } | 193 | } |
201 | 194 | ||
202 | static bool satisfyVersion(const MatrixHal& matrixHal, const Version& manifestHalVersion) { | ||
203 | for (const VersionRange &matrixVersionRange : matrixHal.versionRanges) { | ||
204 | // If Compatibility Matrix says 2.5-2.7, the "2.7" is purely informational; | ||
205 | // the framework can work with all 2.5-2.infinity. | ||
206 | if (matrixVersionRange.supportedBy(manifestHalVersion)) { | ||
207 | return true; | ||
208 | } | ||
209 | } | ||
210 | return false; | ||
211 | } | ||
212 | |||
213 | // Check if matrixHal.interfaces is a subset of instancesOfVersion | ||
214 | static bool satisfyAllInstances(const MatrixHal& matrixHal, | ||
215 | const InstancesOfVersion &instancesOfVersion) { | ||
216 | for (const auto& matrixHalInterfacePair : matrixHal.interfaces) { | ||
217 | const std::string& interface = matrixHalInterfacePair.first; | ||
218 | auto it = instancesOfVersion.find(interface); | ||
219 | if (it == instancesOfVersion.end()) { | ||
220 | return false; | ||
221 | } | ||
222 | const std::set<std::string>& manifestInterfaceInstances = it->second; | ||
223 | const std::set<std::string>& matrixInterfaceInstances = | ||
224 | matrixHalInterfacePair.second.instances; | ||
225 | if (!std::includes(manifestInterfaceInstances.begin(), manifestInterfaceInstances.end(), | ||
226 | matrixInterfaceInstances.begin(), matrixInterfaceInstances.end())) { | ||
227 | return false; | ||
228 | } | ||
229 | } | ||
230 | return true; | ||
231 | } | ||
232 | |||
233 | Instances HalManifest::expandInstances(const std::string& name) const { | ||
234 | Instances instances; | ||
235 | // Do the cross product version x interface x instance and sort them, | ||
236 | // because interfaces / instances can span in multiple HALs. | ||
237 | // This is efficient for small <hal> entries. | ||
238 | for (const ManifestHal* manifestHal : getHals(name)) { | ||
239 | for (const Version& manifestHalVersion : manifestHal->versions) { | ||
240 | instances[manifestHalVersion] = {}; | ||
241 | for (const auto& halInterfacePair : manifestHal->interfaces) { | ||
242 | const std::string& interface = halInterfacePair.first; | ||
243 | const auto& toAdd = halInterfacePair.second.instances; | ||
244 | instances[manifestHalVersion][interface].insert(toAdd.begin(), toAdd.end()); | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | return instances; | ||
249 | } | ||
250 | |||
251 | bool HalManifest::isCompatible(const Instances& instances, const MatrixHal& matrixHal) const { | ||
252 | for (const auto& instanceMapPair : instances) { | ||
253 | const Version& manifestHalVersion = instanceMapPair.first; | ||
254 | const InstancesOfVersion& instancesOfVersion = instanceMapPair.second; | ||
255 | if (!satisfyVersion(matrixHal, manifestHalVersion)) { | ||
256 | continue; | ||
257 | } | ||
258 | if (!satisfyAllInstances(matrixHal, instancesOfVersion)) { | ||
259 | continue; | ||
260 | } | ||
261 | return true; // match! | ||
262 | } | ||
263 | return false; | ||
264 | } | ||
265 | |||
266 | static std::vector<std::string> toLines(const Instances& allInstances) { | ||
267 | std::vector<std::string> lines; | ||
268 | for (const auto& pair : allInstances) { | ||
269 | const auto& version = pair.first; | ||
270 | for (const auto& ifacePair : pair.second) { | ||
271 | const auto& interface = ifacePair.first; | ||
272 | for (const auto& instance : ifacePair.second) { | ||
273 | lines.push_back(toFQNameString(version, interface, instance)); | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | return lines; | ||
278 | } | ||
279 | |||
280 | // indent = 2, {"foo"} => "foo" | 195 | // indent = 2, {"foo"} => "foo" |
281 | // indent = 2, {"foo", "bar"} => "\n foo\n bar"; | 196 | // indent = 2, {"foo", "bar"} => "\n foo\n bar"; |
282 | void multilineIndent(std::ostream& os, size_t indent, const std::vector<std::string>& lines) { | 197 | template <typename Container> |
198 | void multilineIndent(std::ostream& os, size_t indent, const Container& lines) { | ||
283 | if (lines.size() == 1) { | 199 | if (lines.size() == 1) { |
284 | os << lines.front(); | 200 | os << *lines.begin(); |
285 | return; | 201 | return; |
286 | } | 202 | } |
287 | for (const auto& line : lines) { | 203 | for (const auto& line : lines) { |
@@ -298,13 +214,29 @@ std::vector<std::string> HalManifest::checkIncompatibleHals(const CompatibilityM | |||
298 | if (matrixHal.optional) { | 214 | if (matrixHal.optional) { |
299 | continue; | 215 | continue; |
300 | } | 216 | } |
301 | auto manifestInstances = expandInstances(matrixHal.name); | 217 | |
302 | if (!isCompatible(manifestInstances, matrixHal)) { | 218 | std::set<FqInstance> manifestInstances; |
219 | std::set<FqInstance> manifestInstancesNoPackage; | ||
220 | std::set<Version> versions; | ||
221 | for (const ManifestHal* manifestHal : getHals(matrixHal.name)) { | ||
222 | manifestHal->forEachInstance([&](const auto& manifestInstance) { | ||
223 | manifestInstances.insert(manifestInstance.getFqInstance()); | ||
224 | manifestInstancesNoPackage.insert(manifestInstance.getFqInstanceNoPackage()); | ||
225 | return true; | ||
226 | }); | ||
227 | manifestHal->appendAllVersions(&versions); | ||
228 | } | ||
229 | |||
230 | if (!matrixHal.isCompatible(manifestInstances, versions)) { | ||
303 | std::ostringstream oss; | 231 | std::ostringstream oss; |
304 | oss << matrixHal.name << ":\n required: "; | 232 | oss << matrixHal.name << ":\n required: "; |
305 | multilineIndent(oss, 8, android::vintf::expandInstances(matrixHal)); | 233 | multilineIndent(oss, 8, android::vintf::expandInstances(matrixHal)); |
306 | oss << "\n provided: "; | 234 | oss << "\n provided: "; |
307 | multilineIndent(oss, 8, toLines(manifestInstances)); | 235 | if (manifestInstances.empty()) { |
236 | multilineIndent(oss, 8, versions); | ||
237 | } else { | ||
238 | multilineIndent(oss, 8, manifestInstancesNoPackage); | ||
239 | } | ||
308 | 240 | ||
309 | ret.insert(ret.end(), oss.str()); | 241 | ret.insert(ret.end(), oss.str()); |
310 | } | 242 | } |
@@ -312,6 +244,21 @@ std::vector<std::string> HalManifest::checkIncompatibleHals(const CompatibilityM | |||
312 | return ret; | 244 | return ret; |
313 | } | 245 | } |
314 | 246 | ||
247 | std::set<std::string> HalManifest::checkUnusedHals(const CompatibilityMatrix& mat) const { | ||
248 | std::set<std::string> ret; | ||
249 | |||
250 | forEachInstance([&ret, &mat](const auto& manifestInstance) { | ||
251 | const auto& fqInstance = manifestInstance.getFqInstance(); | ||
252 | if (!mat.hasInstance(fqInstance.getPackage(), fqInstance.getVersion(), | ||
253 | fqInstance.getInterface(), fqInstance.getInstance())) { | ||
254 | ret.insert(fqInstance.string()); | ||
255 | } | ||
256 | return true; | ||
257 | }); | ||
258 | |||
259 | return ret; | ||
260 | } | ||
261 | |||
315 | static bool checkVendorNdkCompatibility(const VendorNdk& matVendorNdk, | 262 | static bool checkVendorNdkCompatibility(const VendorNdk& matVendorNdk, |
316 | const std::vector<VendorNdk>& manifestVendorNdk, | 263 | const std::vector<VendorNdk>& manifestVendorNdk, |
317 | std::string* error) { | 264 | std::string* error) { |