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 // "[email protected]", "[email protected]", 101 // "[email protected]"] 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 // 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, ExclusiveTo exclusiveTo, 211 const std::string& package, const Version& version, 212 const std::string& interfaceName) const; 213 214 // Return whether instance is in getInstances(...). 215 bool hasInstance(HalFormat format, ExclusiveTo exclusiveTo, const std::string& package, 216 const Version& version, const std::string& interfaceName, 217 const std::string& instance) const; 218 219 // Get the <kernel> tag. Assumes type() == DEVICE. 220 // - On host, <kernel> tag only exists for the fully assembled HAL manifest. 221 // - On device, this only contain information about level(). Other information should be 222 // looked up via RuntimeInfo. 223 const std::optional<KernelInfo>& kernel() const; 224 225 // Merge information of other to this. 226 bool mergeKernel(std::optional<KernelInfo>* other, std::string* error = nullptr); 227 228 // Whether the manifest contains information about the kernel for compatibility checks. 229 // True if kernel()->checkCompatibility can be called. 230 bool shouldCheckKernelCompatibility() const; 231 232 // Helper for shouldAdd(). Check if |hal| has a conflicting major version with this. Return 233 // false if hal should not be added, and set |error| accordingly. Return true if check passes. 234 bool addingConflictingMajorVersion(const ManifestHal& hal, std::string* error) const; 235 236 // Helper for shouldAdd(). Check if |hal| has a conflicting major version in <fqname> with this. 237 // Return false if hal should not be added, and set |error| accordingly. Return true if check 238 // passes. 239 bool addingConflictingFqInstance(const ManifestHal& hal, std::string* error) const; 240 241 // Inferred kernel level. 242 Level inferredKernelLevel() const; 243 244 SchemaType mType; 245 Level mLevel = Level::UNSPECIFIED; 246 247 // The metaversion on the source file if the HAL manifest is parsed from an XML file, 248 // Otherwise, the object is created programmatically, so default to libvintf meta version. 249 Version mSourceMetaVersion = kMetaVersion; 250 251 // entries for device hal manifest only 252 struct { 253 SepolicyVersion mSepolicyVersion; 254 std::optional<KernelInfo> mKernel; 255 } device; 256 257 // entries for framework hal manifest only 258 struct { 259 #pragma clang diagnostic push 260 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 261 std::vector<Vndk> mVndks; 262 #pragma clang diagnostic pop 263 264 std::vector<VendorNdk> mVendorNdks; 265 SystemSdk mSystemSdk; 266 } framework; 267 }; 268 269 } // namespace vintf 270 } // namespace android 271 272 #endif // ANDROID_VINTF_HAL_MANIFEST_H 273