Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ede0467a authored by Daniel Van Veen's avatar Daniel Van Veen Committed by Mikhail Naganov
Browse files

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
parent 9d5eb0a2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+0 −3
Original line number Diff line number Diff line
@@ -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() {
+0 −1
Original line number Diff line number Diff line
@@ -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);

+35 −26
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include <string.h>
#include <vector>

#define LOG_TAG "DevicesFactoryHalHidl"
//#define LOG_NDEBUG 0
@@ -35,27 +36,29 @@ 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
    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*/);
    }

DevicesFactoryHalHidl::~DevicesFactoryHalHidl() {
}

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(
    for (const auto& factory : mDeviceFactories) {
        Return<void> ret = factory->openDevice(
                name,
                [&](Result r, const sp<IDevice>& result) {
                    retval = r;
@@ -63,12 +66,18 @@ status_t DevicesFactoryHalHidl::openDevice(const char *name, sp<DeviceHalInterfa
                        *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;
        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
+2 −3
Original line number Diff line number Diff line
@@ -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