diff --git a/audio/2.0/IDevice.hal b/audio/2.0/IDevice.hal index 38bfe211a4..630a32cf23 100644 --- a/audio/2.0/IDevice.hal +++ b/audio/2.0/IDevice.hal @@ -102,6 +102,8 @@ interface IDevice { /* * This method creates and opens the audio hardware output stream. + * If the stream can not be opened with the proposed audio config, + * HAL must provide suggested values for the audio config. * * @param ioHandle handle assigned by AudioFlinger. * @param device device type and (if needed) address. @@ -109,15 +111,21 @@ interface IDevice { * @param flags additional flags. * @return retval operation completion status. * @return outStream created output stream. + * @return suggestedConfig in case of invalid parameters, suggested config. */ openOutputStream( AudioIoHandle ioHandle, DeviceAddress device, AudioConfig config, - AudioOutputFlag flags) generates (Result retval, IStreamOut outStream); + AudioOutputFlag flags) generates ( + Result retval, + IStreamOut outStream, + AudioConfig suggestedConfig); /* * This method creates and opens the audio hardware input stream. + * If the stream can not be opened with the proposed audio config, + * HAL must provide suggested values for the audio config. * * @param ioHandle handle assigned by AudioFlinger. * @param device device type and (if needed) address. @@ -125,14 +133,25 @@ interface IDevice { * @param flags additional flags. * @param source source specification. * @return retval operation completion status. - * @return inStream created input stream. + * @return inStream in case of success, created input stream. + * @return suggestedConfig in case of invalid parameters, suggested config. */ openInputStream( AudioIoHandle ioHandle, DeviceAddress device, AudioConfig config, AudioInputFlag flags, - AudioSource source) generates (Result retval, IStreamIn inStream); + AudioSource source) generates ( + Result retval, + IStreamIn inStream, + AudioConfig suggestedConfig); + + /* + * Returns whether HAL supports audio patches. + * + * @return supports true if audio patches are supported. + */ + supportsAudioPatches() generates (bool supports); /* * Creates an audio patch between several source and sink ports. The handle diff --git a/audio/2.0/IStreamOut.hal b/audio/2.0/IStreamOut.hal index 55a852d1ca..4ba3b2f194 100644 --- a/audio/2.0/IStreamOut.hal +++ b/audio/2.0/IStreamOut.hal @@ -90,10 +90,24 @@ interface IStreamOut extends IStream { * Calling this function implies that all future 'write' and 'drain' * must be non-blocking and use the callback to signal completion. * + * 'clearCallback' method needs to be called in order to release the local + * callback proxy on the server side and thus dereference the callback + * implementation on the client side. + * * @return retval operation completion status. */ setCallback(IStreamOutCallback callback) generates (Result retval); + /* + * Clears the callback previously set via 'setCallback' method. + * + * Warning: failure to call this method results in callback implementation + * on the client side being held until the HAL server termination. + * + * @return retval operation completion status: OK or NOT_SUPPORTED. + */ + clearCallback() generates (Result retval); + /* * Returns whether HAL supports pausing and resuming of streams. * diff --git a/audio/2.0/default/Conversions.cpp b/audio/2.0/default/Conversions.cpp index 1ba16e1c61..e6691851bb 100644 --- a/audio/2.0/default/Conversions.cpp +++ b/audio/2.0/default/Conversions.cpp @@ -29,27 +29,31 @@ std::string deviceAddressToHal(const DeviceAddress& address) { char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN]; memset(halAddress, 0, sizeof(halAddress)); uint32_t halDevice = static_cast(address.device); - if ((halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0 - || (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0) { + const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0; + if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN; + if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) + || (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) { 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) != 0 || (halDevice & AUDIO_DEVICE_IN_IP) != 0) { + } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) + || (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) { 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 ((halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0 - || (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0) { + } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) + || (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) { snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card, address.address.alsa.device); - } else if ((halDevice & AUDIO_DEVICE_OUT_BUS) != 0 || (halDevice & AUDIO_DEVICE_IN_BUS) != 0) { + } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) + || (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) { snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str()); - } else if ((halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) != 0 - || (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0) { + } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 + || (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) { snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str()); } diff --git a/audio/2.0/default/Device.cpp b/audio/2.0/default/Device.cpp index 339f371763..9c227f61c0 100644 --- a/audio/2.0/default/Device.cpp +++ b/audio/2.0/default/Device.cpp @@ -15,6 +15,7 @@ */ #define LOG_TAG "DeviceHAL" +//#define LOG_NDEBUG 0 #include #include @@ -24,6 +25,7 @@ #include "Conversions.h" #include "Device.h" +#include "HidlUtils.h" #include "StreamIn.h" #include "StreamOut.h" @@ -43,267 +45,6 @@ Device::~Device() { mDevice = nullptr; } -// static -void Device::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) { - memset(halConfig, 0, sizeof(audio_config_t)); - halConfig->sample_rate = config.sampleRateHz; - halConfig->channel_mask = static_cast(config.channelMask); - halConfig->format = static_cast(config.format); - audioOffloadInfoToHal(config.offloadInfo, &halConfig->offload_info); - halConfig->frame_count = config.frameCount; -} - -// static -void Device::audioGainConfigFromHal( - const struct audio_gain_config& halConfig, AudioGainConfig* config) { - config->index = halConfig.index; - config->mode = AudioGainMode(halConfig.mode); - config->channelMask = AudioChannelMask(halConfig.channel_mask); - for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) { - config->values[i] = halConfig.values[i]; - } - config->rampDurationMs = halConfig.ramp_duration_ms; -} - -// static -void Device::audioGainConfigToHal( - const AudioGainConfig& config, struct audio_gain_config* halConfig) { - halConfig->index = config.index; - halConfig->mode = static_cast(config.mode); - halConfig->channel_mask = static_cast(config.channelMask); - memset(halConfig->values, 0, sizeof(halConfig->values)); - for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) { - halConfig->values[i] = config.values[i]; - } - halConfig->ramp_duration_ms = config.rampDurationMs; -} - -// static -void Device::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) { - gain->mode = AudioGainMode(halGain.mode); - gain->channelMask = AudioChannelMask(halGain.channel_mask); - gain->minValue = halGain.min_value; - gain->maxValue = halGain.max_value; - gain->defaultValue = halGain.default_value; - gain->stepValue = halGain.step_value; - gain->minRampMs = halGain.min_ramp_ms; - gain->maxRampMs = halGain.max_ramp_ms; -} - -// static -void Device::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) { - halGain->mode = static_cast(gain.mode); - halGain->channel_mask = static_cast(gain.channelMask); - halGain->min_value = gain.minValue; - halGain->max_value = gain.maxValue; - halGain->default_value = gain.defaultValue; - halGain->step_value = gain.stepValue; - halGain->min_ramp_ms = gain.minRampMs; - halGain->max_ramp_ms = gain.maxRampMs; -} - -// static -void Device::audioOffloadInfoToHal( - const AudioOffloadInfo& offload, audio_offload_info_t* halOffload) { - *halOffload = AUDIO_INFO_INITIALIZER; - halOffload->sample_rate = offload.sampleRateHz; - halOffload->channel_mask = static_cast(offload.channelMask); - halOffload->stream_type = static_cast(offload.streamType); - halOffload->bit_rate = offload.bitRatePerSecond; - halOffload->duration_us = offload.durationMicroseconds; - halOffload->has_video = offload.hasVideo; - halOffload->is_streaming = offload.isStreaming; -} - -// static -void Device::audioPortConfigFromHal( - const struct audio_port_config& halConfig, AudioPortConfig* config) { - config->id = halConfig.id; - config->role = AudioPortRole(halConfig.role); - config->type = AudioPortType(halConfig.type); - config->configMask = AudioPortConfigMask(halConfig.config_mask); - config->sampleRateHz = halConfig.sample_rate; - config->channelMask = AudioChannelMask(halConfig.channel_mask); - config->format = AudioFormat(halConfig.format); - audioGainConfigFromHal(halConfig.gain, &config->gain); - switch (halConfig.type) { - case AUDIO_PORT_TYPE_NONE: break; - case AUDIO_PORT_TYPE_DEVICE: { - config->ext.device.hwModule = halConfig.ext.device.hw_module; - config->ext.device.type = AudioDevice(halConfig.ext.device.type); - memcpy(config->ext.device.address.data(), - halConfig.ext.device.address, - AUDIO_DEVICE_MAX_ADDRESS_LEN); - break; - } - case AUDIO_PORT_TYPE_MIX: { - config->ext.mix.hwModule = halConfig.ext.mix.hw_module; - config->ext.mix.ioHandle = halConfig.ext.mix.handle; - if (halConfig.role == AUDIO_PORT_ROLE_SOURCE) { - config->ext.mix.useCase.source = AudioSource(halConfig.ext.mix.usecase.source); - } else if (halConfig.role == AUDIO_PORT_ROLE_SINK) { - config->ext.mix.useCase.stream = AudioStreamType(halConfig.ext.mix.usecase.stream); - } - break; - } - case AUDIO_PORT_TYPE_SESSION: { - config->ext.session.session = halConfig.ext.session.session; - break; - } - } -} - -// static -void Device::audioPortConfigToHal( - const AudioPortConfig& config, struct audio_port_config* halConfig) { - memset(halConfig, 0, sizeof(audio_port_config)); - halConfig->id = config.id; - halConfig->role = static_cast(config.role); - halConfig->type = static_cast(config.type); - halConfig->config_mask = static_cast(config.configMask); - halConfig->sample_rate = config.sampleRateHz; - halConfig->channel_mask = static_cast(config.channelMask); - halConfig->format = static_cast(config.format); - audioGainConfigToHal(config.gain, &halConfig->gain); - switch (config.type) { - case AudioPortType::NONE: break; - case AudioPortType::DEVICE: { - halConfig->ext.device.hw_module = config.ext.device.hwModule; - halConfig->ext.device.type = static_cast(config.ext.device.type); - memcpy(halConfig->ext.device.address, - config.ext.device.address.data(), - AUDIO_DEVICE_MAX_ADDRESS_LEN); - break; - } - case AudioPortType::MIX: { - halConfig->ext.mix.hw_module = config.ext.mix.hwModule; - halConfig->ext.mix.handle = config.ext.mix.ioHandle; - if (config.role == AudioPortRole::SOURCE) { - halConfig->ext.mix.usecase.source = - static_cast(config.ext.mix.useCase.source); - } else if (config.role == AudioPortRole::SINK) { - halConfig->ext.mix.usecase.stream = - static_cast(config.ext.mix.useCase.stream); - } - break; - } - case AudioPortType::SESSION: { - halConfig->ext.session.session = - static_cast(config.ext.session.session); - break; - } - } -} - -// static -std::unique_ptr Device::audioPortConfigsToHal( - const hidl_vec& configs) { - std::unique_ptr halConfigs(new audio_port_config[configs.size()]); - for (size_t i = 0; i < configs.size(); ++i) { - audioPortConfigToHal(configs[i], &halConfigs[i]); - } - return halConfigs; -} - -// static -void Device::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) { - port->id = halPort.id; - port->role = AudioPortRole(halPort.role); - port->type = AudioPortType(halPort.type); - port->name.setToExternal(halPort.name, strlen(halPort.name)); - port->sampleRates.resize(halPort.num_sample_rates); - for (size_t i = 0; i < halPort.num_sample_rates; ++i) { - port->sampleRates[i] = halPort.sample_rates[i]; - } - port->channelMasks.resize(halPort.num_channel_masks); - for (size_t i = 0; i < halPort.num_channel_masks; ++i) { - port->channelMasks[i] = AudioChannelMask(halPort.channel_masks[i]); - } - port->formats.resize(halPort.num_formats); - for (size_t i = 0; i < halPort.num_formats; ++i) { - port->formats[i] = AudioFormat(halPort.formats[i]); - } - port->gains.resize(halPort.num_gains); - for (size_t i = 0; i < halPort.num_gains; ++i) { - audioGainFromHal(halPort.gains[i], &port->gains[i]); - } - audioPortConfigFromHal(halPort.active_config, &port->activeConfig); - switch (halPort.type) { - case AUDIO_PORT_TYPE_NONE: break; - case AUDIO_PORT_TYPE_DEVICE: { - port->ext.device.hwModule = halPort.ext.device.hw_module; - port->ext.device.type = AudioDevice(halPort.ext.device.type); - memcpy(port->ext.device.address.data(), - halPort.ext.device.address, - AUDIO_DEVICE_MAX_ADDRESS_LEN); - break; - } - case AUDIO_PORT_TYPE_MIX: { - port->ext.mix.hwModule = halPort.ext.mix.hw_module; - port->ext.mix.ioHandle = halPort.ext.mix.handle; - port->ext.mix.latencyClass = AudioMixLatencyClass(halPort.ext.mix.latency_class); - break; - } - case AUDIO_PORT_TYPE_SESSION: { - port->ext.session.session = halPort.ext.session.session; - break; - } - } -} - -// static -void Device::audioPortToHal(const AudioPort& port, struct audio_port* halPort) { - memset(halPort, 0, sizeof(audio_port)); - halPort->id = port.id; - halPort->role = static_cast(port.role); - halPort->type = static_cast(port.type); - memcpy(halPort->name, - port.name.c_str(), - std::min(port.name.size(), static_cast(AUDIO_PORT_MAX_NAME_LEN))); - halPort->num_sample_rates = - std::min(port.sampleRates.size(), static_cast(AUDIO_PORT_MAX_SAMPLING_RATES)); - for (size_t i = 0; i < halPort->num_sample_rates; ++i) { - halPort->sample_rates[i] = port.sampleRates[i]; - } - halPort->num_channel_masks = - std::min(port.channelMasks.size(), static_cast(AUDIO_PORT_MAX_CHANNEL_MASKS)); - for (size_t i = 0; i < halPort->num_channel_masks; ++i) { - halPort->channel_masks[i] = static_cast(port.channelMasks[i]); - } - halPort->num_formats = - std::min(port.formats.size(), static_cast(AUDIO_PORT_MAX_FORMATS)); - for (size_t i = 0; i < halPort->num_formats; ++i) { - halPort->formats[i] = static_cast(port.formats[i]); - } - halPort->num_gains = std::min(port.gains.size(), static_cast(AUDIO_PORT_MAX_GAINS)); - for (size_t i = 0; i < halPort->num_gains; ++i) { - audioGainToHal(port.gains[i], &halPort->gains[i]); - } - audioPortConfigToHal(port.activeConfig, &halPort->active_config); - switch (port.type) { - case AudioPortType::NONE: break; - case AudioPortType::DEVICE: { - halPort->ext.device.hw_module = port.ext.device.hwModule; - halPort->ext.device.type = static_cast(port.ext.device.type); - memcpy(halPort->ext.device.address, - port.ext.device.address.data(), - AUDIO_DEVICE_MAX_ADDRESS_LEN); - break; - } - case AudioPortType::MIX: { - halPort->ext.mix.hw_module = port.ext.mix.hwModule; - halPort->ext.mix.handle = port.ext.mix.ioHandle; - halPort->ext.mix.latency_class = - static_cast(port.ext.mix.latencyClass); - break; - } - case AudioPortType::SESSION: { - halPort->ext.session.session = static_cast(port.ext.session.session); - break; - } - } -} - Result Device::analyzeStatus(const char* funcName, int status) { if (status != 0) { ALOGW("Device %p %s: %s", mDevice, funcName, strerror(-status)); @@ -381,7 +122,7 @@ Return Device::getMasterMute(getMasterMute_cb _hidl_cb) { Return Device::getInputBufferSize( const AudioConfig& config, getInputBufferSize_cb _hidl_cb) { audio_config_t halConfig; - audioConfigToHal(config, &halConfig); + HidlUtils::audioConfigToHal(config, &halConfig); size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig); Result retval(Result::INVALID_ARGUMENTS); uint64_t bufferSize = 0; @@ -400,8 +141,14 @@ Return Device::openOutputStream( AudioOutputFlag flags, openOutputStream_cb _hidl_cb) { audio_config_t halConfig; - audioConfigToHal(config, &halConfig); + HidlUtils::audioConfigToHal(config, &halConfig); audio_stream_out_t *halStream; + ALOGV("open_output_stream handle: %d devices: %x flags: %#x " + "srate: %d format %#x channels %x address %s", + ioHandle, + static_cast(device.device), static_cast(flags), + halConfig.sample_rate, halConfig.format, halConfig.channel_mask, + deviceAddressToHal(device).c_str()); int status = mDevice->open_output_stream( mDevice, ioHandle, @@ -410,11 +157,14 @@ Return Device::openOutputStream( &halConfig, &halStream, deviceAddressToHal(device).c_str()); + ALOGV("open_output_stream status %d stream %p", status, halStream); sp streamOut; if (status == OK) { streamOut = new StreamOut(mDevice, halStream); } - _hidl_cb(analyzeStatus("open_output_stream", status), streamOut); + AudioConfig suggestedConfig; + HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig); + _hidl_cb(analyzeStatus("open_output_stream", status), streamOut, suggestedConfig); return Void(); } @@ -426,8 +176,14 @@ Return Device::openInputStream( AudioSource source, openInputStream_cb _hidl_cb) { audio_config_t halConfig; - audioConfigToHal(config, &halConfig); + HidlUtils::audioConfigToHal(config, &halConfig); audio_stream_in_t *halStream; + ALOGV("open_input_stream handle: %d devices: %x flags: %#x " + "srate: %d format %#x channels %x address %s source %d", + ioHandle, + static_cast(device.device), static_cast(flags), + halConfig.sample_rate, halConfig.format, halConfig.channel_mask, + deviceAddressToHal(device).c_str(), static_cast(source)); int status = mDevice->open_input_stream( mDevice, ioHandle, @@ -437,14 +193,21 @@ Return Device::openInputStream( static_cast(flags), deviceAddressToHal(device).c_str(), static_cast(source)); + ALOGV("open_input_stream status %d stream %p", status, halStream); sp streamIn; if (status == OK) { streamIn = new StreamIn(mDevice, halStream); } - _hidl_cb(analyzeStatus("open_input_stream", status), streamIn); + AudioConfig suggestedConfig; + HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig); + _hidl_cb(analyzeStatus("open_input_stream", status), streamIn, suggestedConfig); return Void(); } +Return Device::supportsAudioPatches() { + return version() >= AUDIO_DEVICE_API_VERSION_3_0; +} + Return Device::createAudioPatch( const hidl_vec& sources, const hidl_vec& sinks, @@ -452,8 +215,8 @@ Return Device::createAudioPatch( Result retval(Result::NOT_SUPPORTED); AudioPatchHandle patch = 0; if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { - std::unique_ptr halSources(audioPortConfigsToHal(sources)); - std::unique_ptr halSinks(audioPortConfigsToHal(sinks)); + std::unique_ptr halSources(HidlUtils::audioPortConfigsToHal(sources)); + std::unique_ptr halSinks(HidlUtils::audioPortConfigsToHal(sinks)); audio_patch_handle_t halPatch; retval = analyzeStatus( "create_audio_patch", @@ -481,11 +244,11 @@ Return Device::releaseAudioPatch(int32_t patch) { Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { audio_port halPort; - audioPortToHal(port, &halPort); + HidlUtils::audioPortToHal(port, &halPort); Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort)); AudioPort resultPort = port; if (retval == Result::OK) { - audioPortFromHal(halPort, &resultPort); + HidlUtils::audioPortFromHal(halPort, &resultPort); } _hidl_cb(retval, resultPort); return Void(); @@ -494,7 +257,7 @@ Return Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_c Return Device::setAudioPortConfig(const AudioPortConfig& config) { if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { struct audio_port_config halPortConfig; - audioPortConfigToHal(config, &halPortConfig); + HidlUtils::audioPortConfigToHal(config, &halPortConfig); return analyzeStatus( "set_audio_port_config", mDevice->set_audio_port_config(mDevice, &halPortConfig)); } diff --git a/audio/2.0/default/Device.h b/audio/2.0/default/Device.h index 3fd67e39b7..a7d95a0a92 100644 --- a/audio/2.0/default/Device.h +++ b/audio/2.0/default/Device.h @@ -36,22 +36,13 @@ namespace V2_0 { namespace implementation { using ::android::hardware::audio::common::V2_0::AudioConfig; -using ::android::hardware::audio::common::V2_0::AudioGain; -using ::android::hardware::audio::common::V2_0::AudioGainConfig; -using ::android::hardware::audio::common::V2_0::AudioGainMode; using ::android::hardware::audio::common::V2_0::AudioHwSync; using ::android::hardware::audio::common::V2_0::AudioInputFlag; -using ::android::hardware::audio::common::V2_0::AudioMixLatencyClass; -using ::android::hardware::audio::common::V2_0::AudioOffloadInfo; using ::android::hardware::audio::common::V2_0::AudioOutputFlag; using ::android::hardware::audio::common::V2_0::AudioPatchHandle; using ::android::hardware::audio::common::V2_0::AudioPort; using ::android::hardware::audio::common::V2_0::AudioPortConfig; -using ::android::hardware::audio::common::V2_0::AudioPortConfigMask; -using ::android::hardware::audio::common::V2_0::AudioPortRole; -using ::android::hardware::audio::common::V2_0::AudioPortType; using ::android::hardware::audio::common::V2_0::AudioSource; -using ::android::hardware::audio::common::V2_0::AudioStreamType; using ::android::hardware::audio::V2_0::DeviceAddress; using ::android::hardware::audio::V2_0::IDevice; using ::android::hardware::audio::V2_0::IStreamIn; @@ -90,6 +81,7 @@ struct Device : public IDevice, public ParametersUtil { AudioInputFlag flags, AudioSource source, openInputStream_cb _hidl_cb) override; + Return supportsAudioPatches() override; Return createAudioPatch( const hidl_vec& sources, const hidl_vec& sinks, @@ -111,24 +103,6 @@ struct Device : public IDevice, public ParametersUtil { private: audio_hw_device_t *mDevice; - static void audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); - static void audioGainConfigFromHal( - const struct audio_gain_config& halConfig, AudioGainConfig* config); - static void audioGainConfigToHal( - const AudioGainConfig& config, struct audio_gain_config* halConfig); - static void audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain); - static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain); - static void audioOffloadInfoToHal( - const AudioOffloadInfo& offload, audio_offload_info_t* halOffload); - static void audioPortConfigFromHal( - const struct audio_port_config& halConfig, AudioPortConfig* config); - static void audioPortConfigToHal( - const AudioPortConfig& config, struct audio_port_config* halConfig); - static std::unique_ptr audioPortConfigsToHal( - const hidl_vec& configs); - static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port); - static void audioPortToHal(const AudioPort& port, struct audio_port* halPort); - virtual ~Device(); // Methods from ParametersUtil. diff --git a/audio/2.0/default/PrimaryDevice.cpp b/audio/2.0/default/PrimaryDevice.cpp index a8aa5ecd8a..905203b539 100644 --- a/audio/2.0/default/PrimaryDevice.cpp +++ b/audio/2.0/default/PrimaryDevice.cpp @@ -83,6 +83,10 @@ Return PrimaryDevice::openInputStream( return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb); } +Return PrimaryDevice::supportsAudioPatches() { + return mDevice->supportsAudioPatches(); +} + Return PrimaryDevice::createAudioPatch( const hidl_vec& sources, const hidl_vec& sinks, diff --git a/audio/2.0/default/PrimaryDevice.h b/audio/2.0/default/PrimaryDevice.h index 968c208d52..db01fb3699 100644 --- a/audio/2.0/default/PrimaryDevice.h +++ b/audio/2.0/default/PrimaryDevice.h @@ -76,6 +76,7 @@ struct PrimaryDevice : public IPrimaryDevice { AudioInputFlag flags, AudioSource source, openInputStream_cb _hidl_cb) override; + Return supportsAudioPatches() override; Return createAudioPatch( const hidl_vec& sources, const hidl_vec& sinks, diff --git a/audio/2.0/default/StreamOut.cpp b/audio/2.0/default/StreamOut.cpp index 21062565b2..4ee4961d3c 100644 --- a/audio/2.0/default/StreamOut.cpp +++ b/audio/2.0/default/StreamOut.cpp @@ -191,23 +191,27 @@ Return StreamOut::setCallback(const sp& callback) { return mStreamCommon->analyzeStatus("set_callback", result); } +Return StreamOut::clearCallback() { + if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED; + mCallback.clear(); + return Result::OK; +} + // static int StreamOut::asyncCallback(stream_callback_event_t event, void*, void *cookie) { wp weakSelf(reinterpret_cast(cookie)); sp self = weakSelf.promote(); - if (self == 0) return 0; - sp callback = self->mCallback.promote(); - if (callback == 0) return 0; + if (self == nullptr || self->mCallback == nullptr) return 0; ALOGV("asyncCallback() event %d", event); switch (event) { case STREAM_CBK_EVENT_WRITE_READY: - callback->onWriteReady(); + self->mCallback->onWriteReady(); break; case STREAM_CBK_EVENT_DRAIN_READY: - callback->onDrainReady(); + self->mCallback->onDrainReady(); break; case STREAM_CBK_EVENT_ERROR: - callback->onError(); + self->mCallback->onError(); break; default: ALOGW("asyncCallback() unknown event %d", event); diff --git a/audio/2.0/default/StreamOut.h b/audio/2.0/default/StreamOut.h index ca33b2dc84..b76214a543 100644 --- a/audio/2.0/default/StreamOut.h +++ b/audio/2.0/default/StreamOut.h @@ -83,6 +83,7 @@ struct StreamOut : public IStreamOut { Return getRenderPosition(getRenderPosition_cb _hidl_cb) override; Return getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) override; Return setCallback(const sp& callback) override; + Return clearCallback() override; Return supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb) override; Return pause() override; Return resume() override; @@ -95,9 +96,7 @@ struct StreamOut : public IStreamOut { audio_hw_device_t *mDevice; audio_stream_out_t *mStream; sp mStreamCommon; - // Do not store sp<> to avoid creating a reference loop if the entity that holds - // onto the output stream owns or implements the callback. - wp mCallback; + sp mCallback; virtual ~StreamOut(); diff --git a/audio/common/2.0/default/Android.mk b/audio/common/2.0/default/Android.mk index aa60eb269f..8e2fed4744 100644 --- a/audio/common/2.0/default/Android.mk +++ b/audio/common/2.0/default/Android.mk @@ -20,10 +20,13 @@ include $(CLEAR_VARS) LOCAL_MODULE := android.hardware.audio.common@2.0-util LOCAL_SRC_FILES := \ EffectMap.cpp \ + HidlUtils.cpp \ LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) LOCAL_SHARED_LIBRARIES := \ libutils \ + libhidlbase \ + android.hardware.audio.common@2.0 \ include $(BUILD_SHARED_LIBRARY) diff --git a/audio/common/2.0/default/HidlUtils.cpp b/audio/common/2.0/default/HidlUtils.cpp new file mode 100644 index 0000000000..f25fc5ce5f --- /dev/null +++ b/audio/common/2.0/default/HidlUtils.cpp @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "HidlUtils.h" + +using ::android::hardware::audio::common::V2_0::AudioChannelMask; +using ::android::hardware::audio::common::V2_0::AudioDevice; +using ::android::hardware::audio::common::V2_0::AudioFormat; +using ::android::hardware::audio::common::V2_0::AudioGainMode; +using ::android::hardware::audio::common::V2_0::AudioMixLatencyClass; +using ::android::hardware::audio::common::V2_0::AudioPortConfigMask; +using ::android::hardware::audio::common::V2_0::AudioPortRole; +using ::android::hardware::audio::common::V2_0::AudioPortType; +using ::android::hardware::audio::common::V2_0::AudioSource; +using ::android::hardware::audio::common::V2_0::AudioStreamType; + +namespace android { + +void HidlUtils::audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config) { + config->sampleRateHz = halConfig.sample_rate; + config->channelMask = AudioChannelMask(halConfig.channel_mask); + config->format = AudioFormat(halConfig.format); + audioOffloadInfoFromHal(halConfig.offload_info, &config->offloadInfo); + config->frameCount = halConfig.frame_count; +} + +void HidlUtils::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) { + memset(halConfig, 0, sizeof(audio_config_t)); + halConfig->sample_rate = config.sampleRateHz; + halConfig->channel_mask = static_cast(config.channelMask); + halConfig->format = static_cast(config.format); + audioOffloadInfoToHal(config.offloadInfo, &halConfig->offload_info); + halConfig->frame_count = config.frameCount; +} + +void HidlUtils::audioGainConfigFromHal( + const struct audio_gain_config& halConfig, AudioGainConfig* config) { + config->index = halConfig.index; + config->mode = AudioGainMode(halConfig.mode); + config->channelMask = AudioChannelMask(halConfig.channel_mask); + for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) { + config->values[i] = halConfig.values[i]; + } + config->rampDurationMs = halConfig.ramp_duration_ms; +} + +void HidlUtils::audioGainConfigToHal( + const AudioGainConfig& config, struct audio_gain_config* halConfig) { + halConfig->index = config.index; + halConfig->mode = static_cast(config.mode); + halConfig->channel_mask = static_cast(config.channelMask); + memset(halConfig->values, 0, sizeof(halConfig->values)); + for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) { + halConfig->values[i] = config.values[i]; + } + halConfig->ramp_duration_ms = config.rampDurationMs; +} + +void HidlUtils::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) { + gain->mode = AudioGainMode(halGain.mode); + gain->channelMask = AudioChannelMask(halGain.channel_mask); + gain->minValue = halGain.min_value; + gain->maxValue = halGain.max_value; + gain->defaultValue = halGain.default_value; + gain->stepValue = halGain.step_value; + gain->minRampMs = halGain.min_ramp_ms; + gain->maxRampMs = halGain.max_ramp_ms; +} + +void HidlUtils::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) { + halGain->mode = static_cast(gain.mode); + halGain->channel_mask = static_cast(gain.channelMask); + halGain->min_value = gain.minValue; + halGain->max_value = gain.maxValue; + halGain->default_value = gain.defaultValue; + halGain->step_value = gain.stepValue; + halGain->min_ramp_ms = gain.minRampMs; + halGain->max_ramp_ms = gain.maxRampMs; +} + +void HidlUtils::audioOffloadInfoFromHal( + const audio_offload_info_t& halOffload, AudioOffloadInfo* offload) { + offload->sampleRateHz = halOffload.sample_rate; + offload->channelMask = AudioChannelMask(halOffload.channel_mask); + offload->streamType = AudioStreamType(halOffload.stream_type); + offload->bitRatePerSecond = halOffload.bit_rate; + offload->durationMicroseconds = halOffload.duration_us; + offload->hasVideo = halOffload.has_video; + offload->isStreaming = halOffload.is_streaming; +} + +void HidlUtils::audioOffloadInfoToHal( + const AudioOffloadInfo& offload, audio_offload_info_t* halOffload) { + *halOffload = AUDIO_INFO_INITIALIZER; + halOffload->sample_rate = offload.sampleRateHz; + halOffload->channel_mask = static_cast(offload.channelMask); + halOffload->stream_type = static_cast(offload.streamType); + halOffload->bit_rate = offload.bitRatePerSecond; + halOffload->duration_us = offload.durationMicroseconds; + halOffload->has_video = offload.hasVideo; + halOffload->is_streaming = offload.isStreaming; +} + +void HidlUtils::audioPortConfigFromHal( + const struct audio_port_config& halConfig, AudioPortConfig* config) { + config->id = halConfig.id; + config->role = AudioPortRole(halConfig.role); + config->type = AudioPortType(halConfig.type); + config->configMask = AudioPortConfigMask(halConfig.config_mask); + config->sampleRateHz = halConfig.sample_rate; + config->channelMask = AudioChannelMask(halConfig.channel_mask); + config->format = AudioFormat(halConfig.format); + audioGainConfigFromHal(halConfig.gain, &config->gain); + switch (halConfig.type) { + case AUDIO_PORT_TYPE_NONE: break; + case AUDIO_PORT_TYPE_DEVICE: { + config->ext.device.hwModule = halConfig.ext.device.hw_module; + config->ext.device.type = AudioDevice(halConfig.ext.device.type); + memcpy(config->ext.device.address.data(), + halConfig.ext.device.address, + AUDIO_DEVICE_MAX_ADDRESS_LEN); + break; + } + case AUDIO_PORT_TYPE_MIX: { + config->ext.mix.hwModule = halConfig.ext.mix.hw_module; + config->ext.mix.ioHandle = halConfig.ext.mix.handle; + if (halConfig.role == AUDIO_PORT_ROLE_SOURCE) { + config->ext.mix.useCase.source = AudioSource(halConfig.ext.mix.usecase.source); + } else if (halConfig.role == AUDIO_PORT_ROLE_SINK) { + config->ext.mix.useCase.stream = AudioStreamType(halConfig.ext.mix.usecase.stream); + } + break; + } + case AUDIO_PORT_TYPE_SESSION: { + config->ext.session.session = halConfig.ext.session.session; + break; + } + } +} + +void HidlUtils::audioPortConfigToHal( + const AudioPortConfig& config, struct audio_port_config* halConfig) { + memset(halConfig, 0, sizeof(audio_port_config)); + halConfig->id = config.id; + halConfig->role = static_cast(config.role); + halConfig->type = static_cast(config.type); + halConfig->config_mask = static_cast(config.configMask); + halConfig->sample_rate = config.sampleRateHz; + halConfig->channel_mask = static_cast(config.channelMask); + halConfig->format = static_cast(config.format); + audioGainConfigToHal(config.gain, &halConfig->gain); + switch (config.type) { + case AudioPortType::NONE: break; + case AudioPortType::DEVICE: { + halConfig->ext.device.hw_module = config.ext.device.hwModule; + halConfig->ext.device.type = static_cast(config.ext.device.type); + memcpy(halConfig->ext.device.address, + config.ext.device.address.data(), + AUDIO_DEVICE_MAX_ADDRESS_LEN); + break; + } + case AudioPortType::MIX: { + halConfig->ext.mix.hw_module = config.ext.mix.hwModule; + halConfig->ext.mix.handle = config.ext.mix.ioHandle; + if (config.role == AudioPortRole::SOURCE) { + halConfig->ext.mix.usecase.source = + static_cast(config.ext.mix.useCase.source); + } else if (config.role == AudioPortRole::SINK) { + halConfig->ext.mix.usecase.stream = + static_cast(config.ext.mix.useCase.stream); + } + break; + } + case AudioPortType::SESSION: { + halConfig->ext.session.session = + static_cast(config.ext.session.session); + break; + } + } +} + +void HidlUtils::audioPortConfigsFromHal( + unsigned int numHalConfigs, const struct audio_port_config *halConfigs, + hidl_vec *configs) { + configs->resize(numHalConfigs); + for (unsigned int i = 0; i < numHalConfigs; ++i) { + audioPortConfigFromHal(halConfigs[i], &(*configs)[i]); + } +} + +std::unique_ptr HidlUtils::audioPortConfigsToHal( + const hidl_vec& configs) { + std::unique_ptr halConfigs(new audio_port_config[configs.size()]); + for (size_t i = 0; i < configs.size(); ++i) { + audioPortConfigToHal(configs[i], &halConfigs[i]); + } + return halConfigs; +} + +void HidlUtils::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) { + port->id = halPort.id; + port->role = AudioPortRole(halPort.role); + port->type = AudioPortType(halPort.type); + port->name.setToExternal(halPort.name, strlen(halPort.name)); + port->sampleRates.resize(halPort.num_sample_rates); + for (size_t i = 0; i < halPort.num_sample_rates; ++i) { + port->sampleRates[i] = halPort.sample_rates[i]; + } + port->channelMasks.resize(halPort.num_channel_masks); + for (size_t i = 0; i < halPort.num_channel_masks; ++i) { + port->channelMasks[i] = AudioChannelMask(halPort.channel_masks[i]); + } + port->formats.resize(halPort.num_formats); + for (size_t i = 0; i < halPort.num_formats; ++i) { + port->formats[i] = AudioFormat(halPort.formats[i]); + } + port->gains.resize(halPort.num_gains); + for (size_t i = 0; i < halPort.num_gains; ++i) { + audioGainFromHal(halPort.gains[i], &port->gains[i]); + } + audioPortConfigFromHal(halPort.active_config, &port->activeConfig); + switch (halPort.type) { + case AUDIO_PORT_TYPE_NONE: break; + case AUDIO_PORT_TYPE_DEVICE: { + port->ext.device.hwModule = halPort.ext.device.hw_module; + port->ext.device.type = AudioDevice(halPort.ext.device.type); + memcpy(port->ext.device.address.data(), + halPort.ext.device.address, + AUDIO_DEVICE_MAX_ADDRESS_LEN); + break; + } + case AUDIO_PORT_TYPE_MIX: { + port->ext.mix.hwModule = halPort.ext.mix.hw_module; + port->ext.mix.ioHandle = halPort.ext.mix.handle; + port->ext.mix.latencyClass = AudioMixLatencyClass(halPort.ext.mix.latency_class); + break; + } + case AUDIO_PORT_TYPE_SESSION: { + port->ext.session.session = halPort.ext.session.session; + break; + } + } +} + +void HidlUtils::audioPortToHal(const AudioPort& port, struct audio_port* halPort) { + memset(halPort, 0, sizeof(audio_port)); + halPort->id = port.id; + halPort->role = static_cast(port.role); + halPort->type = static_cast(port.type); + memcpy(halPort->name, + port.name.c_str(), + std::min(port.name.size(), static_cast(AUDIO_PORT_MAX_NAME_LEN))); + halPort->num_sample_rates = + std::min(port.sampleRates.size(), static_cast(AUDIO_PORT_MAX_SAMPLING_RATES)); + for (size_t i = 0; i < halPort->num_sample_rates; ++i) { + halPort->sample_rates[i] = port.sampleRates[i]; + } + halPort->num_channel_masks = + std::min(port.channelMasks.size(), static_cast(AUDIO_PORT_MAX_CHANNEL_MASKS)); + for (size_t i = 0; i < halPort->num_channel_masks; ++i) { + halPort->channel_masks[i] = static_cast(port.channelMasks[i]); + } + halPort->num_formats = + std::min(port.formats.size(), static_cast(AUDIO_PORT_MAX_FORMATS)); + for (size_t i = 0; i < halPort->num_formats; ++i) { + halPort->formats[i] = static_cast(port.formats[i]); + } + halPort->num_gains = std::min(port.gains.size(), static_cast(AUDIO_PORT_MAX_GAINS)); + for (size_t i = 0; i < halPort->num_gains; ++i) { + audioGainToHal(port.gains[i], &halPort->gains[i]); + } + audioPortConfigToHal(port.activeConfig, &halPort->active_config); + switch (port.type) { + case AudioPortType::NONE: break; + case AudioPortType::DEVICE: { + halPort->ext.device.hw_module = port.ext.device.hwModule; + halPort->ext.device.type = static_cast(port.ext.device.type); + memcpy(halPort->ext.device.address, + port.ext.device.address.data(), + AUDIO_DEVICE_MAX_ADDRESS_LEN); + break; + } + case AudioPortType::MIX: { + halPort->ext.mix.hw_module = port.ext.mix.hwModule; + halPort->ext.mix.handle = port.ext.mix.ioHandle; + halPort->ext.mix.latency_class = + static_cast(port.ext.mix.latencyClass); + break; + } + case AudioPortType::SESSION: { + halPort->ext.session.session = static_cast(port.ext.session.session); + break; + } + } +} + +void HidlUtils::uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid) { + uuid->timeLow = halUuid.timeLow; + uuid->timeMid = halUuid.timeMid; + uuid->versionAndTimeHigh = halUuid.timeHiAndVersion; + uuid->variantAndClockSeqHigh = halUuid.clockSeq; + memcpy(uuid->node.data(), halUuid.node, uuid->node.size()); +} + +void HidlUtils::uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid) { + halUuid->timeLow = uuid.timeLow; + halUuid->timeMid = uuid.timeMid; + halUuid->timeHiAndVersion = uuid.versionAndTimeHigh; + halUuid->clockSeq = uuid.variantAndClockSeqHigh; + memcpy(halUuid->node, uuid.node.data(), uuid.node.size()); +} + +} // namespace android diff --git a/audio/common/2.0/default/HidlUtils.h b/audio/common/2.0/default/HidlUtils.h new file mode 100644 index 0000000000..3fde4d7c8a --- /dev/null +++ b/audio/common/2.0/default/HidlUtils.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef android_hardware_audio_V2_0_Hidl_Utils_H_ +#define android_hardware_audio_V2_0_Hidl_Utils_H_ + +#include + +#include +#include + +using ::android::hardware::audio::common::V2_0::AudioConfig; +using ::android::hardware::audio::common::V2_0::AudioGain; +using ::android::hardware::audio::common::V2_0::AudioGainConfig; +using ::android::hardware::audio::common::V2_0::AudioOffloadInfo; +using ::android::hardware::audio::common::V2_0::AudioPort; +using ::android::hardware::audio::common::V2_0::AudioPortConfig; +using ::android::hardware::audio::common::V2_0::Uuid; +using ::android::hardware::hidl_vec; + +namespace android { + +class HidlUtils { + public: + static void audioConfigFromHal(const audio_config_t& halConfig, AudioConfig* config); + static void audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig); + static void audioGainConfigFromHal( + const struct audio_gain_config& halConfig, AudioGainConfig* config); + static void audioGainConfigToHal( + const AudioGainConfig& config, struct audio_gain_config* halConfig); + static void audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain); + static void audioGainToHal(const AudioGain& gain, struct audio_gain* halGain); + static void audioOffloadInfoFromHal( + const audio_offload_info_t& halOffload, AudioOffloadInfo* offload); + static void audioOffloadInfoToHal( + const AudioOffloadInfo& offload, audio_offload_info_t* halOffload); + static void audioPortConfigFromHal( + const struct audio_port_config& halConfig, AudioPortConfig* config); + static void audioPortConfigToHal( + const AudioPortConfig& config, struct audio_port_config* halConfig); + static void audioPortConfigsFromHal( + unsigned int numHalConfigs, const struct audio_port_config *halConfigs, + hidl_vec *configs); + static std::unique_ptr audioPortConfigsToHal( + const hidl_vec& configs); + static void audioPortFromHal(const struct audio_port& halPort, AudioPort* port); + static void audioPortToHal(const AudioPort& port, struct audio_port* halPort); + static void uuidFromHal(const audio_uuid_t& halUuid, Uuid* uuid); + static void uuidToHal(const Uuid& uuid, audio_uuid_t* halUuid); +}; + +} // namespace android + +#endif // android_hardware_audio_V2_0_Hidl_Utils_H_ diff --git a/audio/effect/2.0/default/Conversions.cpp b/audio/effect/2.0/default/Conversions.cpp index ef2374cd80..e7d4c46388 100644 --- a/audio/effect/2.0/default/Conversions.cpp +++ b/audio/effect/2.0/default/Conversions.cpp @@ -18,6 +18,7 @@ #include #include "Conversions.h" +#include "HidlUtils.h" namespace android { namespace hardware { @@ -28,8 +29,8 @@ namespace implementation { void effectDescriptorFromHal( const effect_descriptor_t& halDescriptor, EffectDescriptor* descriptor) { - uuidFromHal(halDescriptor.type, &descriptor->type); - uuidFromHal(halDescriptor.uuid, &descriptor->uuid); + HidlUtils::uuidFromHal(halDescriptor.type, &descriptor->type); + HidlUtils::uuidFromHal(halDescriptor.uuid, &descriptor->uuid); descriptor->flags = EffectFlags(halDescriptor.flags); descriptor->cpuLoad = halDescriptor.cpuLoad; descriptor->memoryUsage = halDescriptor.memoryUsage; @@ -38,22 +39,6 @@ void effectDescriptorFromHal( halDescriptor.implementor, descriptor->implementor.size()); } -void uuidFromHal(const effect_uuid_t& halUuid, Uuid* uuid) { - uuid->timeLow = halUuid.timeLow; - uuid->timeMid = halUuid.timeMid; - uuid->versionAndTimeHigh = halUuid.timeHiAndVersion; - uuid->variantAndClockSeqHigh = halUuid.clockSeq; - memcpy(uuid->node.data(), halUuid.node, uuid->node.size()); -} - -void uuidToHal(const Uuid& uuid, effect_uuid_t* halUuid) { - halUuid->timeLow = uuid.timeLow; - halUuid->timeMid = uuid.timeMid; - halUuid->timeHiAndVersion = uuid.versionAndTimeHigh; - halUuid->clockSeq = uuid.variantAndClockSeqHigh; - memcpy(halUuid->node, uuid.node.data(), uuid.node.size()); -} - std::string uuidToString(const effect_uuid_t& halUuid) { char str[64]; snprintf(str, sizeof(str), "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x", diff --git a/audio/effect/2.0/default/Conversions.h b/audio/effect/2.0/default/Conversions.h index 5348ae6686..7cef362c35 100644 --- a/audio/effect/2.0/default/Conversions.h +++ b/audio/effect/2.0/default/Conversions.h @@ -29,13 +29,10 @@ namespace effect { namespace V2_0 { namespace implementation { -using ::android::hardware::audio::common::V2_0::Uuid; using ::android::hardware::audio::effect::V2_0::EffectDescriptor; void effectDescriptorFromHal( const effect_descriptor_t& halDescriptor, EffectDescriptor* descriptor); -void uuidFromHal(const effect_uuid_t& halUuid, Uuid* uuid); -void uuidToHal(const Uuid& uuid, effect_uuid_t* halUuid); std::string uuidToString(const effect_uuid_t& halUuid); } // namespace implementation diff --git a/audio/effect/2.0/default/Effect.cpp b/audio/effect/2.0/default/Effect.cpp index 82d0292d4e..6553da4767 100644 --- a/audio/effect/2.0/default/Effect.cpp +++ b/audio/effect/2.0/default/Effect.cpp @@ -14,7 +14,6 @@ * limitations under the License. */ -#include #include #define LOG_TAG "EffectHAL" @@ -56,10 +55,15 @@ template size_t Effect::alignedSizeIn(size_t s) { } // static -template void Effect::hidlVecToHal( - const hidl_vec& vec, uint32_t* halDataSize, void** halData) { - *halDataSize = static_cast(vec.size() * sizeof(T)); - *halData = static_cast(const_cast(&vec[0])); +template std::unique_ptr Effect::hidlVecToHal( + const hidl_vec& vec, uint32_t* halDataSize) { + // Due to bugs in HAL, they may attempt to write into the provided + // input buffer. The original binder buffer is r/o, thus it is needed + // to create a r/w version. + *halDataSize = vec.size() * sizeof(T); + std::unique_ptr halData(new uint8_t[*halDataSize]); + memcpy(&halData[0], &vec[0], *halDataSize); + return halData; } // static @@ -393,12 +397,13 @@ Return Effect::setDevice(AudioDevice device) { Return Effect::setAndGetVolume( const hidl_vec& volumes, setAndGetVolume_cb _hidl_cb) { uint32_t halDataSize; - void *halData; - hidlVecToHal(volumes, &halDataSize, &halData); + std::unique_ptr halData = hidlVecToHal(volumes, &halDataSize); uint32_t halResultSize = halDataSize; uint32_t halResult[volumes.size()]; Result retval = sendCommandReturningData( - EFFECT_CMD_SET_VOLUME, "SET_VOLUME", halDataSize, halData, &halResultSize, halResult); + EFFECT_CMD_SET_VOLUME, "SET_VOLUME", + halDataSize, &halData[0], + &halResultSize, halResult); hidl_vec result; if (retval == Result::OK) { result.setToExternal(&halResult[0], halResultSize); @@ -528,13 +533,12 @@ Return Effect::command( uint32_t resultMaxSize, command_cb _hidl_cb) { uint32_t halDataSize; - void *halData; - hidlVecToHal(data, &halDataSize, &halData); + std::unique_ptr halData = hidlVecToHal(data, &halDataSize); uint32_t halResultSize = resultMaxSize; std::unique_ptr halResult(new uint8_t[halResultSize]); memset(&halResult[0], 0, halResultSize); status_t status = (*mHandle)->command( - mHandle, commandId, halDataSize, halData, &halResultSize, &halResult[0]); + mHandle, commandId, halDataSize, &halData[0], &halResultSize, &halResult[0]); hidl_vec result; if (status == OK) { result.setToExternal(&halResult[0], halResultSize); diff --git a/audio/effect/2.0/default/Effect.h b/audio/effect/2.0/default/Effect.h index e27a7e4c6e..ff57051c21 100644 --- a/audio/effect/2.0/default/Effect.h +++ b/audio/effect/2.0/default/Effect.h @@ -17,6 +17,7 @@ #ifndef HIDL_GENERATED_android_hardware_audio_effect_V2_0_Effect_H_ #define HIDL_GENERATED_android_hardware_audio_effect_V2_0_Effect_H_ +#include #include #include @@ -180,8 +181,8 @@ struct Effect : public IEffect { virtual ~Effect(); template static size_t alignedSizeIn(size_t s); - template static void hidlVecToHal( - const hidl_vec& vec, uint32_t* halDataSize, void** halData); + template std::unique_ptr hidlVecToHal( + const hidl_vec& vec, uint32_t* halDataSize); static void effectAuxChannelsConfigFromHal( const channel_config_t& halConfig, EffectAuxChannelsConfig* config); static void effectAuxChannelsConfigToHal( diff --git a/audio/effect/2.0/default/EffectsFactory.cpp b/audio/effect/2.0/default/EffectsFactory.cpp index 2b5d70ba2b..2bfe6af573 100644 --- a/audio/effect/2.0/default/EffectsFactory.cpp +++ b/audio/effect/2.0/default/EffectsFactory.cpp @@ -33,8 +33,9 @@ #include "AutomaticGainControlEffect.h" #include "BassBoostEffect.h" #include "Conversions.h" -#include "EffectsFactory.h" #include "DownmixEffect.h" +#include "EffectsFactory.h" +#include "HidlUtils.h" #include "Effect.h" #include "EffectMap.h" #include "EnvironmentalReverbEffect.h" @@ -131,7 +132,7 @@ exit: Return EffectsFactory::getDescriptor(const Uuid& uid, getDescriptor_cb _hidl_cb) { effect_uuid_t halUuid; - uuidToHal(uid, &halUuid); + HidlUtils::uuidToHal(uid, &halUuid); effect_descriptor_t halDescriptor; status_t status = EffectGetDescriptor(&halUuid, &halDescriptor); EffectDescriptor descriptor; @@ -153,7 +154,7 @@ Return EffectsFactory::getDescriptor(const Uuid& uid, getDescriptor_cb _hi Return EffectsFactory::createEffect( const Uuid& uid, int32_t session, int32_t ioHandle, createEffect_cb _hidl_cb) { effect_uuid_t halUuid; - uuidToHal(uid, &halUuid); + HidlUtils::uuidToHal(uid, &halUuid); effect_handle_t handle; Result retval(Result::OK); status_t status = EffectCreate(&halUuid, session, ioHandle, &handle);