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

Commit e1a9c8f8 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audio: Update default wrapper to support V7

During this conversion, the functionality of the V7 wrapper
hasn't been tested yet. This will be done in a separate CL
that will also include required updates to the VTS tests.

Since the changes were made to the code shared with pre-V7
versions, verified that V6 HAL didn't regress.

Bug: 142480271
Test: atest VtsHalAudioV6_0TargetTest
Test: m VtsHalAudioV7_0TargetTest
Change-Id: I0e42fe1279912ffa78ce40c69f6aa2054e84d385
Merged-In: I0e42fe1279912ffa78ce40c69f6aa2054e84d385
parent b52e93f5
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -66,9 +66,10 @@ interface IStream {
     * Retrieves basic stream configuration: sample rate, audio format,
     * channel mask.
     *
     * @return retval operation completion status.
     * @return config basic stream configuration.
     */
    getAudioProperties() generates (AudioConfigBase config);
    getAudioProperties() generates (Result retval, AudioConfigBase config);

    /**
     * Sets stream parameters. Only sets parameters that are specified.
+3 −1
Original line number Diff line number Diff line
@@ -125,13 +125,15 @@ cc_library_shared {
}

cc_library_shared {
    enabled: false,
    name: "android.hardware.audio@7.0-impl",
    defaults: ["android.hardware.audio-impl_default"],
    shared_libs: [
        "android.hardware.audio@7.0",
        "android.hardware.audio.common@7.0",
        "android.hardware.audio.common@7.0-enums",
        "android.hardware.audio.common@7.0-util",
        "libbase",
        "libxml2",
    ],
    cflags: [
        "-DMAJOR_VERSION=7",
+64 −60
Original line number Diff line number Diff line
@@ -18,8 +18,11 @@

#include <stdio.h>

#if MAJOR_VERSION >= 7
#include <android_audio_policy_configuration_V7_0-enums.h>
#endif
#include <HidlUtils.h>
#include <log/log.h>
#include <media/AudioContainers.h>

namespace android {
namespace hardware {
@@ -27,73 +30,36 @@ namespace audio {
namespace CPP_VERSION {
namespace implementation {

// TODO(mnaganov): Use method from HidlUtils for V7
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;

#if MAJOR_VERSION <= 6
std::string deviceAddressToHal(const DeviceAddress& address) {
    // HAL assumes that the address is NUL-terminated.
    audio_devices_t halDevice;
    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());
    }
    (void)deviceAddressToHal(address, &halDevice, halAddress);
    return halAddress;
}
#endif

#if MAJOR_VERSION >= 4
status_t deviceAddressFromHal(audio_devices_t device, const char* halAddress,
                              DeviceAddress* address) {
    if (address == nullptr) {
        return BAD_VALUE;
    }
    address->device = AudioDevice(device);
    if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
        return OK;
status_t deviceAddressToHal(const DeviceAddress& device, audio_devices_t* halDeviceType,
                            char* halDeviceAddress) {
#if MAJOR_VERSION >= 5
    return HidlUtils::deviceAddressToHal(device, halDeviceType, halDeviceAddress);
#else
    return HidlUtils::deviceAddressToHalImpl(device, halDeviceType, halDeviceAddress);
#endif
}

    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;
    }
    address->busAddress = halAddress;
    return OK;
status_t deviceAddressFromHal(audio_devices_t halDeviceType, const char* halDeviceAddress,
                              DeviceAddress* device) {
#if MAJOR_VERSION >= 5
    return HidlUtils::deviceAddressFromHal(halDeviceType, halDeviceAddress, device);
#else
    return HidlUtils::deviceAddressFromHalImpl(halDeviceType, halDeviceAddress, device);
#endif
}

#if MAJOR_VERSION >= 4
bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst,
                                    const struct audio_microphone_characteristic_t& src) {
    bool status = false;
@@ -131,6 +97,44 @@ bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst,
    }
    return status;
}
#endif  // MAJOR_VERSION >= 4

#if MAJOR_VERSION >= 7
namespace xsd {
using namespace ::android::audio::policy::configuration::V7_0;
}

bool audioInputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_input_flags_t* halFlags) {
    bool success = true;
    *halFlags = {};
    for (const auto& flag : flags) {
        audio_input_flags_t halFlag;
        if (!xsd::isUnknownAudioInOutFlag(flag) &&
            audio_input_flag_from_string(flag.c_str(), &halFlag)) {
            *halFlags = static_cast<audio_input_flags_t>(*halFlags | halFlag);
        } else {
            ALOGE("Unknown audio input flag \"%s\"", flag.c_str());
            success = false;
        }
    }
    return success;
}

bool audioOutputFlagsToHal(const hidl_vec<AudioInOutFlag>& flags, audio_output_flags_t* halFlags) {
    bool success = true;
    *halFlags = {};
    for (const auto& flag : flags) {
        audio_output_flags_t halFlag;
        if (!xsd::isUnknownAudioInOutFlag(flag) &&
            audio_output_flag_from_string(flag.c_str(), &halFlag)) {
            *halFlags = static_cast<audio_output_flags_t>(*halFlags | halFlag);
        } else {
            ALOGE("Unknown audio output flag \"%s\"", flag.c_str());
            success = false;
        }
    }
    return success;
}
#endif

}  // namespace implementation
+55 −34
Original line number Diff line number Diff line
@@ -150,63 +150,76 @@ Return<void> Device::getInputBufferSize(const AudioConfig& config, getInputBuffe
std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle,
                                                                const DeviceAddress& device,
                                                                const AudioConfig& config,
                                                                AudioOutputFlagBitfield flags,
                                                                const AudioOutputFlags& flags,
                                                                AudioConfig* suggestedConfig) {
    audio_config_t halConfig;
    HidlUtils::audioConfigToHal(config, &halConfig);
    audio_stream_out_t* halStream;
    ALOGV(
        "open_output_stream handle: %d devices: %x flags: %#x "
    audio_devices_t halDevice;
    char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
    if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) {
        return {Result::INVALID_ARGUMENTS, nullptr};
    }
    audio_output_flags_t halFlags;
    if (!audioOutputFlagsToHal(flags, &halFlags)) {
        return {Result::INVALID_ARGUMENTS, nullptr};
    }
    ALOGV("open_output_stream handle: %d devices: %x flags: %#x "
          "srate: %d format %#x channels %x address %s",
        ioHandle, static_cast<audio_devices_t>(device.device),
        static_cast<audio_output_flags_t>(flags), halConfig.sample_rate, halConfig.format,
        halConfig.channel_mask, deviceAddressToHal(device).c_str());
    int status =
        mDevice->open_output_stream(mDevice, ioHandle, static_cast<audio_devices_t>(device.device),
                                    static_cast<audio_output_flags_t>(flags), &halConfig,
                                    &halStream, deviceAddressToHal(device).c_str());
          ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format,
          halConfig.channel_mask, halDeviceAddress);
    int status = mDevice->open_output_stream(mDevice, ioHandle, halDevice, halFlags, &halConfig,
                                             &halStream, halDeviceAddress);
    ALOGV("open_output_stream status %d stream %p", status, halStream);
    sp<IStreamOut> streamOut;
    if (status == OK) {
        streamOut = new StreamOut(this, halStream);
        ++mOpenedStreamsCount;
    }
    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
    status_t convertStatus =
            HidlUtils::audioConfigFromHal(halConfig, false /*isInput*/, suggestedConfig);
    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
    return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut};
}

