• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef ANDROID_VINTF_VINTF_OBJECT_H_
18 #define ANDROID_VINTF_VINTF_OBJECT_H_
19 
20 #include <map>
21 #include <memory>
22 #include <optional>
23 #include <string>
24 #include <tuple>
25 #include <vector>
26 
27 #include <aidl/metadata.h>
28 #include <android-base/result.h>
29 #include <hidl/metadata.h>
30 
31 #include <vintf/CheckFlags.h>
32 #include <vintf/CompatibilityMatrix.h>
33 #include <vintf/FileSystem.h>
34 #include <vintf/HalManifest.h>
35 #include <vintf/Level.h>
36 #include <vintf/ObjectFactory.h>
37 #include <vintf/PropertyFetcher.h>
38 #include <vintf/RuntimeInfo.h>
39 
40 namespace android {
41 namespace vintf {
42 
43 class VintfObject;
44 
45 namespace details {
46 class CheckVintfUtils;
47 class FmOnlyVintfObject;
48 
49 template <typename T>
50 struct LockedSharedPtr {
51     std::shared_ptr<T> object;
52     std::mutex mutex;
53     bool fetchedOnce = false;
54 };
55 
56 struct LockedRuntimeInfoCache {
57     std::shared_ptr<RuntimeInfo> object;
58     std::mutex mutex;
59     RuntimeInfo::FetchFlags fetchedFlags = RuntimeInfo::FetchFlag::NONE;
60 };
61 
62 /**
63  * DO NOT USE outside of libvintf. This is an implementation detail. Use VintfObject::Builder
64  * instead.
65  *
66  * A builder of VintfObject. If a dependency is not specified, the default behavior is used.
67  * - FileSystem fetch from "/" for target and fetch no files for host
68  * - ObjectFactory<RuntimeInfo> fetches default RuntimeInfo for target and nothing for host
69  * - PropertyFetcher fetches properties for target and nothing for host
70  */
71 class VintfObjectBuilder {
72    public:
VintfObjectBuilder(std::unique_ptr<VintfObject> && object)73     VintfObjectBuilder(std::unique_ptr<VintfObject>&& object) : mObject(std::move(object)) {}
74     ~VintfObjectBuilder();
75     VintfObjectBuilder& setFileSystem(std::unique_ptr<FileSystem>&&);
76     VintfObjectBuilder& setRuntimeInfoFactory(std::unique_ptr<ObjectFactory<RuntimeInfo>>&&);
77     VintfObjectBuilder& setPropertyFetcher(std::unique_ptr<PropertyFetcher>&&);
78 
79     template <typename VintfObjectType = VintfObject>
build()80     std::unique_ptr<VintfObjectType> build() {
81         return std::unique_ptr<VintfObjectType>(
82             static_cast<VintfObjectType*>(buildInternal().release()));
83     }
84 
85    private:
86     std::unique_ptr<VintfObject> buildInternal();
87     std::unique_ptr<VintfObject> mObject;
88 };
89 
90 }  // namespace details
91 
92 namespace testing {
93 class VintfObjectTestBase;
94 class VintfObjectRecoveryTest;
95 class VintfObjectRuntimeInfoTest;
96 class VintfObjectCompatibleTest;
97 }  // namespace testing
98 
99 /*
100  * The top level class for libvintf.
101  * An overall diagram of the public API:
102  * VintfObject
103  *   + GetDeviceHalManfiest
104  *   |   + getHidlTransport
105  *   |   + checkCompatibility
106  *   + GetFrameworkHalManifest
107  *   |   + getHidlTransport
108  *   |   + checkCompatibility
109  *   + GetRuntimeInfo
110  *       + checkCompatibility
111  *
112  * Each of the function gathers all information and encapsulate it into the object.
113  * If no error, it return the same singleton object in the future, and the HAL manifest
114  * file won't be touched again.
115  * If any error, nullptr is returned, and Get will try to parse the HAL manifest
116  * again when it is called again.
117  * All these operations are thread-safe.
118  */
119 class VintfObject {
120    public:
121     virtual ~VintfObject() = default;
122 
123     /*
124      * Return the API that access the device-side HAL manifests built from component pieces on the
125      * vendor partition.
126      */
127     virtual std::shared_ptr<const HalManifest> getDeviceHalManifest();
128 
129     /*
130      * Return the API that access the framework-side HAL manifest built from component pieces on the
131      * system partition.
132      */
133     virtual std::shared_ptr<const HalManifest> getFrameworkHalManifest();
134 
135     /*
136      * Return the API that access the device-side compatibility matrix built from component pieces
137      * on the vendor partition.
138      */
139     virtual std::shared_ptr<const CompatibilityMatrix> getDeviceCompatibilityMatrix();
140 
141     /*
142      * Return the API that access the framework-side compatibility matrix built from component
143      * pieces on the system partition.
144      *
145      * This automatically selects the right compatibility matrix according to the target-level
146      * specified by the device.
147      */
148     virtual std::shared_ptr<const CompatibilityMatrix> getFrameworkCompatibilityMatrix();
149 
150     /*
151      * Return the API that access device runtime info.
152      *
153      * {skipCache == true, flags == ALL}: re-fetch everything
154      * {skipCache == false, flags == ALL}: fetch everything if not previously fetched
155      * {skipCache == true, flags == selected info}: re-fetch selected information
156      *                                if not previously fetched.
157      * {skipCache == false, flags == selected info}: fetch selected information
158      *                                if not previously fetched.
159      *
160      * @param skipCache do not fetch if previously fetched
161      * @param flags bitwise-or of RuntimeInfo::FetchFlag
162      */
163     std::shared_ptr<const RuntimeInfo> getRuntimeInfo(
164         RuntimeInfo::FetchFlags flags = RuntimeInfo::FetchFlag::ALL);
165 
166     /**
167      * Check compatibility on the device.
168      *
169      * @param error error message
170      * @param flags flags to disable certain checks. See CheckFlags.
171      *
172      * @return = 0 if success (compatible)
173      *         > 0 if incompatible
174      *         < 0 if any error (mount partition fails, illformed XML, etc.)
175      */
176     int32_t checkCompatibility(std::string* error = nullptr,
177                                CheckFlags::Type flags = CheckFlags::DEFAULT);
178 
179     /**
180      * A std::function that abstracts a list of "provided" instance names. Given package, version
181      * and interface, the function returns a list of instance names that matches.
182      * This function can represent a manifest, an IServiceManager, etc.
183      * If the source is passthrough service manager, a list of instance names cannot be provided.
184      * Instead, the function should call getService on each of the "hintInstances", and
185      * return those instances for which getService does not return a nullptr. This means that for
186      * passthrough HALs, the deprecation on <regex-instance>s cannot be enforced; only <instance>s
187      * can be enforced.
188      */
189     using ListInstances = std::function<std::vector<std::pair<std::string, Version>>(
190         const std::string& package, Version version, const std::string& interface,
191         const std::vector<std::string>& hintInstances)>;
192     /**
193      * Check deprecation on framework matrices with a provided predicate.
194      *
195      * @param listInstances predicate that takes parameter in this format:
196      *        android.hardware.foo@1.0::IFoo
197      *        and returns {{"default", version}...} if HAL is in use, where version =
198      *        first version in interfaceChain where package + major version matches.
199      *
200      * @return = 0 if success (no deprecated HALs)
201      *         > 0 if there is at least one deprecated HAL
202      *         < 0 if any error (mount partition fails, illformed XML, etc.)
203      */
204     int32_t checkDeprecation(const ListInstances& listInstances,
205                              const std::vector<HidlInterfaceMetadata>& hidlMetadata,
206                              std::string* error = nullptr);
207 
208     /**
209      * Check deprecation on existing VINTF metadata. Use Device Manifest as the
210      * predicate to check if a HAL is in use.
211      *
212      * @return = 0 if success (no deprecated HALs)
213      *         > 0 if there is at least one deprecated HAL
214      *         < 0 if any error (mount partition fails, illformed XML, etc.)
215      */
216     int32_t checkDeprecation(const std::vector<HidlInterfaceMetadata>& hidlMetadata,
217                              std::string* error = nullptr);
218 
219     /**
220      * Return kernel FCM version.
221      *
222      * If any error, UNSPECIFIED is returned, and error is set to an error message.
223      */
224     Level getKernelLevel(std::string* error = nullptr);
225 
226     /**
227      * Returns true if the framework compatibility matrix has extensions. In
228      * other words, returns true if any of the following exists on the device:
229      * - device framework compatibility matrix
230      * - product framework compatibility matrix
231      * - system_ext framework compatibility matrix
232      *
233      * Return result:
234      * - true if framework compatibility matrix has extensions
235      * - false if framework compatibility
236      *     matrix does not have extensions.
237      * - !result.has_value() if any error. Check
238      *     result.error() for detailed message.
239      */
240     android::base::Result<bool> hasFrameworkCompatibilityMatrixExtensions();
241 
242     /**
243      * Check that there are no unused HALs in HAL manifests. Currently, only
244      * device manifest is checked against framework compatibility matrix.
245      *
246      * Return result:
247      * - result.ok() if no unused HALs
248      * - !result.ok() && result.error().code() == 0 if with unused HALs. Check
249      *     result.error() for detailed message.
250      * - !result.ok() && result.error().code() != 0 if any error. Check
251      *     result.error() for detailed message.
252      */
253     android::base::Result<void> checkUnusedHals(
254         const std::vector<HidlInterfaceMetadata>& hidlMetadata);
255 
256     // Check that all HALs are added to any framework compatibility matrix.
257     // If shouldCheck is set, only check if:
258     // - For HIDL, shouldCheck(packageAndVersion) (e.g. android.hardware.foo@1.0)
259     // - For AIDL and native, shouldCheck(package) (e.g. android.hardware.foo)
260     android::base::Result<void> checkMissingHalsInMatrices(
261         const std::vector<HidlInterfaceMetadata>& hidlMetadata,
262         const std::vector<AidlInterfaceMetadata>& aidlMetadata,
263         std::function<bool(const std::string&)> shouldCheck = {});
264 
265     // Check that all HALs in all framework compatibility matrices have the
266     // proper interface definition (HIDL / AIDL files).
267     android::base::Result<void> checkMatrixHalsHasDefinition(
268         const std::vector<HidlInterfaceMetadata>& hidlMetadata,
269         const std::vector<AidlInterfaceMetadata>& aidlMetadata);
270 
271    private:
272     std::unique_ptr<FileSystem> mFileSystem;
273     std::unique_ptr<ObjectFactory<RuntimeInfo>> mRuntimeInfoFactory;
274     std::unique_ptr<PropertyFetcher> mPropertyFetcher;
275 
276     details::LockedSharedPtr<HalManifest> mDeviceManifest;
277     details::LockedSharedPtr<HalManifest> mFrameworkManifest;
278     details::LockedSharedPtr<CompatibilityMatrix> mDeviceMatrix;
279 
280     // Parent lock of the following fields. It should be acquired before locking the child locks.
281     std::mutex mFrameworkCompatibilityMatrixMutex;
282     details::LockedSharedPtr<CompatibilityMatrix> mFrameworkMatrix;
283     details::LockedSharedPtr<CompatibilityMatrix> mCombinedFrameworkMatrix;
284     // End of mFrameworkCompatibilityMatrixMutex
285 
286     details::LockedRuntimeInfoCache mDeviceRuntimeInfo;
287 
288     // Expose functions for testing and recovery
289     friend class testing::VintfObjectTestBase;
290     friend class testing::VintfObjectRecoveryTest;
291     friend class testing::VintfObjectRuntimeInfoTest;
292     friend class testing::VintfObjectCompatibleTest;
293 
294     // Expose functions to simulate dependency injection.
295     friend class details::VintfObjectBuilder;
296     friend class details::CheckVintfUtils;
297     friend class details::FmOnlyVintfObject;
298 
299    protected:
300     virtual const std::unique_ptr<FileSystem>& getFileSystem();
301     virtual const std::unique_ptr<PropertyFetcher>& getPropertyFetcher();
302     virtual const std::unique_ptr<ObjectFactory<RuntimeInfo>>& getRuntimeInfoFactory();
303 
304    public:
305     /*
306      * Get global instance. Results are cached.
307      */
308     static std::shared_ptr<VintfObject> GetInstance();
309 
310     // Static variants of member functions.
311 
312     /*
313      * Return the API that access the device-side HAL manifest built from component pieces on the
314      * vendor partition.
315      */
316     static std::shared_ptr<const HalManifest> GetDeviceHalManifest();
317 
318     /*
319      * Return the API that access the framework-side HAL manifest built from component pieces on the
320      * system partition.
321      */
322     static std::shared_ptr<const HalManifest> GetFrameworkHalManifest();
323 
324     /*
325      * Return the API that access the device-side compatibility matrix built from component pieces
326      * on the vendor partition.
327      */
328     static std::shared_ptr<const CompatibilityMatrix> GetDeviceCompatibilityMatrix();
329 
330     /*
331      * Return the API that access the framework-side compatibility matrix built from component
332      * pieces on the system partition.
333      */
334     static std::shared_ptr<const CompatibilityMatrix> GetFrameworkCompatibilityMatrix();
335 
336     /*
337      * Return the API that access device runtime info.
338      *
339      * @param flags bitwise-or of RuntimeInfo::FetchFlag
340      *   flags == ALL: fetch everything if not previously fetched
341      *   flags == selected info: fetch selected information if not previously fetched.
342      */
343     static std::shared_ptr<const RuntimeInfo> GetRuntimeInfo(
344         RuntimeInfo::FetchFlags flags = RuntimeInfo::FetchFlag::ALL);
345 
346    protected:
347     status_t getCombinedFrameworkMatrix(const std::shared_ptr<const HalManifest>& deviceManifest,
348                                         Level kernelLevel, CompatibilityMatrix* out,
349                                         std::string* error = nullptr);
350     status_t getAllFrameworkMatrixLevels(std::vector<CompatibilityMatrix>* out,
351                                          std::string* error = nullptr);
352     status_t getOneMatrix(const std::string& path, CompatibilityMatrix* out,
353                           std::string* error = nullptr);
354     status_t addDirectoryManifests(const std::string& directory, HalManifest* manifests,
355                                    bool ignoreSchemaType, std::string* error);
356     status_t fetchDeviceHalManifest(HalManifest* out, std::string* error = nullptr);
357     status_t fetchDeviceMatrix(CompatibilityMatrix* out, std::string* error = nullptr);
358     status_t fetchOdmHalManifest(HalManifest* out, std::string* error = nullptr);
359     status_t fetchOneHalManifest(const std::string& path, HalManifest* out,
360                                  std::string* error = nullptr);
361     status_t fetchVendorHalManifest(HalManifest* out, std::string* error = nullptr);
362     status_t fetchFrameworkHalManifest(HalManifest* out, std::string* error = nullptr);
363 
364     status_t fetchUnfilteredFrameworkHalManifest(HalManifest* out, std::string* error);
365     void filterHalsByDeviceManifestLevel(HalManifest* out);
366 
367     // Helper for checking matrices against lib*idlmetadata. Wrapper of the other variant of
368     // getAllFrameworkMatrixLevels. Treat empty output as an error.
369     android::base::Result<std::vector<CompatibilityMatrix>> getAllFrameworkMatrixLevels();
370 
371     using ChildrenMap = std::multimap<std::string, std::string>;
372     static bool IsHalDeprecated(const MatrixHal& oldMatrixHal,
373                                 const CompatibilityMatrix& targetMatrix,
374                                 const ListInstances& listInstances, const ChildrenMap& childrenMap,
375                                 std::string* appendedError);
376     static bool IsInstanceDeprecated(const MatrixInstance& oldMatrixInstance,
377                                      const CompatibilityMatrix& targetMatrix,
378                                      const ListInstances& listInstances,
379                                      const ChildrenMap& childrenMap, std::string* appendedError);
380 
381     static android::base::Result<std::vector<FqInstance>> GetListedInstanceInheritance(
382         const std::string& package, const Version& version, const std::string& interface,
383         const std::string& instance, const ListInstances& listInstances,
384         const ChildrenMap& childrenMap);
385     static bool IsInstanceListed(const ListInstances& listInstances, const FqInstance& fqInstance);
386     static android::base::Result<void> IsFqInstanceDeprecated(
387         const CompatibilityMatrix& targetMatrix, HalFormat format, const FqInstance& fqInstance,
388         const ListInstances& listInstances);
389 
390    public:
391     /** Builder of VintfObject. See VintfObjectBuilder for details. */
392     class Builder : public details::VintfObjectBuilder {
393        public:
394         Builder();
395     };
396 
397    protected:
398     /* Empty VintfObject without any dependencies. Used by Builder and subclasses. */
399     VintfObject() = default;
400 };
401 
402 enum : int32_t {
403     COMPATIBLE = 0,
404     INCOMPATIBLE = 1,
405 
406     NO_DEPRECATED_HALS = 0,
407     DEPRECATED = 1,
408 };
409 
410 // exposed for testing.
411 namespace details {
412 
413 // Convenience function to dump all files and directories that could be read
414 // by calling Get(Framework|Device)(HalManifest|CompatibilityMatrix). The list
415 // include files that may not actually be read when the four functions are called
416 // because some files have a higher priority than others. The list does NOT
417 // include "files" (including kernel interfaces) that are read when GetRuntimeInfo
418 // is called.
419 std::vector<std::string> dumpFileList();
420 
421 } // namespace details
422 
423 } // namespace vintf
424 } // namespace android
425 
426 #endif // ANDROID_VINTF_VINTF_OBJECT_H_
427