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