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