xref: /aosp_15_r20/system/libvintf/include/vintf/HalManifest.h (revision 70a7ec852fcefd15a4fb57f8f183a8b1c3aacb08)
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