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