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