diff --git a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp index a9797bbfbd..7f4a777d7f 100644 --- a/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp +++ b/audio/core/all-versions/vts/functional/4.0/AudioPrimaryHidlHalTest.cpp @@ -28,8 +28,7 @@ TEST_P(AudioHidlTest, OpenPrimaryDeviceUsingGetDevice) { if (getDeviceName() != DeviceManager::kPrimaryDevice) { GTEST_SKIP() << "No primary device on this factory"; // returns } - EXPECT_TRUE( - DeviceManager::getInstance().reset(getFactoryName(), DeviceManager::kPrimaryDevice)); + EXPECT_TRUE(DeviceManager::getInstance().resetPrimary(getFactoryName())); // Must use IDevicesFactory directly because DeviceManager always uses // the latest interfaces version and corresponding methods for opening diff --git a/audio/core/all-versions/vts/functional/DeviceManager.h b/audio/core/all-versions/vts/functional/DeviceManager.h index c8e016731d..6bb39ed3ce 100644 --- a/audio/core/all-versions/vts/functional/DeviceManager.h +++ b/audio/core/all-versions/vts/functional/DeviceManager.h @@ -96,40 +96,83 @@ class DevicesFactoryManager } }; -using FactoryAndDevice = std::tuple; -class DeviceManager : public InterfaceManager { +namespace impl { + +class PrimaryDeviceManager + : public InterfaceManager { public: - static DeviceManager& getInstance() { - static DeviceManager instance; - return instance; + static sp createInterfaceInstance(const std::string& factoryName) { + sp factory = DevicesFactoryManager::getInstance().get(factoryName); + return openPrimaryDevice(factory); } + + bool reset(const std::string& factoryName) __attribute__((warn_unused_result)) { +#if MAJOR_VERSION <= 5 + return InterfaceManager::reset(factoryName, true); +#elif MAJOR_VERSION >= 6 + { + sp device = getExisting(factoryName); + if (device != nullptr) { + auto ret = device->close(); + ALOGE_IF(!ret.isOk(), "PrimaryDevice %s close failed: %s", factoryName.c_str(), + ret.description().c_str()); + } + } + return InterfaceManager::reset(factoryName, false); +#endif + } + + private: + static sp openPrimaryDevice(const sp& factory) { + if (factory == nullptr) return {}; + Result result; + sp primaryDevice; +#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1) + sp device; +#if MAJOR_VERSION == 2 + auto ret = factory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, device)); + if (ret.isOk() && result == Result::OK && device != nullptr) { + primaryDevice = IPrimaryDevice::castFrom(device); + } +#elif MAJOR_VERSION >= 4 + auto ret = factory->openPrimaryDevice(returnIn(result, device)); + if (ret.isOk() && result == Result::OK && device != nullptr) { + primaryDevice = IPrimaryDevice::castFrom(device); + } +#endif + if (!ret.isOk() || result != Result::OK || primaryDevice == nullptr) { + ALOGW("Primary device can not be opened, transaction: %s, result %d, device %p", + ret.description().c_str(), result, device.get()); + return nullptr; + } +#else // V7.1 + auto ret = factory->openPrimaryDevice_7_1(returnIn(result, primaryDevice)); + if (!ret.isOk() || result != Result::OK) { + ALOGW("Primary device can not be opened, transaction: %s, result %d", + ret.description().c_str(), result); + return nullptr; + } +#endif + return primaryDevice; + } +}; + +using FactoryAndDevice = std::tuple; +class RegularDeviceManager + : public InterfaceManager { + public: static sp createInterfaceInstance(const FactoryAndDevice& factoryAndDevice) { auto [factoryName, name] = factoryAndDevice; sp factory = DevicesFactoryManager::getInstance().get(factoryName); return openDevice(factory, name); } - using InterfaceManager::reset; - - static constexpr const char* kPrimaryDevice = "primary"; sp get(const std::string& factoryName, const std::string& name) { - if (name == kPrimaryDevice) { - (void)getPrimary(factoryName); // for initializing primaryDevice if needed. - } return InterfaceManager::get(std::make_tuple(factoryName, name)); } - sp getPrimary(const std::string& factoryName) { - if (primaryDevice == nullptr) { - sp factory = DevicesFactoryManager::getInstance().get(factoryName); - primaryDevice = openPrimaryDevice(factory); - } - return primaryDevice; - } + bool reset(const std::string& factoryName, const std::string& name) __attribute__((warn_unused_result)) { - if (name == kPrimaryDevice) { - primaryDevice.clear(); - } #if MAJOR_VERSION <= 5 return InterfaceManager::reset(std::make_tuple(factoryName, name), true); #elif MAJOR_VERSION >= 6 @@ -144,9 +187,6 @@ class DeviceManager : public InterfaceManager openDevice(const sp& factory, const std::string& name) { @@ -155,9 +195,7 @@ class DeviceManager : public InterfaceManager device; #if MAJOR_VERSION == 2 IDevicesFactory::Device dev = IDevicesFactory::IDevicesFactory::Device(-1); - if (name == AUDIO_HARDWARE_MODULE_ID_PRIMARY) { - dev = IDevicesFactory::Device::PRIMARY; - } else if (name == AUDIO_HARDWARE_MODULE_ID_A2DP) { + if (name == AUDIO_HARDWARE_MODULE_ID_A2DP) { dev = IDevicesFactory::Device::A2DP; } else if (name == AUDIO_HARDWARE_MODULE_ID_USB) { dev = IDevicesFactory::Device::USB; @@ -179,47 +217,62 @@ class DeviceManager : public InterfaceManager openPrimaryDevice(const sp& factory) { - if (factory == nullptr) return {}; - Result result; - sp device; - sp primaryDevice; -#if MAJOR_VERSION == 2 - auto ret = factory->openDevice(IDevicesFactory::Device::PRIMARY, returnIn(result, device)); - if (ret.isOk() && result == Result::OK && device != nullptr) { - primaryDevice = IPrimaryDevice::castFrom(device); +} // namespace impl + +class DeviceManager { + public: + static DeviceManager& getInstance() { + static DeviceManager instance; + return instance; + } + + static constexpr const char* kPrimaryDevice = "primary"; + + sp get(const std::string& factoryName, const std::string& name) { + if (name == kPrimaryDevice) { + auto primary = getPrimary(factoryName); + return primary ? deviceFromPrimary(primary) : nullptr; } -#elif MAJOR_VERSION >= 4 && (MAJOR_VERSION < 7 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)) - auto ret = factory->openPrimaryDevice(returnIn(result, device)); - if (ret.isOk() && result == Result::OK && device != nullptr) { - primaryDevice = IPrimaryDevice::castFrom(device); - } -#elif MAJOR_VERSION == 7 && MINOR_VERSION == 1 - auto ret = factory->openPrimaryDevice_7_1(returnIn(result, primaryDevice)); - if (ret.isOk() && result == Result::OK && primaryDevice != nullptr) { - auto getDeviceRet = primaryDevice->getDevice(); - if (getDeviceRet.isOk()) { - device = getDeviceRet; - } else { - primaryDevice.clear(); - ALOGW("Primary device can not downcast, transaction: %s, primary %p", - getDeviceRet.description().c_str(), primaryDevice.get()); - return {}; - } - } -#endif - if (!ret.isOk() || result != Result::OK || device == nullptr) { - ALOGW("Primary device can not be opened, transaction: %s, result %d, device %p", - ret.description().c_str(), result, device.get()); - return {}; - } - return primaryDevice; + return mDevices.get(factoryName, name); + } + + sp getPrimary(const std::string& factoryName) { + return mPrimary.get(factoryName); + } + + bool reset(const std::string& factoryName, const std::string& name) + __attribute__((warn_unused_result)) { + return name == kPrimaryDevice ? resetPrimary(factoryName) + : mDevices.reset(factoryName, name); + } + + bool resetPrimary(const std::string& factoryName) __attribute__((warn_unused_result)) { + return mPrimary.reset(factoryName); + } + + static void waitForInstanceDestruction() { + // Does not matter which device manager to use. + impl::RegularDeviceManager::waitForInstanceDestruction(); } private: - // There can only be one primary device across all HAL modules. - // A reference to a complete interface is used because in V7.1 IDevice can not - // be upcasted to IPrimaryDevice. - sp primaryDevice; + sp deviceFromPrimary(const sp& primary) { +#if MAJOR_VERSION == 7 && MINOR_VERSION == 1 + auto ret = primary->getDevice(); + if (ret.isOk()) { + return ret; + } else { + ALOGW("Error retrieving IDevice from primary: transaction: %s, primary %p", + ret.description().c_str(), primary.get()); + return nullptr; + } +#else + return primary; +#endif + } + + impl::PrimaryDeviceManager mPrimary; + impl::RegularDeviceManager mDevices; };