| /* |
| * 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_MANIFEST_H |
| #define ANDROID_VINTF_HAL_MANIFEST_H |
| |
| #include <utils/Errors.h> |
| #include <map> |
| #include <optional> |
| #include <string> |
| #include <vector> |
| |
| #include "CheckFlags.h" |
| #include "FileSystem.h" |
| #include "HalGroup.h" |
| #include "KernelInfo.h" |
| #include "Level.h" |
| #include "ManifestHal.h" |
| #include "ManifestInstance.h" |
| #include "MapValueIterator.h" |
| #include "SchemaType.h" |
| #include "SystemSdk.h" |
| #include "VendorNdk.h" |
| #include "Version.h" |
| #include "Vndk.h" |
| #include "XmlFileGroup.h" |
| |
| namespace android { |
| namespace vintf { |
| |
| struct MatrixHal; |
| struct CompatibilityMatrix; |
| |
| namespace details { |
| using InstancesOfVersion = |
| std::map<std::string /* interface */, std::set<std::string /* instance */>>; |
| using Instances = std::map<Version, InstancesOfVersion>; |
| } // namespace details |
| |
| // A HalManifest is reported by the hardware and query-able from |
| // framework code. This is the API for the framework. |
| struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> { |
| public: |
| |
| // Construct a device HAL manifest. |
| HalManifest() : mType(SchemaType::DEVICE) {} |
| |
| bool add(ManifestHal&& hal) override; |
| |
| // Given a component name (e.g. "android.hardware.camera"), |
| // return getHal(name)->transport if the component exist and v exactly matches |
| // one of the versions in that component, else EMPTY |
| Transport getHidlTransport(const std::string& name, const Version& v, |
| const std::string& interfaceName, |
| const std::string& instanceName) const; |
| |
| // Check compatibility against a compatibility matrix. Considered compatible if |
| // - framework manifest vs. device compat-mat |
| // - checkIncompatibility for HALs returns only optional HALs |
| // - one of manifest.vndk match compat-mat.vndk |
| // - device manifest vs. framework compat-mat |
| // - checkIncompatibility for HALs returns only optional HALs |
| // - manifest.sepolicy.version match one of compat-mat.sepolicy.sepolicy-version |
| bool checkCompatibility(const CompatibilityMatrix& mat, std::string* error = nullptr, |
| CheckFlags::Type flags = CheckFlags::DEFAULT) const; |
| |
| // Generate a compatibility matrix such that checkCompatibility will return true. |
| CompatibilityMatrix generateCompatibleMatrix() const; |
| |
| // Returns all component names. |
| std::set<std::string> getHalNames() const; |
| |
| // Returns all component names and versions, e.g. |
| // "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2", |
| // "android.hardware.nfc@1.0"] |
| // For AIDL HALs, versions are stripped away. |
| std::set<std::string> getHalNamesAndVersions() const; |
| |
| // Type of the manifest. FRAMEWORK or DEVICE. |
| SchemaType type() const; |
| void setType(SchemaType type); |
| |
| // FCM version that it implements. |
| Level level() const; |
| |
| // device.mSepolicyVersion. Assume type == device. |
| // Abort if type != device. |
| const Version &sepolicyVersion() const; |
| |
| // framework.mVendorNdks. Assume type == framework. |
| // Abort if type != framework. |
| const std::vector<VendorNdk>& vendorNdks() const; |
| |
| // If the corresponding <xmlfile> with the given version exists, |
| // - Return the overridden <path> if it is present, |
| // - otherwise the default value: /{system,vendor}/etc/<name>_V<major>_<minor>.xml |
| // Otherwise if the <xmlfile> entry does not exist, "" is returned. |
| std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const; |
| |
| // Get metaversion of this manifest. |
| Version getMetaVersion() const; |
| |
| // Alternative to forEachInstance if you just need a set of instance names instead. |
| std::set<std::string> getHidlInstances(const std::string& package, const Version& version, |
| const std::string& interfaceName) const; |
| std::set<std::string> getAidlInstances(const std::string& package, |
| const std::string& interfaceName) const; |
| |
| // Return whether instance is in getHidlInstances(...). |
| bool hasHidlInstance(const std::string& package, const Version& version, |
| const std::string& interfaceName, const std::string& instance) const; |
| |
| // Return whether a given AIDL instance is in this manifest. |
| bool hasAidlInstance(const std::string& package, const std::string& interfaceName, |
| const std::string& instance) const; |
| |
| // Insert the given instance. After inserting it, the instance will be available via |
| // forEachInstance* functions. This modifies the manifest. |
| // Return whether this operation is successful. |
| bool insertInstance(const FqInstance& fqInstance, Transport transport, Arch arch, HalFormat fmt, |
| std::string* error = nullptr); |
| |
| // Add everything from another manifest. If no errors (return true), it is guaranteed |
| // that other->empty() == true after execution. |
| [[nodiscard]] bool addAll(HalManifest* other, std::string* error = nullptr); |
| |
| protected: |
| // Check before add() |
| bool shouldAdd(const ManifestHal& toAdd) const override; |
| bool shouldAddXmlFile(const ManifestXmlFile& toAdd) const override; |
| |
| bool forEachInstanceOfVersion( |
| HalFormat format, const std::string& package, const Version& expectVersion, |
| const std::function<bool(const ManifestInstance&)>& func) const override; |
| |
| private: |
| friend struct HalManifestConverter; |
| friend class VintfObject; |
| friend class AssembleVintfImpl; |
| friend struct LibVintfTest; |
| friend std::string dump(const HalManifest &vm); |
| friend bool operator==(const HalManifest &lft, const HalManifest &rgt); |
| |
| status_t fetchAllInformation(const FileSystem* fileSystem, const std::string& path, |
| std::string* error = nullptr); |
| |
| details::Instances expandInstances(const std::string& name) const; |
| // Check if all instances in matrixHal is supported in this manifest. |
| bool isCompatible(const details::Instances& instances, const MatrixHal& matrixHal) const; |
| |
| // Return a list of error messages (for each <hal> name) that does NOT conform to |
| // the given compatibility matrix. It does not contain components that are optional. |
| // That is, return empty list iff |
| // (instance in matrix) => (instance in manifest). |
| std::vector<std::string> checkIncompatibleHals(const CompatibilityMatrix& mat) const; |
| |
| void removeHals(const std::string& name, size_t majorVer); |
| |
| // Returns a list of instance names that are in this manifest but |
| // are not specified in the given matrix, whether the HAL is specified as an optional or |
| // required HAL. |
| // That is, return empty list iff |
| // (instance in manifest) => (instance in matrix). |
| std::set<std::string> checkUnusedHals(const CompatibilityMatrix& mat) const; |
| |
| // Check that manifest has no entries. |
| bool empty() const; |
| |
| // Alternative to forEachInstance if you just need a set of instance names instead. |
| std::set<std::string> getInstances(HalFormat format, const std::string& package, |
| const Version& version, |
| const std::string& interfaceName) const; |
| |
| // Return whether instance is in getInstances(...). |
| bool hasInstance(HalFormat format, const std::string& package, const Version& version, |
| const std::string& interfaceName, const std::string& instance) const; |
| |
| // Get the <kernel> tag. Assumes type() == DEVICE. |
| // - On host, <kernel> tag only exists for the fully assembled HAL manifest. |
| // - On device, this only contain information about level(). Other information should be |
| // looked up via RuntimeInfo. |
| const std::optional<KernelInfo>& kernel() const; |
| |
| // Merge information of other to this. |
| bool mergeKernel(std::optional<KernelInfo>* other, std::string* error = nullptr); |
| |
| // Whether the manifest contains information about the kernel for compatibility checks. |
| // True if kernel()->checkCompatibility can be called. |
| bool shouldCheckKernelCompatibility() const; |
| |
| SchemaType mType; |
| Level mLevel = Level::UNSPECIFIED; |
| |
| // entries for device hal manifest only |
| struct { |
| Version mSepolicyVersion; |
| std::optional<KernelInfo> mKernel; |
| } device; |
| |
| // entries for framework hal manifest only |
| struct { |
| #pragma clang diagnostic push |
| #pragma clang diagnostic ignored "-Wdeprecated-declarations" |
| std::vector<Vndk> mVndks; |
| #pragma clang diagnostic pop |
| |
| std::vector<VendorNdk> mVendorNdks; |
| SystemSdk mSystemSdk; |
| } framework; |
| }; |
| |
| |
| } // namespace vintf |
| } // namespace android |
| |
| #endif // ANDROID_VINTF_HAL_MANIFEST_H |