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