/* * 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 #include #include #include #include #include #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 "WithFileName.h" #include "XmlFileGroup.h" namespace android { namespace vintf { struct MatrixHal; struct CompatibilityMatrix; namespace details { using InstancesOfVersion = std::map>; using Instances = std::map; } // 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, public XmlFileGroup, public WithFileName { public: // Construct a device HAL manifest. HalManifest() : mType(SchemaType::DEVICE) {} bool add(ManifestHal&& hal, std::string* error = nullptr) override; // Move all hals from another HalManifest to this. bool addAllHals(HalManifest* other, std::string* error = nullptr); // 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 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 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& vendorNdks() const; // If the corresponding with the given version exists, // - Return the overridden if it is present, // - otherwise the default value: /{system,vendor}/etc/_V_.xml // Otherwise if the 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 getHidlInstances(const std::string& package, const Version& version, const std::string& interfaceName) const; std::set 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, std::string* error) const; bool shouldAddXmlFile(const ManifestXmlFile& toAdd) const override; bool forEachInstanceOfVersion( HalFormat format, const std::string& package, const Version& expectVersion, const std::function& 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 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 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 checkUnusedHals( const CompatibilityMatrix& mat, const std::vector& hidlMetadata) 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 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 tag. Assumes type() == DEVICE. // - On host, 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& kernel() const; // Merge information of other to this. bool mergeKernel(std::optional* 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 mKernel; } device; // entries for framework hal manifest only struct { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" std::vector mVndks; #pragma clang diagnostic pop std::vector mVendorNdks; SystemSdk mSystemSdk; } framework; }; } // namespace vintf } // namespace android #endif // ANDROID_VINTF_HAL_MANIFEST_H