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