mirror of
https://github.com/Evolution-X/hardware_interfaces
synced 2026-02-01 11:36:00 +00:00
Implement audio devices and streams HAL delegating to legacy HAL
Changes made to the .hal definition:
- introduce Effect ID returned by the IEffectsFactory that
needs to be passed to IStream.{add|remove}Effect; otherwise
it's impossible to retrieve the underlying HAL effect handle;
- change "bus address" in DeviceAddress to "string" type;
- fix signature of some methods w.r.t. returning Result;
- remove unused "struct AudioPatch".
Bug: 30222631
Test: make
Change-Id: Icb51729ef57bb2a5b0b78609735e7481bc04f95c
This commit is contained in:
@@ -180,19 +180,20 @@ interface IDevice {
|
||||
|
||||
/*
|
||||
* Gets the HW synchronization source of the device. Calling this method is
|
||||
* equivalent to getting AUDIO_PARAMETER_STREAM_HW_AV_SYNC on the legacy
|
||||
* HAL.
|
||||
* equivalent to getting AUDIO_PARAMETER_HW_AV_SYNC on the legacy HAL.
|
||||
*
|
||||
* @return retval operation completion status.
|
||||
* @return hwAvSync HW synchronization source
|
||||
*/
|
||||
getHwAvSync() generates (Result retval, AudioHwSync hwAvSync);
|
||||
getHwAvSync() generates (AudioHwSync hwAvSync);
|
||||
|
||||
/*
|
||||
* Sets whether the screen is on. Calling this method is equivalent to
|
||||
* setting AUDIO_PARAMETER_KEY_SCREEN_STATE on the legacy HAL.
|
||||
*
|
||||
* @param turnedOn whether the screen is turned on.
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
setScreenState(bool turnedOn);
|
||||
setScreenState(bool turnedOn) generates (Result retval);
|
||||
|
||||
/*
|
||||
* Generic method for retrieving vendor-specific parameter values.
|
||||
|
||||
@@ -134,18 +134,20 @@ interface IStream {
|
||||
/*
|
||||
* Applies audio effect to the stream.
|
||||
*
|
||||
* @param effect the effect to apply.
|
||||
* @param effectId effect ID (obtained from IEffectsFactory.createEffect) of
|
||||
* the effect to apply.
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
addEffect(IEffect effect) generates (Result retval);
|
||||
addEffect(uint64_t effectId) generates (Result retval);
|
||||
|
||||
/*
|
||||
* Stops application of the effect to the stream.
|
||||
*
|
||||
* @param effect the effect to apply.
|
||||
* @param effectId effect ID (obtained from IEffectsFactory.createEffect) of
|
||||
* the effect to remove.
|
||||
* @return retval operation completion status.
|
||||
*/
|
||||
removeEffect(IEffect effect) generates (Result retval);
|
||||
removeEffect(uint64_t effectId) generates (Result retval);
|
||||
|
||||
/*
|
||||
* Put the audio hardware input/output into standby mode.
|
||||
@@ -158,10 +160,9 @@ interface IStream {
|
||||
/*
|
||||
* Return the set of device(s) which this stream is connected to.
|
||||
*
|
||||
* @return retval operation completion status.
|
||||
* @return device set of device(s) which this stream is connected to.
|
||||
*/
|
||||
getDevice() generates (Result retval, AudioDevice device);
|
||||
getDevice() generates (AudioDevice device);
|
||||
|
||||
/*
|
||||
* Connects the stream to the device.
|
||||
|
||||
@@ -61,10 +61,9 @@ interface IStreamIn extends IStream {
|
||||
* typically occurs when the user space process is blocked longer than the
|
||||
* capacity of audio driver buffers.
|
||||
*
|
||||
* @return retval operation completion status.
|
||||
* @return framesLost the number of input audio frames lost.
|
||||
*/
|
||||
getInputFramesLost() generates (Result retval, uint32_t framesLost);
|
||||
getInputFramesLost() generates (uint32_t framesLost);
|
||||
|
||||
/**
|
||||
* Return a recent count of the number of audio frames received and the
|
||||
|
||||
@@ -142,12 +142,12 @@ interface IStreamOut extends IStream {
|
||||
* 'setCallback' has not been called, then 'drain' must block until
|
||||
* completion.
|
||||
*
|
||||
* If 'type' is 'AUDIO_DRAIN_ALL', the drain completes when all previously
|
||||
* written data has been played.
|
||||
* If 'type' is 'ALL', the drain completes when all previously written data
|
||||
* has been played.
|
||||
*
|
||||
* If 'type' is 'AUDIO_DRAIN_EARLY_NOTIFY', the drain completes shortly
|
||||
* before all data for the current track has played to allow time for the
|
||||
* framework to perform a gapless track switch.
|
||||
* If 'type' is 'EARLY_NOTIFY', the drain completes shortly before all data
|
||||
* for the current track has played to allow time for the framework to
|
||||
* perform a gapless track switch.
|
||||
*
|
||||
* Drain must return immediately on 'stop' and 'flush' calls.
|
||||
*
|
||||
|
||||
@@ -16,21 +16,54 @@
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := android.hardware.audio@2.0-impl
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_SRC_FILES := \
|
||||
Conversions.cpp \
|
||||
Device.cpp \
|
||||
DevicesFactory.cpp \
|
||||
ParametersUtil.cpp \
|
||||
PrimaryDevice.cpp \
|
||||
Stream.cpp \
|
||||
StreamIn.cpp \
|
||||
StreamOut.cpp \
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libhidl \
|
||||
libhwbinder \
|
||||
libutils \
|
||||
libhardware \
|
||||
liblog \
|
||||
android.hardware.audio@2.0 \
|
||||
android.hardware.audio.common@2.0 \
|
||||
android.hardware.audio.common@2.0-util \
|
||||
|
||||
LOCAL_WHOLE_STATIC_LIBRARIES := libmedia_helper
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
#
|
||||
# Service
|
||||
#
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := android.hardware.audio@2.0-service
|
||||
LOCAL_INIT_RC := android.hardware.audio@2.0-service.rc
|
||||
LOCAL_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_SRC_FILES := \
|
||||
service.cpp
|
||||
service.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libhidl \
|
||||
liblog \
|
||||
libhwbinder \
|
||||
libutils \
|
||||
libhardware \
|
||||
android.hardware.soundtrigger@2.0 \
|
||||
android.hardware.audio.common@2.0
|
||||
libhidl \
|
||||
liblog \
|
||||
libhwbinder \
|
||||
libutils \
|
||||
libhardware \
|
||||
android.hardware.audio@2.0 \
|
||||
android.hardware.audio.common@2.0 \
|
||||
android.hardware.audio.effect@2.0 \
|
||||
android.hardware.soundtrigger@2.0 \
|
||||
|
||||
ifeq ($(strip $(AUDIOSERVER_MULTILIB)),)
|
||||
LOCAL_MULTILIB := 32
|
||||
|
||||
63
audio/2.0/default/Conversions.cpp
Normal file
63
audio/2.0/default/Conversions.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
|
||||
#include "Conversions.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
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));
|
||||
uint32_t halDevice = static_cast<uint32_t>(address.device);
|
||||
if ((halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0
|
||||
|| (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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
snprintf(halAddress, sizeof(halAddress),
|
||||
"%s", address.rSubmixAddress.c_str());
|
||||
}
|
||||
return halAddress;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
41
audio/2.0/default/Conversions.h
Normal file
41
audio/2.0/default/Conversions.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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_Conversions_H_
|
||||
#define android_hardware_audio_V2_0_Conversions_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <android/hardware/audio/2.0/types.h>
|
||||
#include <system/audio.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::V2_0::DeviceAddress;
|
||||
|
||||
std::string deviceAddressToHal(const DeviceAddress& address);
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_audio_V2_0_Conversions_H_
|
||||
534
audio/2.0/default/Device.cpp
Normal file
534
audio/2.0/default/Device.cpp
Normal file
@@ -0,0 +1,534 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "DeviceHAL"
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "Conversions.h"
|
||||
#include "Device.h"
|
||||
#include "StreamIn.h"
|
||||
#include "StreamOut.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
Device::Device(audio_hw_device_t* device)
|
||||
: mDevice(device) {
|
||||
}
|
||||
|
||||
Device::~Device() {
|
||||
int status = audio_hw_device_close(mDevice);
|
||||
ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status));
|
||||
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<audio_channel_mask_t>(config.channelMask);
|
||||
halConfig->format = static_cast<audio_format_t>(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<audio_gain_mode_t>(config.mode);
|
||||
halConfig->channel_mask = static_cast<audio_channel_mask_t>(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<audio_gain_mode_t>(gain.mode);
|
||||
halGain->channel_mask = static_cast<audio_channel_mask_t>(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<audio_channel_mask_t>(offload.channelMask);
|
||||
halOffload->stream_type = static_cast<audio_stream_type_t>(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<audio_port_role_t>(config.role);
|
||||
halConfig->type = static_cast<audio_port_type_t>(config.type);
|
||||
halConfig->config_mask = static_cast<unsigned int>(config.configMask);
|
||||
halConfig->sample_rate = config.sampleRateHz;
|
||||
halConfig->channel_mask = static_cast<audio_channel_mask_t>(config.channelMask);
|
||||
halConfig->format = static_cast<audio_format_t>(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<audio_devices_t>(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<audio_source_t>(config.ext.mix.useCase.source);
|
||||
} else if (config.role == AudioPortRole::SINK) {
|
||||
halConfig->ext.mix.usecase.stream =
|
||||
static_cast<audio_stream_type_t>(config.ext.mix.useCase.stream);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AudioPortType::SESSION: {
|
||||
halConfig->ext.session.session =
|
||||
static_cast<audio_session_t>(config.ext.session.session);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
std::unique_ptr<audio_port_config[]> Device::audioPortConfigsToHal(
|
||||
const hidl_vec<AudioPortConfig>& configs) {
|
||||
std::unique_ptr<audio_port_config[]> 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<audio_port_role_t>(port.role);
|
||||
halPort->type = static_cast<audio_port_type_t>(port.type);
|
||||
memcpy(halPort->name,
|
||||
port.name.c_str(),
|
||||
std::min(port.name.size(), static_cast<size_t>(AUDIO_PORT_MAX_NAME_LEN)));
|
||||
halPort->num_sample_rates =
|
||||
std::min(port.sampleRates.size(), static_cast<size_t>(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<size_t>(AUDIO_PORT_MAX_CHANNEL_MASKS));
|
||||
for (size_t i = 0; i < halPort->num_channel_masks; ++i) {
|
||||
halPort->channel_masks[i] = static_cast<audio_channel_mask_t>(port.channelMasks[i]);
|
||||
}
|
||||
halPort->num_formats =
|
||||
std::min(port.formats.size(), static_cast<size_t>(AUDIO_PORT_MAX_FORMATS));
|
||||
for (size_t i = 0; i < halPort->num_formats; ++i) {
|
||||
halPort->formats[i] = static_cast<audio_format_t>(port.formats[i]);
|
||||
}
|
||||
halPort->num_gains = std::min(port.gains.size(), static_cast<size_t>(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<audio_devices_t>(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<audio_mix_latency_class_t>(port.ext.mix.latencyClass);
|
||||
break;
|
||||
}
|
||||
case AudioPortType::SESSION: {
|
||||
halPort->ext.session.session = static_cast<audio_session_t>(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));
|
||||
}
|
||||
switch (status) {
|
||||
case 0: return Result::OK;
|
||||
case -EINVAL: return Result::INVALID_ARGUMENTS;
|
||||
case -ENODATA: return Result::INVALID_STATE;
|
||||
case -ENODEV: return Result::NOT_INITIALIZED;
|
||||
case -ENOSYS: return Result::NOT_SUPPORTED;
|
||||
default: return Result::INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
char* Device::halGetParameters(const char* keys) {
|
||||
return mDevice->get_parameters(mDevice, keys);
|
||||
}
|
||||
|
||||
int Device::halSetParameters(const char* keysAndValues) {
|
||||
return mDevice->set_parameters(mDevice, keysAndValues);
|
||||
}
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IDevice follow.
|
||||
Return<Result> Device::initCheck() {
|
||||
return analyzeStatus("init_check", mDevice->init_check(mDevice));
|
||||
}
|
||||
|
||||
Return<Result> Device::setMasterVolume(float volume) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
if (mDevice->set_master_volume != NULL) {
|
||||
retval = analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
float volume = 0;
|
||||
if (mDevice->get_master_volume != NULL) {
|
||||
retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume));
|
||||
}
|
||||
_hidl_cb(retval, volume);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Device::setMicMute(bool mute) {
|
||||
return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
|
||||
}
|
||||
|
||||
Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
|
||||
bool mute = false;
|
||||
Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
|
||||
_hidl_cb(retval, mute);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Device::setMasterMute(bool mute) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
if (mDevice->set_master_mute != NULL) {
|
||||
retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
bool mute = false;
|
||||
if (mDevice->get_master_mute != NULL) {
|
||||
retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute));
|
||||
}
|
||||
_hidl_cb(retval, mute);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Device::getInputBufferSize(
|
||||
const AudioConfig& config, getInputBufferSize_cb _hidl_cb) {
|
||||
audio_config_t halConfig;
|
||||
audioConfigToHal(config, &halConfig);
|
||||
size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
|
||||
Result retval(Result::INVALID_ARGUMENTS);
|
||||
uint64_t bufferSize = 0;
|
||||
if (halBufferSize != 0) {
|
||||
retval = Result::OK;
|
||||
bufferSize = halBufferSize;
|
||||
}
|
||||
_hidl_cb(retval, bufferSize);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Device::openOutputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioOutputFlag flags,
|
||||
openOutputStream_cb _hidl_cb) {
|
||||
audio_config_t halConfig;
|
||||
audioConfigToHal(config, &halConfig);
|
||||
audio_stream_out_t *halStream;
|
||||
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());
|
||||
sp<IStreamOut> streamOut;
|
||||
if (status == OK) {
|
||||
streamOut = new StreamOut(mDevice, halStream);
|
||||
}
|
||||
_hidl_cb(analyzeStatus("open_output_stream", status), streamOut);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Device::openInputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioInputFlag flags,
|
||||
AudioSource source,
|
||||
openInputStream_cb _hidl_cb) {
|
||||
audio_config_t halConfig;
|
||||
audioConfigToHal(config, &halConfig);
|
||||
audio_stream_in_t *halStream;
|
||||
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));
|
||||
sp<IStreamIn> streamIn;
|
||||
if (status == OK) {
|
||||
streamIn = new StreamIn(mDevice, halStream);
|
||||
}
|
||||
_hidl_cb(analyzeStatus("open_input_stream", status), streamIn);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> Device::createAudioPatch(
|
||||
const hidl_vec<AudioPortConfig>& sources,
|
||||
const hidl_vec<AudioPortConfig>& sinks,
|
||||
createAudioPatch_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
AudioPatchHandle patch = 0;
|
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
|
||||
std::unique_ptr<audio_port_config[]> halSources(audioPortConfigsToHal(sources));
|
||||
std::unique_ptr<audio_port_config[]> halSinks(audioPortConfigsToHal(sinks));
|
||||
audio_patch_handle_t halPatch;
|
||||
retval = analyzeStatus(
|
||||
"create_audio_patch",
|
||||
mDevice->create_audio_patch(
|
||||
mDevice,
|
||||
sources.size(), &halSources[0],
|
||||
sinks.size(), &halSinks[0],
|
||||
&halPatch));
|
||||
if (retval == Result::OK) {
|
||||
patch = static_cast<AudioPatchHandle>(halPatch);
|
||||
}
|
||||
}
|
||||
_hidl_cb(retval, patch);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Device::releaseAudioPatch(int32_t patch) {
|
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
|
||||
return analyzeStatus(
|
||||
"release_audio_patch",
|
||||
mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch)));
|
||||
}
|
||||
return Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
|
||||
audio_port halPort;
|
||||
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);
|
||||
}
|
||||
_hidl_cb(retval, resultPort);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
|
||||
if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
|
||||
struct audio_port_config halPortConfig;
|
||||
audioPortConfigToHal(config, &halPortConfig);
|
||||
return analyzeStatus(
|
||||
"set_audio_port_config", mDevice->set_audio_port_config(mDevice, &halPortConfig));
|
||||
}
|
||||
return Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<AudioHwSync> Device::getHwAvSync() {
|
||||
int halHwAvSync;
|
||||
Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
|
||||
return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
|
||||
}
|
||||
|
||||
Return<Result> Device::setScreenState(bool turnedOn) {
|
||||
return setParam(AudioParameter::keyScreenState, turnedOn);
|
||||
}
|
||||
|
||||
Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
|
||||
getParametersImpl(keys, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) {
|
||||
return setParametersImpl(parameters);
|
||||
}
|
||||
|
||||
Return<void> Device::debugDump(const native_handle_t* fd) {
|
||||
if (fd->numFds == 1) {
|
||||
analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
147
audio/2.0/default/Device.h
Normal file
147
audio/2.0/default/Device.h
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* 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 HIDL_GENERATED_android_hardware_audio_V2_0_Device_H_
|
||||
#define HIDL_GENERATED_android_hardware_audio_V2_0_Device_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <media/AudioParameter.h>
|
||||
#include <hardware/audio.h>
|
||||
|
||||
#include <android/hardware/audio/2.0/IDevice.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
|
||||
#include "ParametersUtil.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
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;
|
||||
using ::android::hardware::audio::V2_0::IStreamOut;
|
||||
using ::android::hardware::audio::V2_0::ParameterValue;
|
||||
using ::android::hardware::audio::V2_0::Result;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
struct Device : public IDevice, public ParametersUtil {
|
||||
explicit Device(audio_hw_device_t* device);
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IDevice follow.
|
||||
Return<Result> initCheck() override;
|
||||
Return<Result> setMasterVolume(float volume) override;
|
||||
Return<void> getMasterVolume(getMasterVolume_cb _hidl_cb) override;
|
||||
Return<Result> setMicMute(bool mute) override;
|
||||
Return<void> getMicMute(getMicMute_cb _hidl_cb) override;
|
||||
Return<Result> setMasterMute(bool mute) override;
|
||||
Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override;
|
||||
Return<void> getInputBufferSize(
|
||||
const AudioConfig& config, getInputBufferSize_cb _hidl_cb) override;
|
||||
Return<void> openOutputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioOutputFlag flags,
|
||||
openOutputStream_cb _hidl_cb) override;
|
||||
Return<void> openInputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioInputFlag flags,
|
||||
AudioSource source,
|
||||
openInputStream_cb _hidl_cb) override;
|
||||
Return<void> createAudioPatch(
|
||||
const hidl_vec<AudioPortConfig>& sources,
|
||||
const hidl_vec<AudioPortConfig>& sinks,
|
||||
createAudioPatch_cb _hidl_cb) override;
|
||||
Return<Result> releaseAudioPatch(int32_t patch) override;
|
||||
Return<void> getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override;
|
||||
Return<Result> setAudioPortConfig(const AudioPortConfig& config) override;
|
||||
Return<AudioHwSync> getHwAvSync() override;
|
||||
Return<Result> setScreenState(bool turnedOn) override;
|
||||
Return<void> getParameters(
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
|
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
|
||||
Return<void> debugDump(const native_handle_t* fd) override;
|
||||
|
||||
// Utility methods for extending interfaces.
|
||||
Result analyzeStatus(const char* funcName, int status);
|
||||
audio_hw_device_t* device() const { return mDevice; }
|
||||
|
||||
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<audio_port_config[]> audioPortConfigsToHal(
|
||||
const hidl_vec<AudioPortConfig>& 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.
|
||||
char* halGetParameters(const char* keys) override;
|
||||
int halSetParameters(const char* keysAndValues) override;
|
||||
|
||||
uint32_t version() const { return mDevice->common.version; }
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HIDL_GENERATED_android_hardware_audio_V2_0_Device_H_
|
||||
103
audio/2.0/default/DevicesFactory.cpp
Normal file
103
audio/2.0/default/DevicesFactory.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "DevicesFactoryHAL"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "Device.h"
|
||||
#include "DevicesFactory.h"
|
||||
#include "PrimaryDevice.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
// static
|
||||
const char* DevicesFactory::deviceToString(IDevicesFactory::Device device) {
|
||||
switch (device) {
|
||||
case IDevicesFactory::Device::PRIMARY: return AUDIO_HARDWARE_MODULE_ID_PRIMARY;
|
||||
case IDevicesFactory::Device::A2DP: return AUDIO_HARDWARE_MODULE_ID_A2DP;
|
||||
case IDevicesFactory::Device::USB: return AUDIO_HARDWARE_MODULE_ID_USB;
|
||||
case IDevicesFactory::Device::R_SUBMIX: return AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX;
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
int DevicesFactory::loadAudioInterface(const char *if_name, audio_hw_device_t **dev)
|
||||
{
|
||||
const hw_module_t *mod;
|
||||
int rc;
|
||||
|
||||
rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod);
|
||||
if (rc) {
|
||||
ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__,
|
||||
AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
rc = audio_hw_device_open(mod, dev);
|
||||
if (rc) {
|
||||
ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__,
|
||||
AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc));
|
||||
goto out;
|
||||
}
|
||||
if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) {
|
||||
ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version);
|
||||
rc = -EINVAL;
|
||||
audio_hw_device_close(*dev);
|
||||
goto out;
|
||||
}
|
||||
return OK;
|
||||
|
||||
out:
|
||||
*dev = NULL;
|
||||
return rc;
|
||||
}
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IDevicesFactory follow.
|
||||
Return<void> DevicesFactory::openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) {
|
||||
audio_hw_device_t *halDevice;
|
||||
int halStatus = loadAudioInterface(deviceToString(device), &halDevice);
|
||||
Result retval(Result::OK);
|
||||
sp<IDevice> result;
|
||||
if (halStatus == OK) {
|
||||
if (device == IDevicesFactory::Device::PRIMARY) {
|
||||
result = new PrimaryDevice(halDevice);
|
||||
} else {
|
||||
result = new ::android::hardware::audio::V2_0::implementation::Device(halDevice);
|
||||
}
|
||||
} else if (halStatus == -EINVAL) {
|
||||
retval = Result::NOT_INITIALIZED;
|
||||
} else {
|
||||
retval = Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
_hidl_cb(retval, result);
|
||||
return Void();
|
||||
}
|
||||
|
||||
IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* /* name */) {
|
||||
return new DevicesFactory();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
59
audio/2.0/default/DevicesFactory.h
Normal file
59
audio/2.0/default/DevicesFactory.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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 HIDL_GENERATED_android_hardware_audio_V2_0_DevicesFactory_H_
|
||||
#define HIDL_GENERATED_android_hardware_audio_V2_0_DevicesFactory_H_
|
||||
|
||||
#include <hardware/audio.h>
|
||||
|
||||
#include <android/hardware/audio/2.0/IDevicesFactory.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::V2_0::IDevice;
|
||||
using ::android::hardware::audio::V2_0::IDevicesFactory;
|
||||
using ::android::hardware::audio::V2_0::Result;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
struct DevicesFactory : public IDevicesFactory {
|
||||
// Methods from ::android::hardware::audio::V2_0::IDevicesFactory follow.
|
||||
Return<void> openDevice(IDevicesFactory::Device device, openDevice_cb _hidl_cb) override;
|
||||
|
||||
private:
|
||||
static const char* deviceToString(IDevicesFactory::Device device);
|
||||
static int loadAudioInterface(const char *if_name, audio_hw_device_t **dev);
|
||||
|
||||
};
|
||||
|
||||
extern "C" IDevicesFactory* HIDL_FETCH_IDevicesFactory(const char* name);
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HIDL_GENERATED_android_hardware_audio_V2_0_DevicesFactory_H_
|
||||
134
audio/2.0/default/ParametersUtil.cpp
Normal file
134
audio/2.0/default/ParametersUtil.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* 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 "ParametersUtil.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
Result ParametersUtil::getParam(const char* name, bool* value) {
|
||||
String8 halValue;
|
||||
Result retval = getParam(name, &halValue);
|
||||
*value = false;
|
||||
if (retval == Result::OK) {
|
||||
*value = !(halValue == AudioParameter::valueOff);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Result ParametersUtil::getParam(const char* name, int* value) {
|
||||
const String8 halName(name);
|
||||
AudioParameter keys;
|
||||
keys.addKey(halName);
|
||||
std::unique_ptr<AudioParameter> params = getParams(keys);
|
||||
status_t halStatus = params->getInt(halName, *value);
|
||||
return halStatus == OK ? Result::OK : Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
Result ParametersUtil::getParam(const char* name, String8* value) {
|
||||
const String8 halName(name);
|
||||
AudioParameter keys;
|
||||
keys.addKey(halName);
|
||||
std::unique_ptr<AudioParameter> params = getParams(keys);
|
||||
status_t halStatus = params->get(halName, *value);
|
||||
return halStatus == OK ? Result::OK : Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
void ParametersUtil::getParametersImpl(
|
||||
const hidl_vec<hidl_string>& keys,
|
||||
std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb) {
|
||||
AudioParameter halKeys;
|
||||
for (size_t i = 0; i < keys.size(); ++i) {
|
||||
halKeys.addKey(String8(keys[i].c_str()));
|
||||
}
|
||||
std::unique_ptr<AudioParameter> halValues = getParams(halKeys);
|
||||
Result retval(Result::INVALID_ARGUMENTS);
|
||||
hidl_vec<ParameterValue> result;
|
||||
if (halValues->size() > 0) {
|
||||
result.resize(halValues->size());
|
||||
String8 halKey, halValue;
|
||||
for (size_t i = 0; i < halValues->size(); ++i) {
|
||||
status_t status = halValues->getAt(i, halKey, halValue);
|
||||
if (status != OK) {
|
||||
result.resize(0);
|
||||
break;
|
||||
}
|
||||
result[i].key = halKey.string();
|
||||
result[i].value = halValue.string();
|
||||
}
|
||||
if (result.size() != 0) {
|
||||
retval = Result::OK;
|
||||
}
|
||||
}
|
||||
cb(retval, result);
|
||||
}
|
||||
|
||||
std::unique_ptr<AudioParameter> ParametersUtil::getParams(const AudioParameter& keys) {
|
||||
String8 paramsAndValues;
|
||||
char *halValues = halGetParameters(keys.keysToString().string());
|
||||
if (halValues != NULL) {
|
||||
paramsAndValues.setTo(halValues);
|
||||
free(halValues);
|
||||
} else {
|
||||
paramsAndValues.clear();
|
||||
}
|
||||
return std::unique_ptr<AudioParameter>(new AudioParameter(paramsAndValues));
|
||||
}
|
||||
|
||||
Result ParametersUtil::setParam(const char* name, bool value) {
|
||||
AudioParameter param;
|
||||
param.add(String8(name), String8(value ? AudioParameter::valueOn : AudioParameter::valueOff));
|
||||
return setParams(param);
|
||||
}
|
||||
|
||||
Result ParametersUtil::setParam(const char* name, int value) {
|
||||
AudioParameter param;
|
||||
param.addInt(String8(name), value);
|
||||
return setParams(param);
|
||||
}
|
||||
|
||||
Result ParametersUtil::setParam(const char* name, const char* value) {
|
||||
AudioParameter param;
|
||||
param.add(String8(name), String8(value));
|
||||
return setParams(param);
|
||||
}
|
||||
|
||||
Result ParametersUtil::setParametersImpl(const hidl_vec<ParameterValue>& parameters) {
|
||||
AudioParameter params;
|
||||
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||
params.add(String8(parameters[i].key.c_str()), String8(parameters[i].value.c_str()));
|
||||
}
|
||||
return setParams(params);
|
||||
}
|
||||
|
||||
Result ParametersUtil::setParams(const AudioParameter& param) {
|
||||
int halStatus = halSetParameters(param.toString().string());
|
||||
if (halStatus == OK)
|
||||
return Result::OK;
|
||||
else if (halStatus == -ENOSYS)
|
||||
return Result::INVALID_STATE;
|
||||
else
|
||||
return Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
66
audio/2.0/default/ParametersUtil.h
Normal file
66
audio/2.0/default/ParametersUtil.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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_ParametersUtil_H_
|
||||
#define android_hardware_audio_V2_0_ParametersUtil_H_
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
#include <android/hardware/audio/2.0/types.h>
|
||||
#include <hidl/HidlSupport.h>
|
||||
#include <media/AudioParameter.h>
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::V2_0::ParameterValue;
|
||||
using ::android::hardware::audio::V2_0::Result;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::hardware::hidl_vec;
|
||||
|
||||
class ParametersUtil {
|
||||
public:
|
||||
Result getParam(const char* name, bool* value);
|
||||
Result getParam(const char* name, int* value);
|
||||
Result getParam(const char* name, String8* value);
|
||||
void getParametersImpl(
|
||||
const hidl_vec<hidl_string>& keys,
|
||||
std::function<void(Result retval, const hidl_vec<ParameterValue>& parameters)> cb);
|
||||
std::unique_ptr<AudioParameter> getParams(const AudioParameter& keys);
|
||||
Result setParam(const char* name, bool value);
|
||||
Result setParam(const char* name, int value);
|
||||
Result setParam(const char* name, const char* value);
|
||||
Result setParametersImpl(const hidl_vec<ParameterValue>& parameters);
|
||||
Result setParams(const AudioParameter& param);
|
||||
|
||||
protected:
|
||||
virtual ~ParametersUtil() {}
|
||||
|
||||
virtual char* halGetParameters(const char* keys) = 0;
|
||||
virtual int halSetParameters(const char* keysAndValues) = 0;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_audio_V2_0_ParametersUtil_H_
|
||||
189
audio/2.0/default/PrimaryDevice.cpp
Normal file
189
audio/2.0/default/PrimaryDevice.cpp
Normal file
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "PrimaryDeviceHAL"
|
||||
|
||||
#include "PrimaryDevice.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
PrimaryDevice::PrimaryDevice(audio_hw_device_t* device)
|
||||
: mDevice(new Device(device)) {
|
||||
}
|
||||
|
||||
PrimaryDevice::~PrimaryDevice() {}
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IDevice follow.
|
||||
Return<Result> PrimaryDevice::initCheck() {
|
||||
return mDevice->initCheck();
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setMasterVolume(float volume) {
|
||||
return mDevice->setMasterVolume(volume);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getMasterVolume(getMasterVolume_cb _hidl_cb) {
|
||||
return mDevice->getMasterVolume(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setMicMute(bool mute) {
|
||||
return mDevice->setMicMute(mute);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getMicMute(getMicMute_cb _hidl_cb) {
|
||||
return mDevice->getMicMute(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setMasterMute(bool mute) {
|
||||
return mDevice->setMasterMute(mute);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getMasterMute(getMasterMute_cb _hidl_cb) {
|
||||
return mDevice->getMasterMute(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getInputBufferSize(
|
||||
const AudioConfig& config, getInputBufferSize_cb _hidl_cb) {
|
||||
return mDevice->getInputBufferSize(config, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::openOutputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioOutputFlag flags,
|
||||
openOutputStream_cb _hidl_cb) {
|
||||
return mDevice->openOutputStream(ioHandle, device, config, flags, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::openInputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioInputFlag flags,
|
||||
AudioSource source,
|
||||
openInputStream_cb _hidl_cb) {
|
||||
return mDevice->openInputStream(ioHandle, device, config, flags, source, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::createAudioPatch(
|
||||
const hidl_vec<AudioPortConfig>& sources,
|
||||
const hidl_vec<AudioPortConfig>& sinks,
|
||||
createAudioPatch_cb _hidl_cb) {
|
||||
return mDevice->createAudioPatch(sources, sinks, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::releaseAudioPatch(int32_t patch) {
|
||||
return mDevice->releaseAudioPatch(patch);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
|
||||
return mDevice->getAudioPort(port, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setAudioPortConfig(const AudioPortConfig& config) {
|
||||
return mDevice->setAudioPortConfig(config);
|
||||
}
|
||||
|
||||
Return<AudioHwSync> PrimaryDevice::getHwAvSync() {
|
||||
return mDevice->getHwAvSync();
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setScreenState(bool turnedOn) {
|
||||
return mDevice->setScreenState(turnedOn);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getParameters(
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
|
||||
return mDevice->getParameters(keys, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setParameters(const hidl_vec<ParameterValue>& parameters) {
|
||||
return mDevice->setParameters(parameters);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::debugDump(const native_handle_t* fd) {
|
||||
return mDevice->debugDump(fd);
|
||||
}
|
||||
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IPrimaryDevice follow.
|
||||
Return<Result> PrimaryDevice::setVoiceVolume(float volume) {
|
||||
return mDevice->analyzeStatus(
|
||||
"set_voice_volume",
|
||||
mDevice->device()->set_voice_volume(mDevice->device(), volume));
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setMode(AudioMode mode) {
|
||||
return mDevice->analyzeStatus(
|
||||
"set_mode",
|
||||
mDevice->device()->set_mode(mDevice->device(), static_cast<audio_mode_t>(mode)));
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) {
|
||||
bool enabled;
|
||||
Result retval = mDevice->getParam(AudioParameter::keyBtNrec, &enabled);
|
||||
_hidl_cb(retval, enabled);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setBtScoNrecEnabled(bool enabled) {
|
||||
return mDevice->setParam(AudioParameter::keyBtNrec, enabled);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) {
|
||||
bool enabled;
|
||||
Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, &enabled);
|
||||
_hidl_cb(retval, enabled);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setBtScoWidebandEnabled(bool enabled) {
|
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_BT_SCO_WB, enabled);
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getTtyMode(getTtyMode_cb _hidl_cb) {
|
||||
int halMode;
|
||||
Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_TTY_MODE, &halMode);
|
||||
TtyMode mode = retval == Result::OK ? TtyMode(halMode) : TtyMode::OFF;
|
||||
_hidl_cb(retval, mode);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setTtyMode(IPrimaryDevice::TtyMode mode) {
|
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_TTY_MODE, static_cast<int>(mode));
|
||||
}
|
||||
|
||||
Return<void> PrimaryDevice::getHacEnabled(getHacEnabled_cb _hidl_cb) {
|
||||
bool enabled;
|
||||
Result retval = mDevice->getParam(AUDIO_PARAMETER_KEY_HAC, &enabled);
|
||||
_hidl_cb(retval, enabled);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> PrimaryDevice::setHacEnabled(bool enabled) {
|
||||
return mDevice->setParam(AUDIO_PARAMETER_KEY_HAC, enabled);
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
117
audio/2.0/default/PrimaryDevice.h
Normal file
117
audio/2.0/default/PrimaryDevice.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* 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 HIDL_GENERATED_android_hardware_audio_V2_0_PrimaryDevice_H_
|
||||
#define HIDL_GENERATED_android_hardware_audio_V2_0_PrimaryDevice_H_
|
||||
|
||||
#include <android/hardware/audio/2.0/IPrimaryDevice.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
|
||||
#include "Device.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
using ::android::hardware::audio::common::V2_0::AudioConfig;
|
||||
using ::android::hardware::audio::common::V2_0::AudioInputFlag;
|
||||
using ::android::hardware::audio::common::V2_0::AudioMode;
|
||||
using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
|
||||
using ::android::hardware::audio::common::V2_0::AudioPort;
|
||||
using ::android::hardware::audio::common::V2_0::AudioPortConfig;
|
||||
using ::android::hardware::audio::common::V2_0::AudioSource;
|
||||
using ::android::hardware::audio::V2_0::DeviceAddress;
|
||||
using ::android::hardware::audio::V2_0::IDevice;
|
||||
using ::android::hardware::audio::V2_0::IPrimaryDevice;
|
||||
using ::android::hardware::audio::V2_0::IStreamIn;
|
||||
using ::android::hardware::audio::V2_0::IStreamOut;
|
||||
using ::android::hardware::audio::V2_0::ParameterValue;
|
||||
using ::android::hardware::audio::V2_0::Result;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
struct PrimaryDevice : public IPrimaryDevice {
|
||||
explicit PrimaryDevice(audio_hw_device_t* device);
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IDevice follow.
|
||||
Return<Result> initCheck() override;
|
||||
Return<Result> setMasterVolume(float volume) override;
|
||||
Return<void> getMasterVolume(getMasterVolume_cb _hidl_cb) override;
|
||||
Return<Result> setMicMute(bool mute) override;
|
||||
Return<void> getMicMute(getMicMute_cb _hidl_cb) override;
|
||||
Return<Result> setMasterMute(bool mute) override;
|
||||
Return<void> getMasterMute(getMasterMute_cb _hidl_cb) override;
|
||||
Return<void> getInputBufferSize(
|
||||
const AudioConfig& config, getInputBufferSize_cb _hidl_cb) override;
|
||||
Return<void> openOutputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioOutputFlag flags,
|
||||
openOutputStream_cb _hidl_cb) override;
|
||||
Return<void> openInputStream(
|
||||
int32_t ioHandle,
|
||||
const DeviceAddress& device,
|
||||
const AudioConfig& config,
|
||||
AudioInputFlag flags,
|
||||
AudioSource source,
|
||||
openInputStream_cb _hidl_cb) override;
|
||||
Return<void> createAudioPatch(
|
||||
const hidl_vec<AudioPortConfig>& sources,
|
||||
const hidl_vec<AudioPortConfig>& sinks,
|
||||
createAudioPatch_cb _hidl_cb) override;
|
||||
Return<Result> releaseAudioPatch(int32_t patch) override;
|
||||
Return<void> getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) override;
|
||||
Return<Result> setAudioPortConfig(const AudioPortConfig& config) override;
|
||||
Return<AudioHwSync> getHwAvSync() override;
|
||||
Return<Result> setScreenState(bool turnedOn) override;
|
||||
Return<void> getParameters(
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
|
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
|
||||
Return<void> debugDump(const native_handle_t* fd) override;
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IPrimaryDevice follow.
|
||||
Return<Result> setVoiceVolume(float volume) override;
|
||||
Return<Result> setMode(AudioMode mode) override;
|
||||
Return<void> getBtScoNrecEnabled(getBtScoNrecEnabled_cb _hidl_cb) override;
|
||||
Return<Result> setBtScoNrecEnabled(bool enabled) override;
|
||||
Return<void> getBtScoWidebandEnabled(getBtScoWidebandEnabled_cb _hidl_cb) override;
|
||||
Return<Result> setBtScoWidebandEnabled(bool enabled) override;
|
||||
Return<void> getTtyMode(getTtyMode_cb _hidl_cb) override;
|
||||
Return<Result> setTtyMode(IPrimaryDevice::TtyMode mode) override;
|
||||
Return<void> getHacEnabled(getHacEnabled_cb _hidl_cb) override;
|
||||
Return<Result> setHacEnabled(bool enabled) override;
|
||||
|
||||
private:
|
||||
sp<Device> mDevice;
|
||||
|
||||
virtual ~PrimaryDevice();
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HIDL_GENERATED_android_hardware_audio_V2_0_PrimaryDevice_H_
|
||||
236
audio/2.0/default/Stream.cpp
Normal file
236
audio/2.0/default/Stream.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* 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 <inttypes.h>
|
||||
|
||||
#define LOG_TAG "StreamHAL"
|
||||
|
||||
#include <hardware/audio.h>
|
||||
#include <hardware/audio_effect.h>
|
||||
#include <media/TypeConverter.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/SortedVector.h>
|
||||
#include <utils/Vector.h>
|
||||
|
||||
#include "Conversions.h"
|
||||
#include "EffectMap.h"
|
||||
#include "Stream.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
Stream::Stream(audio_stream_t* stream)
|
||||
: mStream(stream) {
|
||||
}
|
||||
|
||||
Stream::~Stream() {
|
||||
mStream = nullptr;
|
||||
}
|
||||
|
||||
Result Stream::analyzeStatus(const char* funcName, int status) {
|
||||
if (status != 0) {
|
||||
ALOGW("Stream %p %s: %s", mStream, funcName, strerror(-status));
|
||||
}
|
||||
switch (status) {
|
||||
case 0: return Result::OK;
|
||||
case -EINVAL: return Result::INVALID_ARGUMENTS;
|
||||
case -ENODATA: return Result::INVALID_STATE;
|
||||
case -ENODEV: return Result::NOT_INITIALIZED;
|
||||
case -ENOSYS: return Result::NOT_SUPPORTED;
|
||||
default: return Result::INVALID_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
char* Stream::halGetParameters(const char* keys) {
|
||||
return mStream->get_parameters(mStream, keys);
|
||||
}
|
||||
|
||||
int Stream::halSetParameters(const char* keysAndValues) {
|
||||
return mStream->set_parameters(mStream, keysAndValues);
|
||||
}
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStream follow.
|
||||
Return<uint64_t> Stream::getFrameSize() {
|
||||
// Needs to be implemented by interface subclasses. But can't be declared as pure virtual,
|
||||
// since interface subclasses implementation do not inherit from this class.
|
||||
LOG_ALWAYS_FATAL("Stream::getFrameSize is pure abstract");
|
||||
return uint64_t {};
|
||||
}
|
||||
|
||||
Return<uint64_t> Stream::getFrameCount() {
|
||||
int halFrameCount;
|
||||
Result retval = getParam(AudioParameter::keyFrameCount, &halFrameCount);
|
||||
return retval == Result::OK ? halFrameCount : 0;
|
||||
}
|
||||
|
||||
Return<uint64_t> Stream::getBufferSize() {
|
||||
return mStream->get_buffer_size(mStream);
|
||||
}
|
||||
|
||||
Return<uint32_t> Stream::getSampleRate() {
|
||||
return mStream->get_sample_rate(mStream);
|
||||
}
|
||||
|
||||
Return<void> Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
|
||||
String8 halListValue;
|
||||
Result result = getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue);
|
||||
hidl_vec<uint32_t> sampleRates;
|
||||
SortedVector<uint32_t> halSampleRates;
|
||||
if (result == Result::OK) {
|
||||
halSampleRates = samplingRatesFromString(
|
||||
halListValue.string(), AudioParameter::valueListSeparator);
|
||||
sampleRates.setToExternal(halSampleRates.editArray(), halSampleRates.size());
|
||||
}
|
||||
_hidl_cb(sampleRates);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Stream::setSampleRate(uint32_t sampleRateHz) {
|
||||
return setParam(AudioParameter::keySamplingRate, static_cast<int>(sampleRateHz));
|
||||
}
|
||||
|
||||
Return<AudioChannelMask> Stream::getChannelMask() {
|
||||
return AudioChannelMask(mStream->get_channels(mStream));
|
||||
}
|
||||
|
||||
Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
|
||||
String8 halListValue;
|
||||
Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue);
|
||||
hidl_vec<AudioChannelMask> channelMasks;
|
||||
SortedVector<audio_channel_mask_t> halChannelMasks;
|
||||
if (result == Result::OK) {
|
||||
halChannelMasks = channelMasksFromString(
|
||||
halListValue.string(), AudioParameter::valueListSeparator);
|
||||
channelMasks.resize(halChannelMasks.size());
|
||||
for (size_t i = 0; i < halChannelMasks.size(); ++i) {
|
||||
channelMasks[i] = AudioChannelMask(halChannelMasks[i]);
|
||||
}
|
||||
}
|
||||
_hidl_cb(channelMasks);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Stream::setChannelMask(AudioChannelMask mask) {
|
||||
return setParam(AudioParameter::keyChannels, static_cast<int>(mask));
|
||||
}
|
||||
|
||||
Return<AudioFormat> Stream::getFormat() {
|
||||
return AudioFormat(mStream->get_format(mStream));
|
||||
}
|
||||
|
||||
Return<void> Stream::getSupportedFormats(getSupportedFormats_cb _hidl_cb) {
|
||||
String8 halListValue;
|
||||
Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue);
|
||||
hidl_vec<AudioFormat> formats;
|
||||
Vector<audio_format_t> halFormats;
|
||||
if (result == Result::OK) {
|
||||
halFormats = formatsFromString(halListValue.string(), AudioParameter::valueListSeparator);
|
||||
formats.resize(halFormats.size());
|
||||
for (size_t i = 0; i < halFormats.size(); ++i) {
|
||||
formats[i] = AudioFormat(halFormats[i]);
|
||||
}
|
||||
}
|
||||
_hidl_cb(formats);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Stream::setFormat(AudioFormat format) {
|
||||
return setParam(AudioParameter::keyFormat, static_cast<int>(format));
|
||||
}
|
||||
|
||||
Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) {
|
||||
uint32_t halSampleRate = mStream->get_sample_rate(mStream);
|
||||
audio_channel_mask_t halMask = mStream->get_channels(mStream);
|
||||
audio_format_t halFormat = mStream->get_format(mStream);
|
||||
_hidl_cb(halSampleRate, AudioChannelMask(halMask), AudioFormat(halFormat));
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Stream::addEffect(uint64_t effectId) {
|
||||
effect_handle_t halEffect = EffectMap::getInstance().get(effectId);
|
||||
if (halEffect != NULL) {
|
||||
return analyzeStatus("add_audio_effect", mStream->add_audio_effect(mStream, halEffect));
|
||||
} else {
|
||||
ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId);
|
||||
return Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
}
|
||||
|
||||
Return<Result> Stream::removeEffect(uint64_t effectId) {
|
||||
effect_handle_t halEffect = EffectMap::getInstance().get(effectId);
|
||||
if (halEffect != NULL) {
|
||||
return analyzeStatus(
|
||||
"remove_audio_effect", mStream->remove_audio_effect(mStream, halEffect));
|
||||
} else {
|
||||
ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId);
|
||||
return Result::INVALID_ARGUMENTS;
|
||||
}
|
||||
}
|
||||
|
||||
Return<Result> Stream::standby() {
|
||||
return analyzeStatus("standby", mStream->standby(mStream));
|
||||
}
|
||||
|
||||
Return<AudioDevice> Stream::getDevice() {
|
||||
return AudioDevice(mStream->get_device(mStream));
|
||||
}
|
||||
|
||||
Return<Result> Stream::setDevice(const DeviceAddress& address) {
|
||||
char* halDeviceAddress =
|
||||
audio_device_address_to_parameter(
|
||||
static_cast<audio_devices_t>(address.device),
|
||||
deviceAddressToHal(address).c_str());
|
||||
AudioParameter params((String8(halDeviceAddress)));
|
||||
free(halDeviceAddress);
|
||||
params.addInt(
|
||||
String8(AudioParameter::keyRouting), static_cast<audio_devices_t>(address.device));
|
||||
return setParams(params);
|
||||
}
|
||||
|
||||
Return<Result> Stream::setConnectedState(const DeviceAddress& address, bool connected) {
|
||||
return setParam(
|
||||
connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect,
|
||||
deviceAddressToHal(address).c_str());
|
||||
}
|
||||
|
||||
Return<Result> Stream::setHwAvSync(uint32_t hwAvSync) {
|
||||
return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync));
|
||||
}
|
||||
|
||||
Return<void> Stream::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
|
||||
getParametersImpl(keys, _hidl_cb);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters) {
|
||||
return setParametersImpl(parameters);
|
||||
}
|
||||
|
||||
Return<void> Stream::debugDump(const native_handle_t* fd) {
|
||||
if (fd->numFds == 1) {
|
||||
analyzeStatus("dump", mStream->dump(mStream, fd->data[0]));
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
94
audio/2.0/default/Stream.h
Normal file
94
audio/2.0/default/Stream.h
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 HIDL_GENERATED_android_hardware_audio_V2_0_Stream_H_
|
||||
#define HIDL_GENERATED_android_hardware_audio_V2_0_Stream_H_
|
||||
|
||||
#include <android/hardware/audio/2.0/IStream.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
|
||||
#include "ParametersUtil.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
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::V2_0::DeviceAddress;
|
||||
using ::android::hardware::audio::V2_0::IStream;
|
||||
using ::android::hardware::audio::V2_0::ParameterValue;
|
||||
using ::android::hardware::audio::V2_0::Result;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
struct Stream : public IStream, public ParametersUtil {
|
||||
explicit Stream(audio_stream_t* stream);
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStream follow.
|
||||
Return<uint64_t> getFrameSize() override;
|
||||
Return<uint64_t> getFrameCount() override;
|
||||
Return<uint64_t> getBufferSize() override;
|
||||
Return<uint32_t> getSampleRate() override;
|
||||
Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override;
|
||||
Return<Result> setSampleRate(uint32_t sampleRateHz) override;
|
||||
Return<AudioChannelMask> getChannelMask() override;
|
||||
Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override;
|
||||
Return<Result> setChannelMask(AudioChannelMask mask) override;
|
||||
Return<AudioFormat> getFormat() override;
|
||||
Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override;
|
||||
Return<Result> setFormat(AudioFormat format) override;
|
||||
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
|
||||
Return<Result> addEffect(uint64_t effectId) override;
|
||||
Return<Result> removeEffect(uint64_t effectId) override;
|
||||
Return<Result> standby() override;
|
||||
Return<AudioDevice> getDevice() override;
|
||||
Return<Result> setDevice(const DeviceAddress& address) override;
|
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
|
||||
Return<Result> setHwAvSync(uint32_t hwAvSync) override;
|
||||
Return<void> getParameters(
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
|
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
|
||||
Return<void> debugDump(const native_handle_t* fd) override;
|
||||
|
||||
// Utility methods for extending interfaces.
|
||||
Result analyzeStatus(const char* funcName, int status);
|
||||
|
||||
private:
|
||||
audio_stream_t *mStream;
|
||||
|
||||
virtual ~Stream();
|
||||
|
||||
// Methods from ParametersUtil.
|
||||
char* halGetParameters(const char* keys) override;
|
||||
int halSetParameters(const char* keysAndValues) override;
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HIDL_GENERATED_android_hardware_audio_V2_0_Stream_H_
|
||||
191
audio/2.0/default/StreamIn.cpp
Normal file
191
audio/2.0/default/StreamIn.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "StreamInHAL"
|
||||
|
||||
#include <hardware/audio.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "StreamIn.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
StreamIn::StreamIn(audio_hw_device_t* device, audio_stream_in_t* stream)
|
||||
: mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
|
||||
}
|
||||
|
||||
StreamIn::~StreamIn() {
|
||||
mDevice->close_input_stream(mDevice, mStream);
|
||||
mStream = nullptr;
|
||||
mDevice = nullptr;
|
||||
}
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStream follow.
|
||||
Return<uint64_t> StreamIn::getFrameSize() {
|
||||
return audio_stream_in_frame_size(mStream);
|
||||
}
|
||||
|
||||
Return<uint64_t> StreamIn::getFrameCount() {
|
||||
return mStreamCommon->getFrameCount();
|
||||
}
|
||||
|
||||
Return<uint64_t> StreamIn::getBufferSize() {
|
||||
return mStreamCommon->getBufferSize();
|
||||
}
|
||||
|
||||
Return<uint32_t> StreamIn::getSampleRate() {
|
||||
return mStreamCommon->getSampleRate();
|
||||
}
|
||||
|
||||
Return<void> StreamIn::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
|
||||
return mStreamCommon->getSupportedSampleRates(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setSampleRate(uint32_t sampleRateHz) {
|
||||
return mStreamCommon->setSampleRate(sampleRateHz);
|
||||
}
|
||||
|
||||
Return<AudioChannelMask> StreamIn::getChannelMask() {
|
||||
return mStreamCommon->getChannelMask();
|
||||
}
|
||||
|
||||
Return<void> StreamIn::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
|
||||
return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setChannelMask(AudioChannelMask mask) {
|
||||
return mStreamCommon->setChannelMask(mask);
|
||||
}
|
||||
|
||||
Return<AudioFormat> StreamIn::getFormat() {
|
||||
return mStreamCommon->getFormat();
|
||||
}
|
||||
|
||||
Return<void> StreamIn::getSupportedFormats(getSupportedFormats_cb _hidl_cb) {
|
||||
return mStreamCommon->getSupportedFormats(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setFormat(AudioFormat format) {
|
||||
return mStreamCommon->setFormat(format);
|
||||
}
|
||||
|
||||
Return<void> StreamIn::getAudioProperties(getAudioProperties_cb _hidl_cb) {
|
||||
return mStreamCommon->getAudioProperties(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::addEffect(uint64_t effectId) {
|
||||
return mStreamCommon->addEffect(effectId);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::removeEffect(uint64_t effectId) {
|
||||
return mStreamCommon->removeEffect(effectId);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::standby() {
|
||||
return mStreamCommon->standby();
|
||||
}
|
||||
|
||||
Return<AudioDevice> StreamIn::getDevice() {
|
||||
return mStreamCommon->getDevice();
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setDevice(const DeviceAddress& address) {
|
||||
return mStreamCommon->setDevice(address);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setConnectedState(const DeviceAddress& address, bool connected) {
|
||||
return mStreamCommon->setConnectedState(address, connected);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setHwAvSync(uint32_t hwAvSync) {
|
||||
return mStreamCommon->setHwAvSync(hwAvSync);
|
||||
}
|
||||
|
||||
Return<void> StreamIn::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
|
||||
return mStreamCommon->getParameters(keys, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setParameters(const hidl_vec<ParameterValue>& parameters) {
|
||||
return mStreamCommon->setParameters(parameters);
|
||||
}
|
||||
|
||||
Return<void> StreamIn::debugDump(const native_handle_t* fd) {
|
||||
return mStreamCommon->debugDump(fd);
|
||||
}
|
||||
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStreamIn follow.
|
||||
Return<void> StreamIn::getAudioSource(getAudioSource_cb _hidl_cb) {
|
||||
int halSource;
|
||||
Result retval = mStreamCommon->getParam(AudioParameter::keyInputSource, &halSource);
|
||||
AudioSource source(AudioSource::DEFAULT);
|
||||
if (retval == Result::OK) {
|
||||
source = AudioSource(halSource);
|
||||
}
|
||||
_hidl_cb(retval, source);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> StreamIn::setGain(float gain) {
|
||||
return mStreamCommon->analyzeStatus("set_gain", mStream->set_gain(mStream, gain));
|
||||
}
|
||||
|
||||
Return<void> StreamIn::read(uint64_t size, read_cb _hidl_cb) {
|
||||
// TODO(mnaganov): Replace with FMQ version.
|
||||
hidl_vec<uint8_t> data;
|
||||
data.resize(size);
|
||||
Result retval(Result::OK);
|
||||
ssize_t readResult = mStream->read(mStream, &data[0], data.size());
|
||||
if (readResult >= 0 && static_cast<size_t>(readResult) != data.size()) {
|
||||
data.resize(readResult);
|
||||
} else if (readResult < 0) {
|
||||
data.resize(0);
|
||||
retval = mStreamCommon->analyzeStatus("read", readResult);
|
||||
}
|
||||
_hidl_cb(retval, data);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<uint32_t> StreamIn::getInputFramesLost() {
|
||||
return mStream->get_input_frames_lost(mStream);
|
||||
}
|
||||
|
||||
Return<void> StreamIn::getCapturePosition(getCapturePosition_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
uint64_t frames = 0, time = 0;
|
||||
if (mStream->get_capture_position != NULL) {
|
||||
int64_t halFrames, halTime;
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
"get_capture_position",
|
||||
mStream->get_capture_position(mStream, &halFrames, &halTime));
|
||||
if (retval == Result::OK) {
|
||||
frames = halFrames;
|
||||
time = halTime;
|
||||
}
|
||||
}
|
||||
_hidl_cb(retval, frames, time);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
98
audio/2.0/default/StreamIn.h
Normal file
98
audio/2.0/default/StreamIn.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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 HIDL_GENERATED_android_hardware_audio_V2_0_StreamIn_H_
|
||||
#define HIDL_GENERATED_android_hardware_audio_V2_0_StreamIn_H_
|
||||
|
||||
#include <android/hardware/audio/2.0/IStreamIn.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
|
||||
#include "Stream.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
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::AudioSource;
|
||||
using ::android::hardware::audio::V2_0::DeviceAddress;
|
||||
using ::android::hardware::audio::V2_0::IStream;
|
||||
using ::android::hardware::audio::V2_0::IStreamIn;
|
||||
using ::android::hardware::audio::V2_0::ParameterValue;
|
||||
using ::android::hardware::audio::V2_0::Result;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
struct StreamIn : public IStreamIn {
|
||||
StreamIn(audio_hw_device_t* device, audio_stream_in_t* stream);
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStream follow.
|
||||
Return<uint64_t> getFrameSize() override;
|
||||
Return<uint64_t> getFrameCount() override;
|
||||
Return<uint64_t> getBufferSize() override;
|
||||
Return<uint32_t> getSampleRate() override;
|
||||
Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override;
|
||||
Return<Result> setSampleRate(uint32_t sampleRateHz) override;
|
||||
Return<AudioChannelMask> getChannelMask() override;
|
||||
Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override;
|
||||
Return<Result> setChannelMask(AudioChannelMask mask) override;
|
||||
Return<AudioFormat> getFormat() override;
|
||||
Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override;
|
||||
Return<Result> setFormat(AudioFormat format) override;
|
||||
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
|
||||
Return<Result> addEffect(uint64_t effectId) override;
|
||||
Return<Result> removeEffect(uint64_t effectId) override;
|
||||
Return<Result> standby() override;
|
||||
Return<AudioDevice> getDevice() override;
|
||||
Return<Result> setDevice(const DeviceAddress& address) override;
|
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
|
||||
Return<Result> setHwAvSync(uint32_t hwAvSync) override;
|
||||
Return<void> getParameters(
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
|
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
|
||||
Return<void> debugDump(const native_handle_t* fd) override;
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStreamIn follow.
|
||||
Return<void> getAudioSource(getAudioSource_cb _hidl_cb) override;
|
||||
Return<Result> setGain(float gain) override;
|
||||
Return<void> read(uint64_t size, read_cb _hidl_cb) override;
|
||||
Return<uint32_t> getInputFramesLost() override;
|
||||
Return<void> getCapturePosition(getCapturePosition_cb _hidl_cb) override;
|
||||
|
||||
private:
|
||||
audio_hw_device_t *mDevice;
|
||||
audio_stream_in_t *mStream;
|
||||
sp<Stream> mStreamCommon;
|
||||
|
||||
virtual ~StreamIn();
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HIDL_GENERATED_android_hardware_audio_V2_0_StreamIn_H_
|
||||
275
audio/2.0/default/StreamOut.cpp
Normal file
275
audio/2.0/default/StreamOut.cpp
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "StreamOutHAL"
|
||||
|
||||
#include <hardware/audio.h>
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "StreamOut.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
StreamOut::StreamOut(audio_hw_device_t* device, audio_stream_out_t* stream)
|
||||
: mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
|
||||
}
|
||||
|
||||
StreamOut::~StreamOut() {
|
||||
mCallback.clear();
|
||||
mDevice->close_output_stream(mDevice, mStream);
|
||||
mStream = nullptr;
|
||||
mDevice = nullptr;
|
||||
}
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStream follow.
|
||||
Return<uint64_t> StreamOut::getFrameSize() {
|
||||
return audio_stream_out_frame_size(mStream);
|
||||
}
|
||||
|
||||
Return<uint64_t> StreamOut::getFrameCount() {
|
||||
return mStreamCommon->getFrameCount();
|
||||
}
|
||||
|
||||
Return<uint64_t> StreamOut::getBufferSize() {
|
||||
return mStreamCommon->getBufferSize();
|
||||
}
|
||||
|
||||
Return<uint32_t> StreamOut::getSampleRate() {
|
||||
return mStreamCommon->getSampleRate();
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
|
||||
return mStreamCommon->getSupportedSampleRates(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setSampleRate(uint32_t sampleRateHz) {
|
||||
return mStreamCommon->setSampleRate(sampleRateHz);
|
||||
}
|
||||
|
||||
Return<AudioChannelMask> StreamOut::getChannelMask() {
|
||||
return mStreamCommon->getChannelMask();
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
|
||||
return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setChannelMask(AudioChannelMask mask) {
|
||||
return mStreamCommon->setChannelMask(mask);
|
||||
}
|
||||
|
||||
Return<AudioFormat> StreamOut::getFormat() {
|
||||
return mStreamCommon->getFormat();
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getSupportedFormats(getSupportedFormats_cb _hidl_cb) {
|
||||
return mStreamCommon->getSupportedFormats(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setFormat(AudioFormat format) {
|
||||
return mStreamCommon->setFormat(format);
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getAudioProperties(getAudioProperties_cb _hidl_cb) {
|
||||
return mStreamCommon->getAudioProperties(_hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::addEffect(uint64_t effectId) {
|
||||
return mStreamCommon->addEffect(effectId);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::removeEffect(uint64_t effectId) {
|
||||
return mStreamCommon->removeEffect(effectId);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::standby() {
|
||||
return mStreamCommon->standby();
|
||||
}
|
||||
|
||||
Return<AudioDevice> StreamOut::getDevice() {
|
||||
return mStreamCommon->getDevice();
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setDevice(const DeviceAddress& address) {
|
||||
return mStreamCommon->setDevice(address);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setConnectedState(const DeviceAddress& address, bool connected) {
|
||||
return mStreamCommon->setConnectedState(address, connected);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setHwAvSync(uint32_t hwAvSync) {
|
||||
return mStreamCommon->setHwAvSync(hwAvSync);
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getParameters(
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
|
||||
return mStreamCommon->getParameters(keys, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setParameters(const hidl_vec<ParameterValue>& parameters) {
|
||||
return mStreamCommon->setParameters(parameters);
|
||||
}
|
||||
|
||||
Return<void> StreamOut::debugDump(const native_handle_t* fd) {
|
||||
return mStreamCommon->debugDump(fd);
|
||||
}
|
||||
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
|
||||
Return<uint32_t> StreamOut::getLatency() {
|
||||
return mStream->get_latency(mStream);
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setVolume(float left, float right) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
if (mStream->set_volume != NULL) {
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
"set_volume", mStream->set_volume(mStream, left, right));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
Return<void> StreamOut::write(const hidl_vec<uint8_t>& data, write_cb _hidl_cb) {
|
||||
// TODO(mnaganov): Replace with FMQ version.
|
||||
Result retval(Result::OK);
|
||||
uint64_t written = 0;
|
||||
ssize_t writeResult = mStream->write(mStream, &data[0], data.size());
|
||||
if (writeResult >= 0) {
|
||||
written = writeResult;
|
||||
} else {
|
||||
retval = mStreamCommon->analyzeStatus("write", writeResult);
|
||||
written = 0;
|
||||
}
|
||||
_hidl_cb(retval, written);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb) {
|
||||
uint32_t halDspFrames;
|
||||
Result retval = mStreamCommon->analyzeStatus(
|
||||
"get_render_position", mStream->get_render_position(mStream, &halDspFrames));
|
||||
_hidl_cb(retval, halDspFrames);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
int64_t timestampUs = 0;
|
||||
if (mStream->get_next_write_timestamp != NULL) {
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
"get_next_write_timestamp",
|
||||
mStream->get_next_write_timestamp(mStream, ×tampUs));
|
||||
}
|
||||
_hidl_cb(retval, timestampUs);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback) {
|
||||
if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED;
|
||||
int result = mStream->set_callback(mStream, StreamOut::asyncCallback, this);
|
||||
if (result == 0) {
|
||||
mCallback = callback;
|
||||
}
|
||||
return mStreamCommon->analyzeStatus("set_callback", result);
|
||||
}
|
||||
|
||||
// static
|
||||
int StreamOut::asyncCallback(stream_callback_event_t event, void*, void *cookie) {
|
||||
wp<StreamOut> weakSelf(reinterpret_cast<StreamOut*>(cookie));
|
||||
sp<StreamOut> self = weakSelf.promote();
|
||||
if (self == 0) return 0;
|
||||
sp<IStreamOutCallback> callback = self->mCallback.promote();
|
||||
if (callback == 0) return 0;
|
||||
ALOGV("asyncCallback() event %d", event);
|
||||
switch (event) {
|
||||
case STREAM_CBK_EVENT_WRITE_READY:
|
||||
callback->onWriteReady();
|
||||
break;
|
||||
case STREAM_CBK_EVENT_DRAIN_READY:
|
||||
callback->onDrainReady();
|
||||
break;
|
||||
case STREAM_CBK_EVENT_ERROR:
|
||||
callback->onError();
|
||||
break;
|
||||
default:
|
||||
ALOGW("asyncCallback() unknown event %d", event);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
Return<void> StreamOut::supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb) {
|
||||
_hidl_cb(mStream->pause != NULL, mStream->resume != NULL);
|
||||
return Void();
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::pause() {
|
||||
return mStream->pause != NULL ?
|
||||
mStreamCommon->analyzeStatus("pause", mStream->pause(mStream)) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::resume() {
|
||||
return mStream->resume != NULL ?
|
||||
mStreamCommon->analyzeStatus("resume", mStream->resume(mStream)) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<bool> StreamOut::supportsDrain() {
|
||||
return mStream->drain != NULL;
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::drain(AudioDrain type) {
|
||||
return mStream->drain != NULL ?
|
||||
mStreamCommon->analyzeStatus(
|
||||
"drain", mStream->drain(mStream, static_cast<audio_drain_type_t>(type))) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<Result> StreamOut::flush() {
|
||||
return mStream->flush != NULL ?
|
||||
mStreamCommon->analyzeStatus("flush", mStream->flush(mStream)) :
|
||||
Result::NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
Return<void> StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl_cb) {
|
||||
Result retval(Result::NOT_SUPPORTED);
|
||||
uint64_t frames = 0;
|
||||
TimeSpec timeStamp = { 0, 0 };
|
||||
if (mStream->get_presentation_position != NULL) {
|
||||
struct timespec halTimeStamp;
|
||||
retval = mStreamCommon->analyzeStatus(
|
||||
"get_presentation_position",
|
||||
mStream->get_presentation_position(mStream, &frames, &halTimeStamp));
|
||||
if (retval == Result::OK) {
|
||||
timeStamp.tvSec = halTimeStamp.tv_sec;
|
||||
timeStamp.tvNSec = halTimeStamp.tv_nsec;
|
||||
}
|
||||
}
|
||||
_hidl_cb(retval, frames, timeStamp);
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
113
audio/2.0/default/StreamOut.h
Normal file
113
audio/2.0/default/StreamOut.h
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* 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 HIDL_GENERATED_android_hardware_audio_V2_0_StreamOut_H_
|
||||
#define HIDL_GENERATED_android_hardware_audio_V2_0_StreamOut_H_
|
||||
|
||||
#include <android/hardware/audio/2.0/IStreamOut.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
#include <hidl/MQDescriptor.h>
|
||||
|
||||
#include "Stream.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
namespace audio {
|
||||
namespace V2_0 {
|
||||
namespace implementation {
|
||||
|
||||
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::V2_0::AudioDrain;
|
||||
using ::android::hardware::audio::V2_0::DeviceAddress;
|
||||
using ::android::hardware::audio::V2_0::IStream;
|
||||
using ::android::hardware::audio::V2_0::IStreamOut;
|
||||
using ::android::hardware::audio::V2_0::IStreamOutCallback;
|
||||
using ::android::hardware::audio::V2_0::ParameterValue;
|
||||
using ::android::hardware::audio::V2_0::Result;
|
||||
using ::android::hardware::audio::V2_0::TimeSpec;
|
||||
using ::android::hardware::Return;
|
||||
using ::android::hardware::Void;
|
||||
using ::android::hardware::hidl_vec;
|
||||
using ::android::hardware::hidl_string;
|
||||
using ::android::sp;
|
||||
|
||||
struct StreamOut : public IStreamOut {
|
||||
StreamOut(audio_hw_device_t* device, audio_stream_out_t* stream);
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStream follow.
|
||||
Return<uint64_t> getFrameSize() override;
|
||||
Return<uint64_t> getFrameCount() override;
|
||||
Return<uint64_t> getBufferSize() override;
|
||||
Return<uint32_t> getSampleRate() override;
|
||||
Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override;
|
||||
Return<Result> setSampleRate(uint32_t sampleRateHz) override;
|
||||
Return<AudioChannelMask> getChannelMask() override;
|
||||
Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override;
|
||||
Return<Result> setChannelMask(AudioChannelMask mask) override;
|
||||
Return<AudioFormat> getFormat() override;
|
||||
Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override;
|
||||
Return<Result> setFormat(AudioFormat format) override;
|
||||
Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override;
|
||||
Return<Result> addEffect(uint64_t effectId) override;
|
||||
Return<Result> removeEffect(uint64_t effectId) override;
|
||||
Return<Result> standby() override;
|
||||
Return<AudioDevice> getDevice() override;
|
||||
Return<Result> setDevice(const DeviceAddress& address) override;
|
||||
Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override;
|
||||
Return<Result> setHwAvSync(uint32_t hwAvSync) override;
|
||||
Return<void> getParameters(
|
||||
const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override;
|
||||
Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override;
|
||||
Return<void> debugDump(const native_handle_t* fd) override;
|
||||
|
||||
// Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
|
||||
Return<uint32_t> getLatency() override;
|
||||
Return<Result> setVolume(float left, float right) override;
|
||||
Return<void> write(const hidl_vec<uint8_t>& data, write_cb _hidl_cb) override;
|
||||
Return<void> getRenderPosition(getRenderPosition_cb _hidl_cb) override;
|
||||
Return<void> getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb) override;
|
||||
Return<Result> setCallback(const sp<IStreamOutCallback>& callback) override;
|
||||
Return<void> supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb) override;
|
||||
Return<Result> pause() override;
|
||||
Return<Result> resume() override;
|
||||
Return<bool> supportsDrain() override;
|
||||
Return<Result> drain(AudioDrain type) override;
|
||||
Return<Result> flush() override;
|
||||
Return<void> getPresentationPosition(getPresentationPosition_cb _hidl_cb) override;
|
||||
|
||||
private:
|
||||
audio_hw_device_t *mDevice;
|
||||
audio_stream_out_t *mStream;
|
||||
sp<Stream> 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<IStreamOutCallback> mCallback;
|
||||
|
||||
virtual ~StreamOut();
|
||||
|
||||
static int asyncCallback(stream_callback_event_t event, void *param, void *cookie);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V2_0
|
||||
} // namespace audio
|
||||
} // namespace hardware
|
||||
} // namespace android
|
||||
|
||||
#endif // HIDL_GENERATED_android_hardware_audio_V2_0_StreamOut_H_
|
||||
@@ -14,28 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "soundtriggerhal"
|
||||
#define LOG_TAG "audiohalservice"
|
||||
|
||||
#include <hwbinder/IInterface.h>
|
||||
#include <hwbinder/IPCThreadState.h>
|
||||
#include <hwbinder/ProcessState.h>
|
||||
#include <utils/Errors.h>
|
||||
#include <utils/Log.h>
|
||||
#include <utils/Looper.h>
|
||||
#include <utils/StrongPointer.h>
|
||||
#include <hidl/LegacySupport.h>
|
||||
#include <android/hardware/audio/2.0/IDevicesFactory.h>
|
||||
#include <android/hardware/audio/effect/2.0/IEffectsFactory.h>
|
||||
#include <android/hardware/soundtrigger/2.0/ISoundTriggerHw.h>
|
||||
|
||||
using android::hardware::IPCThreadState;
|
||||
using android::hardware::ProcessState;
|
||||
using android::hardware::audio::effect::V2_0::IEffectsFactory;
|
||||
using android::hardware::audio::V2_0::IDevicesFactory;
|
||||
using android::hardware::soundtrigger::V2_0::ISoundTriggerHw;
|
||||
using android::hardware::registerPassthroughServiceImplementation;
|
||||
|
||||
int main(int /* argc */, char* /* argv */ []) {
|
||||
android::sp<ISoundTriggerHw> service =
|
||||
ISoundTriggerHw::getService("sound_trigger.primary", true /* getStub */);
|
||||
|
||||
service->registerAsService("sound_trigger.primary");
|
||||
|
||||
ProcessState::self()->setThreadPoolMaxThreadCount(0);
|
||||
ProcessState::self()->startThreadPool();
|
||||
IPCThreadState::self()->joinThreadPool();
|
||||
registerPassthroughServiceImplementation<IDevicesFactory>("audio_devices_factory");
|
||||
registerPassthroughServiceImplementation<IEffectsFactory>("audio_effects_factory");
|
||||
registerPassthroughServiceImplementation<ISoundTriggerHw>("sound_trigger.primary");
|
||||
return android::hardware::launchRpcServer(16);
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ struct DeviceAddress {
|
||||
int32_t card;
|
||||
int32_t device;
|
||||
} alsa; // used for USB_*
|
||||
int32_t busId; // used for BUS
|
||||
} address;
|
||||
string busAddress; // used for BUS
|
||||
string rSubmixAddress; // used for REMOTE_SUBMIX
|
||||
};
|
||||
|
||||
29
audio/common/2.0/default/Android.mk
Normal file
29
audio/common/2.0/default/Android.mk
Normal file
@@ -0,0 +1,29 @@
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := android.hardware.audio.common@2.0-util
|
||||
LOCAL_SRC_FILES := \
|
||||
EffectMap.cpp \
|
||||
|
||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libutils \
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
57
audio/common/2.0/default/EffectMap.cpp
Normal file
57
audio/common/2.0/default/EffectMap.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 <atomic>
|
||||
|
||||
#include "EffectMap.h"
|
||||
|
||||
namespace android {
|
||||
|
||||
ANDROID_SINGLETON_STATIC_INSTANCE(EffectMap);
|
||||
|
||||
// static
|
||||
const uint64_t EffectMap::INVALID_ID = 0;
|
||||
|
||||
// static
|
||||
uint64_t EffectMap::makeUniqueId() {
|
||||
static std::atomic<uint64_t> counter{INVALID_ID + 1};
|
||||
return counter++;
|
||||
}
|
||||
|
||||
uint64_t EffectMap::add(effect_handle_t handle) {
|
||||
uint64_t newId = makeUniqueId();
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
mEffects.add(newId, handle);
|
||||
return newId;
|
||||
}
|
||||
|
||||
effect_handle_t EffectMap::get(const uint64_t& id) {
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
ssize_t idx = mEffects.indexOfKey(id);
|
||||
return idx >= 0 ? mEffects[idx] : NULL;
|
||||
}
|
||||
|
||||
void EffectMap::remove(effect_handle_t handle) {
|
||||
std::lock_guard<std::mutex> lock(mLock);
|
||||
for (size_t i = 0; i < mEffects.size(); ++i) {
|
||||
if (mEffects[i] == handle) {
|
||||
mEffects.removeItemsAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace android
|
||||
46
audio/common/2.0/default/EffectMap.h
Normal file
46
audio/common/2.0/default/EffectMap.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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_EffectMap_H_
|
||||
#define android_hardware_audio_V2_0_EffectMap_H_
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <hardware/audio_effect.h>
|
||||
#include <utils/KeyedVector.h>
|
||||
#include <utils/Singleton.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
// This class needs to be in 'android' ns because Singleton macros require that.
|
||||
class EffectMap : public Singleton<EffectMap> {
|
||||
public:
|
||||
static const uint64_t INVALID_ID;
|
||||
|
||||
uint64_t add(effect_handle_t handle);
|
||||
effect_handle_t get(const uint64_t& id);
|
||||
void remove(effect_handle_t handle);
|
||||
|
||||
private:
|
||||
static uint64_t makeUniqueId();
|
||||
|
||||
std::mutex mLock;
|
||||
KeyedVector<uint64_t, effect_handle_t> mEffects;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
#endif // android_hardware_audio_V2_0_EffectMap_H_
|
||||
@@ -555,8 +555,7 @@ enum AudioDevice : uint32_t {
|
||||
IN_IP = BIT_IN | 0x80000,
|
||||
/* audio bus implemented by the audio system (e.g an MOST stereo channel) */
|
||||
IN_BUS = BIT_IN | 0x100000,
|
||||
IN_DEFAULT = BIT_IN |
|
||||
BIT_DEFAULT,
|
||||
IN_DEFAULT = BIT_IN | BIT_DEFAULT,
|
||||
|
||||
IN_ALL = (IN_COMMUNICATION |
|
||||
IN_AMBIENT |
|
||||
@@ -798,10 +797,10 @@ struct AudioPortConfig {
|
||||
union UseCase {
|
||||
AudioStreamType stream;
|
||||
AudioSource source;
|
||||
};
|
||||
} useCase;
|
||||
} mix;
|
||||
AudioPortConfigSessionExt session;
|
||||
};
|
||||
} ext;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -849,16 +848,5 @@ struct AudioPort {
|
||||
AudioPortDeviceExt device;
|
||||
AudioPortMixExt mix;
|
||||
AudioPortSessionExt session;
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* An audio patch represents a connection between one or more source ports and
|
||||
* one or more sink ports. Patches are connected and disconnected by audio
|
||||
* policy manager or by applications via framework APIs.
|
||||
*/
|
||||
struct AudioPatch {
|
||||
AudioPatchHandle id;
|
||||
vec<AudioPortConfig> sources;
|
||||
vec<AudioPortConfig> sinks;
|
||||
} ext;
|
||||
};
|
||||
|
||||
@@ -50,9 +50,11 @@ interface IEffectsFactory {
|
||||
* directed to in audio HAL.
|
||||
* @return retval operation completion status.
|
||||
* @return result the interface for the created effect.
|
||||
* @return effectId the unique ID of the effect to be used with
|
||||
* IStream::addEffect and IStream::removeEffect methods.
|
||||
*/
|
||||
createEffect(Uuid uid, AudioSession session, AudioIoHandle ioHandle)
|
||||
generates (Result retval, IEffect result);
|
||||
generates (Result retval, IEffect result, uint64_t effectId);
|
||||
|
||||
/*
|
||||
* Dumps information about effects into the provided file descriptor.
|
||||
|
||||
@@ -26,6 +26,7 @@ LOCAL_SHARED_LIBRARIES := \
|
||||
libeffects \
|
||||
liblog \
|
||||
android.hardware.audio.common@2.0 \
|
||||
android.hardware.audio.common@2.0-util \
|
||||
android.hardware.audio.effect@2.0 \
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "Conversions.h"
|
||||
#include "Effect.h"
|
||||
#include "EffectMap.h"
|
||||
|
||||
namespace android {
|
||||
namespace hardware {
|
||||
@@ -45,6 +46,7 @@ Effect::Effect(effect_handle_t handle) : mHandle(handle) {
|
||||
Effect::~Effect() {
|
||||
int status = EffectRelease(mHandle);
|
||||
ALOGW_IF(status, "Error releasing effect %p: %s", mHandle, strerror(-status));
|
||||
EffectMap::getInstance().remove(mHandle);
|
||||
mHandle = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "EffectsFactory.h"
|
||||
#include "DownmixEffect.h"
|
||||
#include "Effect.h"
|
||||
#include "EffectMap.h"
|
||||
#include "EnvironmentalReverbEffect.h"
|
||||
#include "EqualizerEffect.h"
|
||||
#include "LoudnessEnhancerEffect.h"
|
||||
@@ -157,12 +158,16 @@ Return<void> EffectsFactory::createEffect(
|
||||
Result retval(Result::OK);
|
||||
status_t status = EffectCreate(&halUuid, session, ioHandle, &handle);
|
||||
sp<IEffect> effect;
|
||||
uint64_t effectId = EffectMap::INVALID_ID;
|
||||
if (status == OK) {
|
||||
effect_descriptor_t halDescriptor;
|
||||
memset(&halDescriptor, 0, sizeof(effect_descriptor_t));
|
||||
status = (*handle)->get_descriptor(handle, &halDescriptor);
|
||||
if (status == OK) {
|
||||
effect = dispatchEffectInstanceCreation(halDescriptor, handle);
|
||||
effectId = EffectMap::getInstance().add(handle);
|
||||
} else {
|
||||
EffectRelease(handle);
|
||||
}
|
||||
}
|
||||
if (status != OK) {
|
||||
@@ -173,7 +178,7 @@ Return<void> EffectsFactory::createEffect(
|
||||
retval = Result::NOT_INITIALIZED;
|
||||
}
|
||||
}
|
||||
_hidl_cb(retval, effect);
|
||||
_hidl_cb(retval, effect, effectId);
|
||||
return Void();
|
||||
}
|
||||
|
||||
|
||||
@@ -84,13 +84,14 @@ TEST_F(AudioEffectHidlTest, CreateEffect) {
|
||||
ASSERT_TRUE(gotEffect);
|
||||
Result retval = Result::NOT_INITIALIZED;
|
||||
sp<IEffect> effect;
|
||||
ret = effectsFactory->createEffect(effectUuid, 1, 1,
|
||||
[&](Result r, const sp<IEffect>& result) {
|
||||
retval = r;
|
||||
if (r == Result::OK) {
|
||||
effect = result;
|
||||
}
|
||||
});
|
||||
ret = effectsFactory->createEffect(
|
||||
effectUuid, 1 /* session */, 1 /* ioHandle */,
|
||||
[&](Result r, const sp<IEffect>& result, uint64_t /*effectId*/) {
|
||||
retval = r;
|
||||
if (r == Result::OK) {
|
||||
effect = result;
|
||||
}
|
||||
});
|
||||
EXPECT_EQ(ret.getStatus().exceptionCode(), Status::EX_NONE);
|
||||
EXPECT_EQ(retval, Result::OK);
|
||||
EXPECT_NE(effect, nullptr);
|
||||
|
||||
Reference in New Issue
Block a user