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