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