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

Commit 247b5f9a authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

Enable support for audio HAL V7 in the framework

Update code in libaudiohal to augment it for the changes
in the data types.

Moved some conversion code out into a new effect utils
library under hardware/interfaces.

Renamed VersionUtils.h to ParameterUtils.h to avoid
file name clash with the file from hardware/interfaces.

Bug: 142480271
Test: m
Change-Id: I45d1a8e4f3620f7e6f0a39dccadb7814c4bb086d
parent 0d6a9e87
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -17,7 +17,7 @@ cc_library_shared {
        "libaudiohal@4.0",
        "libaudiohal@5.0",
        "libaudiohal@6.0",
//        "libaudiohal@7.0",
        "libaudiohal@7.0",
    ],

    shared_libs: [
+8 −2
Original line number Diff line number Diff line
@@ -60,7 +60,9 @@ cc_library_shared {
        "android.hardware.audio.common@4.0",
        "android.hardware.audio.common@4.0-util",
        "android.hardware.audio.effect@4.0",
        "android.hardware.audio.effect@4.0-util",
        "android.hardware.audio@4.0",
        "android.hardware.audio@4.0-util",
    ],
    cflags: [
        "-DMAJOR_VERSION=4",
@@ -76,7 +78,9 @@ cc_library_shared {
        "android.hardware.audio.common@5.0",
        "android.hardware.audio.common@5.0-util",
        "android.hardware.audio.effect@5.0",
        "android.hardware.audio.effect@5.0-util",
        "android.hardware.audio@5.0",
        "android.hardware.audio@5.0-util",
    ],
    cflags: [
        "-DMAJOR_VERSION=5",
@@ -92,7 +96,9 @@ cc_library_shared {
        "android.hardware.audio.common@6.0",
        "android.hardware.audio.common@6.0-util",
        "android.hardware.audio.effect@6.0",
        "android.hardware.audio.effect@6.0-util",
        "android.hardware.audio@6.0",
        "android.hardware.audio@6.0-util",
    ],
    cflags: [
        "-DMAJOR_VERSION=6",
@@ -102,14 +108,15 @@ cc_library_shared {
}

cc_library_shared {
    enabled: false,
    name: "libaudiohal@7.0",
    defaults: ["libaudiohal_default"],
    shared_libs: [
        "android.hardware.audio.common@7.0",
        "android.hardware.audio.common@7.0-util",
        "android.hardware.audio.effect@7.0",
        "android.hardware.audio.effect@7.0-util",
        "android.hardware.audio@7.0",
        "android.hardware.audio@7.0-util",
    ],
    cflags: [
        "-DMAJOR_VERSION=7",
@@ -117,4 +124,3 @@ cc_library_shared {
        "-include common/all-versions/VersionMacro.h",
    ]
}
+0 −124
Original line number Diff line number Diff line
@@ -120,129 +120,5 @@ void ConversionHelperHidl::emitError(const char* funcName, const char* descripti
    ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
}

#if MAJOR_VERSION >= 4
// TODO: Use the same implementation in the hal when it moves to a util library.
static std::string deviceAddressToHal(const DeviceAddress& address) {
    // HAL assumes that the address is NUL-terminated.
    char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
    memset(halAddress, 0, sizeof(halAddress));
    audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
    if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
        halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
        snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
                 address.address.mac[0], address.address.mac[1], address.address.mac[2],
                 address.address.mac[3], address.address.mac[4], address.address.mac[5]);
    } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) {
        snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
                 address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
    } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 ||
               getAudioDeviceInAllUsbSet().count(halDevice) > 0) {
        snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
                 address.address.alsa.device);
    } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) {
        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
    } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
               halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
        snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
    } else {
        snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
    }
    return halAddress;
}

//local conversion helpers

static audio_microphone_channel_mapping_t  channelMappingToHal(AudioMicrophoneChannelMapping mapping) {
    switch (mapping) {
        case AudioMicrophoneChannelMapping::UNUSED:
            return AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
        case AudioMicrophoneChannelMapping::DIRECT:
            return AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
        case AudioMicrophoneChannelMapping::PROCESSED:
            return AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
        default:
            LOG_ALWAYS_FATAL("Unknown channelMappingToHal conversion %d", mapping);
    }
}

