1 /* 2 * Copyright (C) 2017 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 17 18 #ifndef ANDROID_VINTF_HAL_MANIFEST_H 19 #define ANDROID_VINTF_HAL_MANIFEST_H 20 21 #include <utils/Errors.h> 22 #include <map> 23 #include <optional> 24 #include <string> 25 #include <vector> 26 27 #include <hidl/metadata.h> 28 29 #include "CheckFlags.h" 30 #include "FileSystem.h" 31 #include "HalGroup.h" 32 #include "KernelInfo.h" 33 #include "Level.h" 34 #include "ManifestHal.h" 35 #include "ManifestInstance.h" 36 #include "MapValueIterator.h" 37 #include "SchemaType.h" 38 #include "SystemSdk.h" 39 #include "VendorNdk.h" 40 #include "Version.h" 41 #include "Vndk.h" 42 #include "XmlFileGroup.h" 43 44 namespace android { 45 namespace vintf { 46 47 struct MatrixHal; 48 struct CompatibilityMatrix; 49 50 namespace details { 51 using InstancesOfVersion = 52 std::map<std::string /* interface */, std::set<std::string /* instance */>>; 53 using Instances = std::map<Version, InstancesOfVersion>; 54 } // namespace details 55 56 // A HalManifest is reported by the hardware and query-able from 57 // framework code. This is the API for the framework. 58 struct HalManifest : public HalGroup<ManifestHal>, public XmlFileGroup<ManifestXmlFile> { 59 public: 60 61 // Construct a device HAL manifest. HalManifestHalManifest62 HalManifest() : mType(SchemaType::DEVICE) {} 63 64 bool add(ManifestHal&& hal) override; 65 66 // Given a component name (e.g. "android.hardware.camera"), 67 // return getHal(name)->transport if the component exist and v exactly matches 68 // one of the versions in that component, else EMPTY 69 Transport getHidlTransport(const std::string& name, const Version& v, 70 const std::string& interfaceName, 71 const std::string& instanceName) const; 72 73 // Check compatibility against a compatibility matrix. Considered compatible if 74 // - framework manifest vs. device compat-mat 75 // - checkIncompatibility for HALs returns only optional HALs 76 // - one of manifest.vndk match compat-mat.vndk 77 // - device manifest vs. framework compat-mat 78 // - checkIncompatibility for HALs returns only optional HALs 79 // - manifest.sepolicy.version match one of compat-mat.sepolicy.sepolicy-version 80 bool checkCompatibility(const CompatibilityMatrix& mat, std::string* error = nullptr, 81 CheckFlags::Type flags = CheckFlags::DEFAULT) const; 82 83 // Generate a compatibility matrix such that checkCompatibility will return true. 84 CompatibilityMatrix generateCompatibleMatrix() const; 85 86 // Returns all component names. 87 std::set<std::string> getHalNames() const; 88 89 // Returns all component names and versions, e.g. 90 // "android.hardware.camera.device@1.0", "android.hardware.camera.device@3.2", 91 // "android.hardware.nfc@1.0"] 92 // For AIDL HALs, versions are stripped away. 93 std::set<std::string> getHalNamesAndVersions() const; 94 95 // Type of the manifest. FRAMEWORK or DEVICE. 96 SchemaType type() const; 97 void setType(SchemaType type); 98 99 // FCM version that it implements. 100 Level level() const; 101 102 // device.mSepolicyVersion. Assume type == device. 103 // Abort if type != device. 104 const Version &sepolicyVersion() const; 105 106 // framework.mVendorNdks. Assume type == framework. 107 // Abort if type != framework. 108 const std::vector<VendorNdk>& vendorNdks() const; 109 110 // If the corresponding <xmlfile> with the given version exists, 111 // - Return the overridden <path> if it is present, 112 // - otherwise the default value: /{system,vendor}/etc/<name>_V<major>_<minor>.xml 113 // Otherwise if the <xmlfile> entry does not exist, "" is returned. 114 std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const; 115 116 // Get metaversion of this manifest. 117 Version getMetaVersion() const; 118 119 // Alternative to forEachInstance if you just need a set of instance names instead. 120 std::set<std::string> getHidlInstances(const std::string& package, const Version& version, 121 const std::string& interfaceName) const; 122 std::set<std::string> getAidlInstances(const std::string& package, 123 const std::string& interfaceName) const; 124 125 // Return whether instance is in getHidlInstances(...). 126 bool hasHidlInstance(const std::string& package, const Version& version, 127 const std::string& interfaceName, const std::string& instance) const; 128 129 // Return whether a given AIDL instance is in this manifest. 130 bool hasAidlInstance(const std::string& package, const std::string& interfaceName, 131 const std::string& instance) const; 132 133 // Insert the given instance. After inserting it, the instance will be available via 134 // forEachInstance* functions. This modifies the manifest. 135 // Return whether this operation is successful. 136 bool insertInstance(const FqInstance& fqInstance, Transport transport, Arch arch, HalFormat fmt, 137 std::string* error = nullptr); 138 139 // Add everything from another manifest. If no errors (return true), it is guaranteed 140 // that other->empty() == true after execution. 141 [[nodiscard]] bool addAll(HalManifest* other, std::string* error = nullptr); 142 143 protected: 144 // Check before add() 145 bool shouldAdd(const ManifestHal& toAdd) const override; 146 bool shouldAddXmlFile(const ManifestXmlFile& toAdd) const override; 147 148 bool forEachInstanceOfVersion( 149 HalFormat format, const std::string& package, const Version& expectVersion, 150 const std::function<bool(const ManifestInstance&)>& func) const override; 151 152 private: 153 friend struct HalManifestConverter; 154 friend class VintfObject; 155 friend class AssembleVintfImpl; 156 friend struct LibVintfTest; 157 friend std::string dump(const HalManifest &vm); 158 friend bool operator==(const HalManifest &lft, const HalManifest &rgt); 159 160 status_t fetchAllInformation(const FileSystem* fileSystem, const std::string& path, 161 std::string* error = nullptr); 162 163 details::Instances expandInstances(const std::string& name) const; 164 // Check if all instances in matrixHal is supported in this manifest. 165 bool isCompatible(const details::Instances& instances, const MatrixHal& matrixHal) const; 166 167 // Return a list of error messages (for each <hal> name) that does NOT conform to 168 // the given compatibility matrix. It does not contain components that are optional. 169 // That is, return empty list iff 170 // (instance in matrix) => (instance in manifest). 171 std::vector<std::string> checkIncompatibleHals(const CompatibilityMatrix& mat) const; 172 173 void removeHals(const std::string& name, size_t majorVer); 174 175 // Returns a list of instance names that are in this manifest but 176 // are not specified in the given matrix, whether the HAL is specified as an optional or 177 // required HAL. 178 // That is, return empty list iff 179 // (instance in manifest) => (instance in matrix). 180 std::set<std::string> checkUnusedHals( 181 const CompatibilityMatrix& mat, 182 const std::vector<HidlInterfaceMetadata>& hidlMetadata) const; 183 184 // Check that manifest has no entries. 185 bool empty() const; 186 187 // Alternative to forEachInstance if you just need a set of instance names instead. 188 std::set<std::string> getInstances(HalFormat format, const std::string& package, 189 const Version& version, 190 const std::string& interfaceName) const; 191 192 // Return whether instance is in getInstances(...). 193 bool hasInstance(HalFormat format, const std::string& package, const Version& version, 194 const std::string& interfaceName, const std::string& instance) const; 195 196 // Get the <kernel> tag. Assumes type() == DEVICE. 197 // - On host, <kernel> tag only exists for the fully assembled HAL manifest. 198 // - On device, this only contain information about level(). Other information should be 199 // looked up via RuntimeInfo. 200 const std::optional<KernelInfo>& kernel() const; 201 202 // Merge information of other to this. 203 bool mergeKernel(std::optional<KernelInfo>* other, std::string* error = nullptr); 204 205 // Whether the manifest contains information about the kernel for compatibility checks. 206 // True if kernel()->checkCompatibility can be called. 207 bool shouldCheckKernelCompatibility() const; 208 209 SchemaType mType; 210 Level mLevel = Level::UNSPECIFIED; 211 212 // entries for device hal manifest only 213 struct { 214 Version mSepolicyVersion; 215 std::optional<KernelInfo> mKernel; 216 } device; 217 218 // entries for framework hal manifest only 219 struct { 220 #pragma clang diagnostic push 221 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 222 std::vector<Vndk> mVndks; 223 #pragma clang diagnostic pop 224 225 std::vector<VendorNdk> mVendorNdks; 226 SystemSdk mSystemSdk; 227 } framework; 228 }; 229 230 231 } // namespace vintf 232 } // namespace android 233 234 #endif // ANDROID_VINTF_HAL_MANIFEST_H 235