std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl(
        int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config,
    AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig) {
        const AudioInputFlags& flags, AudioSource source, AudioConfig* suggestedConfig) {
    audio_config_t halConfig;
    HidlUtils::audioConfigToHal(config, &halConfig);
    audio_stream_in_t* halStream;
    ALOGV(
        "open_input_stream handle: %d devices: %x flags: %#x "
    audio_devices_t halDevice;
    char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
    if (deviceAddressToHal(device, &halDevice, halDeviceAddress) != NO_ERROR) {
        return {Result::INVALID_ARGUMENTS, nullptr};
    }
    audio_input_flags_t halFlags;
    audio_source_t halSource;
    if (!audioInputFlagsToHal(flags, &halFlags) ||
        HidlUtils::audioSourceToHal(source, &halSource) != NO_ERROR) {
        return {Result::INVALID_ARGUMENTS, nullptr};
    }
    ALOGV("open_input_stream handle: %d devices: %x flags: %#x "
          "srate: %d format %#x channels %x address %s source %d",
        ioHandle, static_cast<audio_devices_t>(device.device),
        static_cast<audio_input_flags_t>(flags), halConfig.sample_rate, halConfig.format,
        halConfig.channel_mask, deviceAddressToHal(device).c_str(),
        static_cast<audio_source_t>(source));
    int status = mDevice->open_input_stream(
        mDevice, ioHandle, static_cast<audio_devices_t>(device.device), &halConfig, &halStream,
        static_cast<audio_input_flags_t>(flags), deviceAddressToHal(device).c_str(),
        static_cast<audio_source_t>(source));
          ioHandle, halDevice, halFlags, halConfig.sample_rate, halConfig.format,
          halConfig.channel_mask, halDeviceAddress, halSource);
    int status = mDevice->open_input_stream(mDevice, ioHandle, halDevice, &halConfig, &halStream,
                                            halFlags, halDeviceAddress, halSource);
    ALOGV("open_input_stream status %d stream %p", status, halStream);
    sp<IStreamIn> streamIn;
    if (status == OK) {
        streamIn = new StreamIn(this, halStream);
        ++mOpenedStreamsCount;
    }
    status_t convertStatus = HidlUtils::audioConfigFromHal(halConfig, suggestedConfig);
    status_t convertStatus =
            HidlUtils::audioConfigFromHal(halConfig, true /*isInput*/, suggestedConfig);
    ALOGW_IF(convertStatus != OK, "%s: suggested config with incompatible fields", __func__);
    return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn};
}

