123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- /*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifndef ANDROID_VINTF_HAL_GROUP_H
- #define ANDROID_VINTF_HAL_GROUP_H
- #include <map>
- #include <set>
- #include "MapValueIterator.h"
- #include "Version.h"
- namespace android {
- namespace vintf {
- // A HalGroup is a wrapped multimap from name to Hal.
- // Hal.getName() must return a string indicating the name.
- template <typename Hal>
- struct HalGroup {
- using InstanceType = typename Hal::InstanceType;
- public:
- virtual ~HalGroup() {}
- // Move all hals from another HalGroup to this.
- bool addAllHals(HalGroup* other, std::string* error = nullptr) {
- for (auto& pair : other->mHals) {
- if (!add(std::move(pair.second))) {
- if (error) {
- *error = "HAL \"" + pair.first + "\" has a conflict.";
- }
- return false;
- }
- }
- other->mHals.clear();
- return true;
- }
- // Add an hal to this HalGroup so that it can be constructed programatically.
- virtual bool add(Hal&& hal) { return addInternal(std::move(hal)) != nullptr; }
- protected:
- // Get all hals with the given name (e.g "android.hardware.camera").
- // There could be multiple hals that matches the same given name.
- std::vector<const Hal*> getHals(const std::string& name) const {
- std::vector<const Hal*> ret;
- auto range = mHals.equal_range(name);
- for (auto it = range.first; it != range.second; ++it) {
- ret.push_back(&it->second);
- }
- return ret;
- }
- // Get all hals with the given name (e.g "android.hardware.camera").
- // There could be multiple hals that matches the same given name.
- // Non-const version of the above getHals() method.
- std::vector<Hal*> getHals(const std::string& name) {
- std::vector<Hal*> ret;
- auto range = mHals.equal_range(name);
- for (auto it = range.first; it != range.second; ++it) {
- ret.push_back(&it->second);
- }
- return ret;
- }
- public:
- // Apply func to all instances.
- bool forEachInstance(const std::function<bool(const InstanceType&)>& func) const {
- for (const auto& hal : getHals()) {
- bool cont = hal.forEachInstance(func);
- if (!cont) return false;
- }
- return true;
- }
- bool forEachInstanceOfPackage(const std::string& package,
- const std::function<bool(const InstanceType&)>& func) const {
- for (const auto* hal : getHals(package)) {
- if (!hal->forEachInstance(func)) {
- return false;
- }
- }
- return true;
- }
- // Apply func to all instances of package@expectVersion::*/*.
- // For example, if [email protected]::IFoo/default is in "this" and getFqInstances
- // is called with [email protected], then [email protected]::IFoo/default is returned.
- virtual bool forEachInstanceOfVersion(
- const std::string& package, const Version& expectVersion,
- const std::function<bool(const InstanceType&)>& func) const = 0;
- // Apply func to instances of package@expectVersion::interface/*.
- // For example, if [email protected]::IFoo/default is in "this" and getFqInstances
- // is called with [email protected]::IFoo, then [email protected]::IFoo/default is returned.
- bool forEachInstanceOfInterface(const std::string& package, const Version& expectVersion,
- const std::string& interface,
- const std::function<bool(const InstanceType&)>& func) const {
- return forEachInstanceOfVersion(package, expectVersion,
- [&func, &interface](const InstanceType& e) {
- if (e.interface() == interface) {
- return func(e);
- }
- return true;
- });
- }
- // Alternative to forEachInstanceOfInterface if you need a vector instead.
- // If interface is empty, returns all instances of package@version;
- // else return all instances of package@version::interface.
- std::vector<InstanceType> getFqInstances(const std::string& package,
- const Version& expectVersion,
- const std::string& interface = "") const {
- std::vector<InstanceType> v;
- auto mapToVector = [&v](const auto& e) {
- v.push_back(e);
- return true;
- };
- if (interface.empty()) {
- (void)forEachInstanceOfVersion(package, expectVersion, mapToVector);
- } else {
- (void)forEachInstanceOfInterface(package, expectVersion, interface, mapToVector);
- }
- return v;
- }
- protected:
- // sorted map from component name to the component.
- // The component name looks like: android.hardware.foo
- std::multimap<std::string, Hal> mHals;
- // override this to filter for add.
- virtual bool shouldAdd(const Hal&) const { return true; }
- // Return an iterable to all Hal objects. Call it as follows:
- // for (const auto& e : vm.getHals()) { }
- ConstMultiMapValueIterable<std::string, Hal> getHals() const { return iterateValues(mHals); }
- // Return an iterable to all Hal objects. Call it as follows:
- // for (const auto& e : vm.getHals()) { }
- MultiMapValueIterable<std::string, Hal> getHals() { return iterateValues(mHals); }
- // Get any HAL component based on the component name. Return any one
- // if multiple. Return nullptr if the component does not exist. This is only
- // for creating objects programatically.
- // The component name looks like:
- // android.hardware.foo
- Hal* getAnyHal(const std::string& name) {
- auto it = mHals.find(name);
- if (it == mHals.end()) {
- return nullptr;
- }
- return &(it->second);
- }
- Hal* addInternal(Hal&& hal) {
- if (!shouldAdd(hal)) {
- return nullptr;
- }
- std::string name = hal.getName();
- auto it = mHals.emplace(std::move(name), std::move(hal)); // always succeeds
- return &it->second;
- }
- };
- } // namespace vintf
- } // namespace android
- #endif // ANDROID_VINTF_HAL_GROUP_H
|