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(bool optional = true) 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 // For AIDL HALs, versions are stripped away. 103 std::set<std::string> getHalNamesAndVersions() const; 104 105 // Type of the manifest. FRAMEWORK or DEVICE. 106 SchemaType type() const; 107 void setType(SchemaType type); 108 109 // FCM version that it implements. 110 Level level() const; 111 112 // device.mSepolicyVersion. Assume type == device. 113 // Abort if type != device. 114 const SepolicyVersion& sepolicyVersion() const; 115 116 // framework.mVendorNdks. Assume type == framework. 117 // Abort if type != framework. 118 const std::vector<VendorNdk>& vendorNdks() const; 119 120 // If the corresponding <xmlfile> with the given version exists, 121 // - Return the overridden <path> if it is present, 122 // - otherwise the default value: /{system,vendor}/etc/<name>_V<major>_<minor>.xml 123 // Otherwise if the <xmlfile> entry does not exist, "" is returned. 124 std::string getXmlFilePath(const std::string& xmlFileName, const Version& version) const; 125 126 // Alternative to forEachInstance if you just need a set of instance names instead. 127 std::set<std::string> getHidlInstances(const std::string& package, const Version& version, 128 const std::string& interfaceName) const; 129 std::set<std::string> getAidlInstances(const std::string& package, size_t version, 130 const std::string& interfaceName) const; 131 std::set<std::string> getAidlInstances(const std::string& package, 132 const std::string& interfaceName) const; 133 std::set<std::string> getNativeInstances(const std::string& package) const; 134 135 // Return whether instance is in getHidlInstances(...). 136 bool hasHidlInstance(const std::string& package, const Version& version, 137 const std::string& interfaceName, const std::string& instance) const; 138 139 // Return whether a given AIDL instance is in this manifest with version >= the given version. 140 bool hasAidlInstance(const std::string& package, size_t version, 141 const std::string& interfaceName, const std::string& instance) const; 142 143 // Return whether a given AIDL instance is in this manifest with any version. 144 bool hasAidlInstance(const std::string& package, const std::string& interfaceName, 145 const std::string& instance) const; 146 147 // Return whether a given native instance is in getNativeInstances(...). 148 bool hasNativeInstance(const std::string& package, const std::string& instance) const; 149 150 // Insert the given instance. After inserting it, the instance will be available via 151 // forEachInstance* functions. This modifies the manifest. 152 // Return whether this operation is successful. 153 bool insertInstance(const FqInstance& fqInstance, Transport transport, Arch arch, HalFormat fmt, 154 std::string* error = nullptr); 155 156 // Add everything from another manifest. If no errors (return true), it is guaranteed 157 // that other->empty() == true after execution. 158 [[nodiscard]] bool addAll(HalManifest* other, std::string* error = nullptr); 159 160 protected: 161 // Check before add() 162 bool shouldAdd(const ManifestHal& toAdd, std::string* error) const; 163 bool shouldAddXmlFile(const ManifestXmlFile& toAdd) const override; 164 165 bool forEachInstanceOfVersion( 166 HalFormat format, const std::string& package, 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 // Check if all instances in matrixHal is supported in this manifest. 187 bool isCompatible(const details::Instances& instances, const MatrixHal& matrixHal) const; 188 189 // Return a list of error messages (for each <hal> name) that does NOT conform to 190 // the given compatibility matrix. It does not contain components that are optional. 191 // That is, return empty list iff 192 // (instance in matrix) => (instance in manifest). 193 std::vector<std::string> checkIncompatibleHals(const CompatibilityMatrix& mat) const; 194 195 void removeHals(const std::string& name, size_t majorVer); 196 197 // Returns a list of instance names that are in this manifest but 198 // are not specified in the given matrix, whether the HAL is specified as an optional or 199 // required HAL. 200 // That is, return empty list iff 201 // (instance in manifest) => (instance in matrix). 202 std::set<std::string> checkUnusedHals( 203 const CompatibilityMatrix& mat, 204 const std::vector<HidlInterfaceMetadata>& hidlMetadata) const; 205 206 // Check that manifest has no entries. 207 bool empty() const; 208 209 // Alternative to forEachInstance if you just need a set of instance names instead. 210 std::set<std::string> getInstances(HalFormat format, const std::string& package, 211 const Version& version, 212 const std::string& interfaceName) const; 213 214 // Return whether instance is in getInstances(...). 215 bool hasInstance(HalFormat format, const std::string& package, const Version& version, 216 const std::string& interfaceName, const std::string& instance) const; 217 218 // Get the <kernel> tag. Assumes type() == DEVICE. 219 // - On host, <kernel> tag only exists for the fully assembled HAL manifest. 220 // - On device, this only contain information about level(). Other information should be 221 // looked up via RuntimeInfo. 222 const std::optional<KernelInfo>& kernel() const; 223 224 // Merge information of other to this. 225 bool mergeKernel(std::optional<KernelInfo>* other, std::string* error = nullptr); 226 227 // Whether the manifest contains information about the kernel for compatibility checks. 228 // True if kernel()->checkCompatibility can be called. 229 bool shouldCheckKernelCompatibility() const; 230 231 // Helper for shouldAdd(). Check if |hal| has a conflicting major version with this. Return 232 // false if hal should not be added, and set |error| accordingly. Return true if check passes. 233 bool addingConflictingMajorVersion(const ManifestHal& hal, std::string* error) const; 234 235 // Helper for shouldAdd(). Check if |hal| has a conflicting major version in <fqname> with this. 236 // Return false if hal should not be added, and set |error| accordingly. Return true if check 237 // passes. 238 bool addingConflictingFqInstance(const ManifestHal& hal, std::string* error) const; 239 240 // Inferred kernel level. 241 Level inferredKernelLevel() const; 242 243 SchemaType mType; 244 Level mLevel = Level::UNSPECIFIED; 245 246 // The metaversion on the source file if the HAL manifest is parsed from an XML file, 247 // Otherwise, the object is created programmatically, so default to libvintf meta version. 248 Version mSourceMetaVersion = kMetaVersion; 249 250 // entries for device hal manifest only 251 struct { 252 SepolicyVersion mSepolicyVersion; 253 std::optional<KernelInfo> mKernel; 254 } device; 255 256 // entries for framework hal manifest only 257 struct { 258 #pragma clang diagnostic push 259 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 260 std::vector<Vndk> mVndks; 261 #pragma clang diagnostic pop 262 263 std::vector<VendorNdk> mVendorNdks; 264 SystemSdk mSystemSdk; 265 } framework; 266 }; 267 268 } // namespace vintf 269 } // namespace android 270 271 #endif // ANDROID_VINTF_HAL_MANIFEST_H 272