libaudiohal: Use IDeviceFactory in MSD HAL when opening a device

This allows instantiating the MSD device if the HAL is present.

The directive in the .rc about restarting "vendor.audio-hal-4-0-msd"
service is ignored when the service is not present.

The current policy for handling HAL service restarts is to
terminate the audio service. It is possible to do better,
e.g. only re-open the devices of the crashed HAL when possible,
without affecting devices from other HALs. Will try to implement
that later.

Remove the MSD-related code from the V2.0 shim, as MSD isn't
supported on HAL V2.0.

Bug: 63901775
Test: manual on a MSD HAL prototype, also on taimen with no MSD HAL
Change-Id: I7f9de692d6e7b8ff52cdbcaba1074692c5f1c90e
gugelfrei
Daniel Van Veen 6 years ago committed by Mikhail Naganov
parent 9d5eb0a2b7
commit ede0467aa4

@ -6,6 +6,7 @@ service audioserver /system/bin/audioserver
ioprio rt 4
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
onrestart restart vendor.audio-hal-2-0
onrestart restart vendor.audio-hal-4-0-msd
# Keep the original service name for backward compatibility when upgrading
# O-MR1 devices with framework-only.
onrestart restart audio-hal-2-0

@ -43,9 +43,6 @@ DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
ALOGE("Failed to obtain IDevicesFactory service, terminating process.");
exit(1);
}
// The MSD factory is optional
mDevicesFactoryMsd = IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD);
// TODO: Register death handler, and add 'restart' directive to audioserver.rc
}
DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {

@ -39,7 +39,6 @@ class DevicesFactoryHalHidl : public DevicesFactoryHalInterface
friend class DevicesFactoryHalHybrid;
sp<IDevicesFactory> mDevicesFactory;
sp<IDevicesFactory> mDevicesFactoryMsd;
static status_t nameFromHal(const char *name, IDevicesFactory::Device *device);

@ -15,6 +15,7 @@
*/
#include <string.h>
#include <vector>
#define LOG_TAG "DevicesFactoryHalHidl"
//#define LOG_NDEBUG 0
@ -35,40 +36,48 @@ namespace android {
namespace V4_0 {
DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
mDevicesFactory = IDevicesFactory::getService();
if (mDevicesFactory != 0) {
// It is assumed that DevicesFactory is owned by AudioFlinger
// and thus have the same lifespan.
mDevicesFactory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
} else {
ALOGE("Failed to obtain IDevicesFactory service, terminating process.");
sp<IDevicesFactory> defaultFactory{IDevicesFactory::getService()};
if (!defaultFactory) {
ALOGE("Failed to obtain IDevicesFactory/default service, terminating process.");
exit(1);
}
mDeviceFactories.push_back(defaultFactory);
// The MSD factory is optional
mDevicesFactoryMsd = IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD);
// TODO: Register death handler, and add 'restart' directive to audioserver.rc
}
DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
sp<IDevicesFactory> msdFactory{IDevicesFactory::getService(AUDIO_HAL_SERVICE_NAME_MSD)};
if (msdFactory) {
mDeviceFactories.push_back(msdFactory);
}
for (const auto& factory : mDeviceFactories) {
// It is assumed that the DevicesFactoryHalInterface instance is owned
// by AudioFlinger and thus have the same lifespan.
factory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
}
}
status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterface> *device) {
if (mDevicesFactory == 0) return NO_INIT;
if (mDeviceFactories.empty()) return NO_INIT;
Result retval = Result::NOT_INITIALIZED;
Return<void> ret = mDevicesFactory->openDevice(
name,
[&](Result r, const sp<IDevice>& result) {
retval = r;
if (retval == Result::OK) {
*device = new DeviceHalHidl(result);
}
});
if (ret.isOk()) {
if (retval == Result::OK) return OK;
else if (retval == Result::INVALID_ARGUMENTS) return BAD_VALUE;
else return NO_INIT;
for (const auto& factory : mDeviceFactories) {
Return<void> ret = factory->openDevice(
name,
[&](Result r, const sp<IDevice>& result) {
retval = r;
if (retval == Result::OK) {
*device = new DeviceHalHidl(result);
}
});
if (!ret.isOk()) return FAILED_TRANSACTION;
switch (retval) {
// Device was found and was initialized successfully.
case Result::OK: return OK;
// Device was found but failed to initalize.
case Result::NOT_INITIALIZED: return NO_INIT;
// Otherwise continue iterating.
default: ;
}
}
return FAILED_TRANSACTION;
ALOGW("The specified device name is not recognized: \"%s\"", name);
return BAD_VALUE;
}
} // namespace V4_0

@ -39,13 +39,12 @@ class DevicesFactoryHalHidl : public DevicesFactoryHalInterface
private:
friend class DevicesFactoryHalHybrid;
sp<IDevicesFactory> mDevicesFactory;
sp<IDevicesFactory> mDevicesFactoryMsd;
std::vector<sp<IDevicesFactory>> mDeviceFactories;
// Can not be constructed directly by clients.
DevicesFactoryHalHidl();
virtual ~DevicesFactoryHalHidl();
virtual ~DevicesFactoryHalHidl() = default;
};
} // namespace V4_0

Loading…
Cancel
Save