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