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