#if MAJOR_VERSION == 2
Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
                                      const AudioConfig& config, AudioOutputFlagBitfield flags,
                                      const AudioConfig& config, AudioOutputFlags flags,
                                      openOutputStream_cb _hidl_cb) {
    AudioConfig suggestedConfig;
    auto [result, streamOut] =
@@ -216,7 +229,7 @@ Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& dev
}

Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
                                     const AudioConfig& config, AudioInputFlagBitfield flags,
                                     const AudioConfig& config, AudioInputFlags flags,
                                     AudioSource source, openInputStream_cb _hidl_cb) {
    AudioConfig suggestedConfig;
    auto [result, streamIn] =
@@ -227,7 +240,12 @@ Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& devi

#elif MAJOR_VERSION >= 4
Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device,
                                      const AudioConfig& config, AudioOutputFlagBitfield flags,
                                      const AudioConfig& config,
#if MAJOR_VERSION <= 6
                                      AudioOutputFlags flags,
#else
                                      const AudioOutputFlags& flags,
#endif
                                      const SourceMetadata& sourceMetadata,
                                      openOutputStream_cb _hidl_cb) {
    AudioConfig suggestedConfig;
@@ -241,7 +259,12 @@ Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& dev
}

Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device,
                                     const AudioConfig& config, AudioInputFlagBitfield flags,
                                     const AudioConfig& config,
#if MAJOR_VERSION <= 6
                                     AudioInputFlags flags,
#else
                                     const AudioInputFlags& flags,
#endif
                                     const SinkMetadata& sinkMetadata,
                                     openInputStream_cb _hidl_cb) {
    if (sinkMetadata.tracks.size() == 0) {
@@ -271,9 +294,7 @@ Return<bool> Device::supportsAudioPatches() {
Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources,
                                      const hidl_vec<AudioPortConfig>& sinks,
                                      createAudioPatch_cb _hidl_cb) {
    auto [retval, patch] = createOrUpdateAudioPatch(
            static_cast<AudioPatchHandle>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE), sources,
            sinks);
    auto [retval, patch] = createOrUpdateAudioPatch(AudioPatchHandle{}, sources, sinks);
    _hidl_cb(retval, patch);
    return Void();
}
@@ -454,7 +475,7 @@ Return<void> Device::updateAudioPatch(int32_t previousPatch,
                                      const hidl_vec<AudioPortConfig>& sources,
                                      const hidl_vec<AudioPortConfig>& sinks,
                                      createAudioPatch_cb _hidl_cb) {
    if (previousPatch != static_cast<int32_t>(AudioHandleConsts::AUDIO_PATCH_HANDLE_NONE)) {
    if (previousPatch != static_cast<int32_t>(AudioPatchHandle{})) {
        auto [retval, patch] = createOrUpdateAudioPatch(previousPatch, sources, sinks);
        _hidl_cb(retval, patch);
    } else {
+8 −2
Original line number Diff line number Diff line
@@ -149,9 +149,15 @@ Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& context
    }
    return setParams(params);
}

Result ParametersUtil::setParam(const char* name, const DeviceAddress& address) {
    AudioParameter params(String8(deviceAddressToHal(address).c_str()));
    params.addInt(String8(name), int(address.device));
    audio_devices_t halDeviceType;
    char halDeviceAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
    if (deviceAddressToHal(address, &halDeviceType, halDeviceAddress) != NO_ERROR) {
        return Result::INVALID_ARGUMENTS;
    }
    AudioParameter params{String8(halDeviceAddress)};
    params.addInt(String8(name), halDeviceType);
    return setParams(params);
}

Loading