static audio_microphone_location_t locationToHal(AudioMicrophoneLocation location) {
    switch (location) {
        case AudioMicrophoneLocation::UNKNOWN:
            return AUDIO_MICROPHONE_LOCATION_UNKNOWN;
        case AudioMicrophoneLocation::MAINBODY:
            return AUDIO_MICROPHONE_LOCATION_MAINBODY;
        case AudioMicrophoneLocation::MAINBODY_MOVABLE:
            return AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE;
        case AudioMicrophoneLocation::PERIPHERAL:
            return AUDIO_MICROPHONE_LOCATION_PERIPHERAL;
        default:
            LOG_ALWAYS_FATAL("Unknown locationToHal conversion %d", location);
    }
}
static audio_microphone_directionality_t directionalityToHal(AudioMicrophoneDirectionality dir) {
    switch (dir) {
        case AudioMicrophoneDirectionality::UNKNOWN:
            return AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
        case AudioMicrophoneDirectionality::OMNI:
            return AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
        case AudioMicrophoneDirectionality::BI_DIRECTIONAL:
            return AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL;
        case AudioMicrophoneDirectionality::CARDIOID:
            return AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID;
        case AudioMicrophoneDirectionality::HYPER_CARDIOID:
            return AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID;
        case AudioMicrophoneDirectionality::SUPER_CARDIOID:
            return AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID;
        default:
            LOG_ALWAYS_FATAL("Unknown directionalityToHal conversion %d", dir);
    }
}

void microphoneInfoToHal(const MicrophoneInfo& src,
                         audio_microphone_characteristic_t *pDst) {
    if (pDst != NULL) {
        snprintf(pDst->device_id, sizeof(pDst->device_id),
                 "%s", src.deviceId.c_str());
        pDst->device = static_cast<audio_devices_t>(src.deviceAddress.device);
        snprintf(pDst->address, sizeof(pDst->address),
                 "%s", deviceAddressToHal(src.deviceAddress).c_str());
        if (src.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
            ALOGW("microphoneInfoToStruct found %zu channelMapping elements. Max expected is %d",
                  src.channelMapping.size(), AUDIO_CHANNEL_COUNT_MAX);
        }
        size_t ch;
        for (ch = 0; ch < src.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
            pDst->channel_mapping[ch] = channelMappingToHal(src.channelMapping[ch]);
        }
        for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
            pDst->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
        }
        pDst->location = locationToHal(src.location);
        pDst->group = (audio_microphone_group_t)src.group;
        pDst->index_in_the_group = (unsigned int)src.indexInTheGroup;
        pDst->sensitivity = src.sensitivity;
        pDst->max_spl = src.maxSpl;
        pDst->min_spl = src.minSpl;
        pDst->directionality = directionalityToHal(src.directionality);
        pDst->num_frequency_responses = (unsigned int)src.frequencyResponse.size();
        if (pDst->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
            ALOGW("microphoneInfoToStruct found %d frequency responses. Max expected is %d",
                  pDst->num_frequency_responses, AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES);
            pDst->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES;
        }
        for (size_t k = 0; k < pDst->num_frequency_responses; k++) {
            pDst->frequency_responses[0][k] = src.frequencyResponse[k].frequency;
            pDst->frequency_responses[1][k] = src.frequencyResponse[k].level;
        }
        pDst->geometric_location.x = src.position.x;
        pDst->geometric_location.y = src.position.y;
        pDst->geometric_location.z = src.position.z;
        pDst->orientation.x = src.orientation.x;
        pDst->orientation.y = src.orientation.y;
        pDst->orientation.z = src.orientation.z;
    }
}
#endif

}  // namespace CPP_VERSION
}  // namespace android
+0 −6
Original line number Diff line number Diff line
@@ -82,12 +82,6 @@ class ConversionHelperHidl {
    void emitError(const char* funcName, const char* description);
};

#if MAJOR_VERSION >= 4
using ::android::hardware::audio::CPP_VERSION::MicrophoneInfo;
void microphoneInfoToHal(const MicrophoneInfo& src,
                         audio_microphone_characteristic_t *pDst);
#endif

}  // namespace CPP_VERSION
}  // namespace android

+41 −66
Original line number Diff line number Diff line
@@ -19,22 +19,24 @@
#define LOG_TAG "DeviceHalHidl"
//#define LOG_NDEBUG 0

#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include <cutils/native_handle.h>
#include <hwbinder/IPCThreadState.h>
#include <media/AudioContainers.h>
#include <utils/Log.h>

#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include <HidlUtils.h>
#include <common/all-versions/VersionUtils.h>
#include <util/CoreUtils.h>

#include "DeviceHalHidl.h"
#include "EffectHalHidl.h"
#include "HidlUtils.h"
#include "ParameterUtils.h"
#include "StreamHalHidl.h"
#include "VersionUtils.h"

using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
using ::android::hardware::audio::common::utils::EnumBitfield;
using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;

@@ -46,50 +48,6 @@ using namespace ::android::hardware::audio::CPP_VERSION;

