1e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov/* 2e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * Copyright (C) 2016 The Android Open Source Project 3e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * 4e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License"); 5e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * you may not use this file except in compliance with the License. 6e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * You may obtain a copy of the License at 7e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * 8e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * http://www.apache.org/licenses/LICENSE-2.0 9e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * 10e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * Unless required by applicable law or agreed to in writing, software 11e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS, 12e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * See the License for the specific language governing permissions and 14e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov * limitations under the License. 15e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov */ 16e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 17a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov#define LOG_TAG "DeviceHalLocal" 18e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov//#define LOG_NDEBUG 0 19e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 20e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov#include <utils/Log.h> 21e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 22e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov#include "DeviceHalLocal.h" 231dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov#include "StreamHalLocal.h" 24e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 25e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovnamespace android { 26e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 27e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail NaganovDeviceHalLocal::DeviceHalLocal(audio_hw_device_t *dev) 28e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov : mDev(dev) { 29e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 30e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 31e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail NaganovDeviceHalLocal::~DeviceHalLocal() { 32e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov int status = audio_hw_device_close(mDev); 33e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov ALOGW_IF(status, "Error closing audio hw device %p: %s", mDev, strerror(-status)); 34e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov mDev = 0; 35e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 36e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 37e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::getSupportedDevices(uint32_t *devices) { 38e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov if (mDev->get_supported_devices == NULL) return INVALID_OPERATION; 39e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov *devices = mDev->get_supported_devices(mDev); 40e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return OK; 41e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 42e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 43e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::initCheck() { 44e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->init_check(mDev); 45e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 46e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 47e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::setVoiceVolume(float volume) { 48e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->set_voice_volume(mDev, volume); 49e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 50e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 51e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::setMasterVolume(float volume) { 52e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov if (mDev->set_master_volume == NULL) return INVALID_OPERATION; 53e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->set_master_volume(mDev, volume); 54e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 55e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 56e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::getMasterVolume(float *volume) { 57e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov if (mDev->get_master_volume == NULL) return INVALID_OPERATION; 58e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->get_master_volume(mDev, volume); 59e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 60e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 61e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::setMode(audio_mode_t mode) { 62e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->set_mode(mDev, mode); 63e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 64e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 65e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::setMicMute(bool state) { 66e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->set_mic_mute(mDev, state); 67e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 68e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 69e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::getMicMute(bool *state) { 70e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->get_mic_mute(mDev, state); 71e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 72e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 73e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::setMasterMute(bool state) { 74e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov if (mDev->set_master_mute == NULL) return INVALID_OPERATION; 75e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->set_master_mute(mDev, state); 76e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 77e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 78e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::getMasterMute(bool *state) { 79e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov if (mDev->get_master_mute == NULL) return INVALID_OPERATION; 80e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->get_master_mute(mDev, state); 81e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 82e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 83e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::setParameters(const String8& kvPairs) { 84e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->set_parameters(mDev, kvPairs.string()); 85e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 86e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 87e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::getParameters(const String8& keys, String8 *values) { 881dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov char *halValues = mDev->get_parameters(mDev, keys.string()); 891dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (halValues != NULL) { 901dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov values->setTo(halValues); 911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov free(halValues); 92e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov } else { 93e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov values->clear(); 94e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov } 95e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return OK; 96e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 97e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 98e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::getInputBufferSize( 99e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov const struct audio_config *config, size_t *size) { 100e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov *size = mDev->get_input_buffer_size(mDev, config); 101e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return OK; 102e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 103e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 1041dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t DeviceHalLocal::openOutputStream( 1051dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_io_handle_t handle, 1061dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_devices_t devices, 1071dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_output_flags_t flags, 1081dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov struct audio_config *config, 1091dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov const char *address, 1101dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov sp<StreamOutHalInterface> *outStream) { 1111dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_stream_out_t *halStream; 112f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov ALOGV("open_output_stream handle: %d devices: %x flags: %#x" 113f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov "srate: %d format %#x channels %x address %s", 114f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov handle, devices, flags, 115f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov config->sample_rate, config->format, config->channel_mask, 116f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov address); 1171dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov int openResut = mDev->open_output_stream( 1181dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mDev, handle, devices, flags, config, &halStream, address); 1191dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (openResut == OK) { 1201dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *outStream = new StreamOutHalLocal(halStream, this); 1211dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 122f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov ALOGV("open_output_stream status %d stream %p", openResut, halStream); 1231dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return openResut; 1241dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1251dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1261dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t DeviceHalLocal::openInputStream( 1271dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_io_handle_t handle, 1281dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_devices_t devices, 1291dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov struct audio_config *config, 1301dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_input_flags_t flags, 1311dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov const char *address, 1321dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_source_t source, 1331dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov sp<StreamInHalInterface> *inStream) { 1341dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov audio_stream_in_t *halStream; 135f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov ALOGV("open_input_stream handle: %d devices: %x flags: %#x " 136f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov "srate: %d format %#x channels %x address %s source %d", 137f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov handle, devices, flags, 138f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov config->sample_rate, config->format, config->channel_mask, 139f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov address, source); 1401dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov int openResult = mDev->open_input_stream( 1411dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mDev, handle, devices, config, &halStream, flags, address, source); 1421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (openResult == OK) { 1431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *inStream = new StreamInHalLocal(halStream, this); 1441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 145f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov ALOGV("open_input_stream status %d stream %p", openResult, inStream); 1461dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return openResult; 1471dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1481dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1499ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganovstatus_t DeviceHalLocal::supportsAudioPatches(bool *supportsPatches) { 1509ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov *supportsPatches = version() >= AUDIO_DEVICE_API_VERSION_3_0; 1519ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov return OK; 1529ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov} 1539ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov 154e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::createAudioPatch( 155e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov unsigned int num_sources, 156e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov const struct audio_port_config *sources, 157e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov unsigned int num_sinks, 158e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov const struct audio_port_config *sinks, 159e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov audio_patch_handle_t *patch) { 1609ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 1619ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov return mDev->create_audio_patch( 1629ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov mDev, num_sources, sources, num_sinks, sinks, patch); 1639ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov } else { 1649ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov return INVALID_OPERATION; 1659ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov } 166e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 167e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 168e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::releaseAudioPatch(audio_patch_handle_t patch) { 1699ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 1709ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov return mDev->release_audio_patch(mDev, patch); 1719ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov } else { 1729ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov return INVALID_OPERATION; 1739ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov } 174e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 175e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 176e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::getAudioPort(struct audio_port *port) { 177e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->get_audio_port(mDev, port); 178e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 179e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 180e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::setAudioPortConfig(const struct audio_port_config *config) { 1819ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov if (version() >= AUDIO_DEVICE_API_VERSION_3_0) 1829ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov return mDev->set_audio_port_config(mDev, config); 1839ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov else 1849ee0540d3a61bff03d561ca431a371c3d9335d2bMikhail Naganov return INVALID_OPERATION; 185e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 186e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 187e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganovstatus_t DeviceHalLocal::dump(int fd) { 188e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov return mDev->dump(mDev, fd); 189e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 190e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 1911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid DeviceHalLocal::closeOutputStream(struct audio_stream_out *stream_out) { 192e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov mDev->close_output_stream(mDev, stream_out); 193e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 194e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 1951dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovvoid DeviceHalLocal::closeInputStream(struct audio_stream_in *stream_in) { 196e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov mDev->close_input_stream(mDev, stream_in); 197e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} 198e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov 199e4f1f63a2c54ee8687ad8cca18df0f6639ad7c81Mikhail Naganov} // namespace android 200