using EffectHalHidl = ::android::effect::CPP_VERSION::EffectHalHidl;

namespace {

using ::android::hardware::audio::common::CPP_VERSION::AudioPort;
using ::android::hardware::audio::common::CPP_VERSION::AudioPortConfig;

status_t deviceAddressFromHal(
        audio_devices_t device, const char* halAddress, DeviceAddress* address) {
    address->device = AudioDevice(device);

    if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
        return OK;
    }
    if (getAudioDeviceOutAllA2dpSet().count(device) > 0
            || device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
        int status = sscanf(halAddress,
                "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
                &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
                &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
        return status == 6 ? OK : BAD_VALUE;
    } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
        int status = sscanf(halAddress,
                "%hhu.%hhu.%hhu.%hhu",
                &address->address.ipv4[0], &address->address.ipv4[1],
                &address->address.ipv4[2], &address->address.ipv4[3]);
        return status == 4 ? OK : BAD_VALUE;
    } else if (getAudioDeviceOutAllUsbSet().count(device) > 0
            || getAudioDeviceInAllUsbSet().count(device) > 0) {
        int status = sscanf(halAddress,
                "card=%d;device=%d",
                &address->address.alsa.card, &address->address.alsa.device);
        return status == 2 ? OK : BAD_VALUE;
    } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
        address->busAddress = halAddress;
        return OK;
    } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
            || device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
        address->rSubmixAddress = halAddress;
        return OK;
    }
    return OK;
}

}  // namespace

DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
        : ConversionHelperHidl("Device"), mDevice(device),
          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
@@ -237,16 +195,22 @@ status_t DeviceHalHidl::openOutputStream(
        sp<StreamOutHalInterface> *outStream) {
    if (mDevice == 0) return NO_INIT;
    DeviceAddress hidlDevice;
    status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice);
    if (status != OK) return status;
    if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
            status != OK) {
        return status;
    }
    AudioConfig hidlConfig;
    HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
    if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
            status != OK) {
        return status;
    }
    CoreUtils::AudioOutputFlags hidlFlags;
    if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
        return status;
    }
    Result retval = Result::NOT_INITIALIZED;
    Return<void> ret = mDevice->openOutputStream(
            handle,
            hidlDevice,
            hidlConfig,
            EnumBitfield<AudioOutputFlag>(flags),
            handle, hidlDevice, hidlConfig, hidlFlags,
#if MAJOR_VERSION >= 4
            {} /* metadata */,
#endif
@@ -272,17 +236,30 @@ status_t DeviceHalHidl::openInputStream(
        sp<StreamInHalInterface> *inStream) {
    if (mDevice == 0) return NO_INIT;
    DeviceAddress hidlDevice;
    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
    if (status != OK) return status;
    if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
            status != OK) {
        return status;
    }
    AudioConfig hidlConfig;
    HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
    if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
            status != OK) {
        return status;
    }
    CoreUtils::AudioInputFlags hidlFlags;
    if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
        return status;
    }
    Result retval = Result::NOT_INITIALIZED;
#if MAJOR_VERSION == 2
    auto sinkMetadata = AudioSource(source);
#elif MAJOR_VERSION >= 4
    // TODO: correctly propagate the tracks sources and volume
    //       for now, only send the main source at 1dbfs
    SinkMetadata sinkMetadata = {{{ .source = AudioSource(source), .gain = 1 }}};
    AudioSource hidlSource;
    if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
        return status;
    }
    SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
#endif
#if MAJOR_VERSION < 5
    (void)outputDevice;
@@ -290,8 +267,10 @@ status_t DeviceHalHidl::openInputStream(
#else
    if (outputDevice != AUDIO_DEVICE_NONE) {
        DeviceAddress hidlOutputDevice;
        status = deviceAddressFromHal(outputDevice, outputDeviceAddress, &hidlOutputDevice);
        if (status != OK) return status;
        if (status_t status = CoreUtils::deviceAddressFromHal(
                        outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
            return status;
        }
        sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
    }
#endif
@@ -300,11 +279,7 @@ status_t DeviceHalHidl::openInputStream(
    flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
#endif
    Return<void> ret = mDevice->openInputStream(
            handle,
            hidlDevice,
            hidlConfig,
            EnumBitfield<AudioInputFlag>(flags),
            sinkMetadata,
            handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
            [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
                retval = r;
                if (retval == Result::OK) {
@@ -441,7 +416,7 @@ status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *micro
        for (size_t k = 0; k < micArrayHal.size(); k++) {
            audio_microphone_characteristic_t dst;
            //convert
            microphoneInfoToHal(micArrayHal[k], &dst);
            (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
            media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
            microphonesInfo->push_back(microphone);
        }
Loading