172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard/* 282cb03632c15976838407c231fd85804de9bf84cKevin Rocard * Copyright (C) 2016 The Android Open Source Project 382cb03632c15976838407c231fd85804de9bf84cKevin Rocard * 482cb03632c15976838407c231fd85804de9bf84cKevin Rocard * Licensed under the Apache License, Version 2.0 (the "License"); 582cb03632c15976838407c231fd85804de9bf84cKevin Rocard * you may not use this file except in compliance with the License. 682cb03632c15976838407c231fd85804de9bf84cKevin Rocard * You may obtain a copy of the License at 782cb03632c15976838407c231fd85804de9bf84cKevin Rocard * 882cb03632c15976838407c231fd85804de9bf84cKevin Rocard * http://www.apache.org/licenses/LICENSE-2.0 982cb03632c15976838407c231fd85804de9bf84cKevin Rocard * 1082cb03632c15976838407c231fd85804de9bf84cKevin Rocard * Unless required by applicable law or agreed to in writing, software 1182cb03632c15976838407c231fd85804de9bf84cKevin Rocard * distributed under the License is distributed on an "AS IS" BASIS, 1282cb03632c15976838407c231fd85804de9bf84cKevin Rocard * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1382cb03632c15976838407c231fd85804de9bf84cKevin Rocard * See the License for the specific language governing permissions and 1482cb03632c15976838407c231fd85804de9bf84cKevin Rocard * limitations under the License. 1582cb03632c15976838407c231fd85804de9bf84cKevin Rocard */ 1610548295023bee99108e418499aff09fe578211eMikhail Naganov 17e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocard#include <common/all-versions/IncludeGuard.h> 18e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocard 196e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov//#define LOG_NDEBUG 0 2010548295023bee99108e418499aff09fe578211eMikhail Naganov 2110548295023bee99108e418499aff09fe578211eMikhail Naganov#include <memory.h> 2210548295023bee99108e418499aff09fe578211eMikhail Naganov#include <string.h> 2382cb03632c15976838407c231fd85804de9bf84cKevin Rocard#include <algorithm> 2410548295023bee99108e418499aff09fe578211eMikhail Naganov 25f9d303435d80161fabb16cdff3b8f2f75f362480Yifan Hong#include <android/log.h> 2610548295023bee99108e418499aff09fe578211eMikhail Naganov 27e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocardusing ::android::hardware::audio::common::AUDIO_HAL_VERSION::HidlUtils; 286891d7ec28761db85c8d4c486fe105ee64a2bd04Kevin Rocard 2910548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace android { 3010548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace hardware { 3110548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace audio { 32e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocardnamespace AUDIO_HAL_VERSION { 3310548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace implementation { 3410548295023bee99108e418499aff09fe578211eMikhail Naganov 3582cb03632c15976838407c231fd85804de9bf84cKevin RocardDevice::Device(audio_hw_device_t* device) : mDevice(device) {} 3610548295023bee99108e418499aff09fe578211eMikhail Naganov 3710548295023bee99108e418499aff09fe578211eMikhail NaganovDevice::~Device() { 3810548295023bee99108e418499aff09fe578211eMikhail Naganov int status = audio_hw_device_close(mDevice); 3982cb03632c15976838407c231fd85804de9bf84cKevin Rocard ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status)); 4010548295023bee99108e418499aff09fe578211eMikhail Naganov mDevice = nullptr; 4110548295023bee99108e418499aff09fe578211eMikhail Naganov} 4210548295023bee99108e418499aff09fe578211eMikhail Naganov 4310548295023bee99108e418499aff09fe578211eMikhail NaganovResult Device::analyzeStatus(const char* funcName, int status) { 4464c3932736558609f7cf657b2a63e90a937f663cKevin Rocard return util::analyzeStatus("Device", funcName, status); 4510548295023bee99108e418499aff09fe578211eMikhail Naganov} 4610548295023bee99108e418499aff09fe578211eMikhail Naganov 47936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganovvoid Device::closeInputStream(audio_stream_in_t* stream) { 48936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov mDevice->close_input_stream(mDevice, stream); 49936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov} 50936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov 51936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganovvoid Device::closeOutputStream(audio_stream_out_t* stream) { 52936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov mDevice->close_output_stream(mDevice, stream); 53936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov} 54936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov 5586685f56da0941027406d1ffba67bd4272faa526Mikhail Naganovchar* Device::halGetParameters(const char* keys) { 5686685f56da0941027406d1ffba67bd4272faa526Mikhail Naganov return mDevice->get_parameters(mDevice, keys); 5710548295023bee99108e418499aff09fe578211eMikhail Naganov} 5810548295023bee99108e418499aff09fe578211eMikhail Naganov 5986685f56da0941027406d1ffba67bd4272faa526Mikhail Naganovint Device::halSetParameters(const char* keysAndValues) { 6086685f56da0941027406d1ffba67bd4272faa526Mikhail Naganov return mDevice->set_parameters(mDevice, keysAndValues); 6110548295023bee99108e418499aff09fe578211eMikhail Naganov} 6210548295023bee99108e418499aff09fe578211eMikhail Naganov 63e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocard// Methods from ::android::hardware::audio::AUDIO_HAL_VERSION::IDevice follow. 6472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<Result> Device::initCheck() { 6510548295023bee99108e418499aff09fe578211eMikhail Naganov return analyzeStatus("init_check", mDevice->init_check(mDevice)); 6610548295023bee99108e418499aff09fe578211eMikhail Naganov} 6710548295023bee99108e418499aff09fe578211eMikhail Naganov 6872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<Result> Device::setMasterVolume(float volume) { 694c030024dfa9cdf924cb771580e13d237f1ec813Kevin Rocard if (mDevice->set_master_volume == NULL) { 704c030024dfa9cdf924cb771580e13d237f1ec813Kevin Rocard return Result::NOT_SUPPORTED; 714c030024dfa9cdf924cb771580e13d237f1ec813Kevin Rocard } 724c030024dfa9cdf924cb771580e13d237f1ec813Kevin Rocard if (!isGainNormalized(volume)) { 734c030024dfa9cdf924cb771580e13d237f1ec813Kevin Rocard ALOGW("Can not set a master volume (%f) outside [0,1]", volume); 744c030024dfa9cdf924cb771580e13d237f1ec813Kevin Rocard return Result::INVALID_ARGUMENTS; 7510548295023bee99108e418499aff09fe578211eMikhail Naganov } 7682cb03632c15976838407c231fd85804de9bf84cKevin Rocard return analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume)); 7710548295023bee99108e418499aff09fe578211eMikhail Naganov} 7810548295023bee99108e418499aff09fe578211eMikhail Naganov 7972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) { 8010548295023bee99108e418499aff09fe578211eMikhail Naganov Result retval(Result::NOT_SUPPORTED); 8110548295023bee99108e418499aff09fe578211eMikhail Naganov float volume = 0; 8210548295023bee99108e418499aff09fe578211eMikhail Naganov if (mDevice->get_master_volume != NULL) { 8382cb03632c15976838407c231fd85804de9bf84cKevin Rocard retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume)); 8410548295023bee99108e418499aff09fe578211eMikhail Naganov } 8510548295023bee99108e418499aff09fe578211eMikhail Naganov _hidl_cb(retval, volume); 8610548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 8710548295023bee99108e418499aff09fe578211eMikhail Naganov} 8810548295023bee99108e418499aff09fe578211eMikhail Naganov 8972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<Result> Device::setMicMute(bool mute) { 9010548295023bee99108e418499aff09fe578211eMikhail Naganov return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute)); 9110548295023bee99108e418499aff09fe578211eMikhail Naganov} 9210548295023bee99108e418499aff09fe578211eMikhail Naganov 9372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<void> Device::getMicMute(getMicMute_cb _hidl_cb) { 9410548295023bee99108e418499aff09fe578211eMikhail Naganov bool mute = false; 9582cb03632c15976838407c231fd85804de9bf84cKevin Rocard Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute)); 9610548295023bee99108e418499aff09fe578211eMikhail Naganov _hidl_cb(retval, mute); 9710548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 9810548295023bee99108e418499aff09fe578211eMikhail Naganov} 9910548295023bee99108e418499aff09fe578211eMikhail Naganov 10072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<Result> Device::setMasterMute(bool mute) { 10110548295023bee99108e418499aff09fe578211eMikhail Naganov Result retval(Result::NOT_SUPPORTED); 10210548295023bee99108e418499aff09fe578211eMikhail Naganov if (mDevice->set_master_mute != NULL) { 10382cb03632c15976838407c231fd85804de9bf84cKevin Rocard retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute)); 10410548295023bee99108e418499aff09fe578211eMikhail Naganov } 10510548295023bee99108e418499aff09fe578211eMikhail Naganov return retval; 10610548295023bee99108e418499aff09fe578211eMikhail Naganov} 10710548295023bee99108e418499aff09fe578211eMikhail Naganov 10872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) { 10910548295023bee99108e418499aff09fe578211eMikhail Naganov Result retval(Result::NOT_SUPPORTED); 11010548295023bee99108e418499aff09fe578211eMikhail Naganov bool mute = false; 11110548295023bee99108e418499aff09fe578211eMikhail Naganov if (mDevice->get_master_mute != NULL) { 11282cb03632c15976838407c231fd85804de9bf84cKevin Rocard retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute)); 11310548295023bee99108e418499aff09fe578211eMikhail Naganov } 11410548295023bee99108e418499aff09fe578211eMikhail Naganov _hidl_cb(retval, mute); 11510548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 11610548295023bee99108e418499aff09fe578211eMikhail Naganov} 11710548295023bee99108e418499aff09fe578211eMikhail Naganov 11882cb03632c15976838407c231fd85804de9bf84cKevin RocardReturn<void> Device::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) { 11910548295023bee99108e418499aff09fe578211eMikhail Naganov audio_config_t halConfig; 1206e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioConfigToHal(config, &halConfig); 12110548295023bee99108e418499aff09fe578211eMikhail Naganov size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig); 12210548295023bee99108e418499aff09fe578211eMikhail Naganov Result retval(Result::INVALID_ARGUMENTS); 12310548295023bee99108e418499aff09fe578211eMikhail Naganov uint64_t bufferSize = 0; 12410548295023bee99108e418499aff09fe578211eMikhail Naganov if (halBufferSize != 0) { 12510548295023bee99108e418499aff09fe578211eMikhail Naganov retval = Result::OK; 12610548295023bee99108e418499aff09fe578211eMikhail Naganov bufferSize = halBufferSize; 12710548295023bee99108e418499aff09fe578211eMikhail Naganov } 12810548295023bee99108e418499aff09fe578211eMikhail Naganov _hidl_cb(retval, bufferSize); 12910548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 13010548295023bee99108e418499aff09fe578211eMikhail Naganov} 13110548295023bee99108e418499aff09fe578211eMikhail Naganov 13282cb03632c15976838407c231fd85804de9bf84cKevin RocardReturn<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, 1335ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard const AudioConfig& config, AudioOutputFlagBitfield flags, 1345ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#ifdef AUDIO_HAL_VERSION_4_0 1355ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard const SourceMetadata& /* sourceMetadata */, 1365ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#endif 13772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard openOutputStream_cb _hidl_cb) { 13810548295023bee99108e418499aff09fe578211eMikhail Naganov audio_config_t halConfig; 1396e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioConfigToHal(config, &halConfig); 14072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard audio_stream_out_t* halStream; 14172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ALOGV( 14272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "open_output_stream handle: %d devices: %x flags: %#x " 14372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "srate: %d format %#x channels %x address %s", 14472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ioHandle, static_cast<audio_devices_t>(device.device), 14582cb03632c15976838407c231fd85804de9bf84cKevin Rocard static_cast<audio_output_flags_t>(flags), halConfig.sample_rate, halConfig.format, 14682cb03632c15976838407c231fd85804de9bf84cKevin Rocard halConfig.channel_mask, deviceAddressToHal(device).c_str()); 14782cb03632c15976838407c231fd85804de9bf84cKevin Rocard int status = 14882cb03632c15976838407c231fd85804de9bf84cKevin Rocard mDevice->open_output_stream(mDevice, ioHandle, static_cast<audio_devices_t>(device.device), 14982cb03632c15976838407c231fd85804de9bf84cKevin Rocard static_cast<audio_output_flags_t>(flags), &halConfig, 15082cb03632c15976838407c231fd85804de9bf84cKevin Rocard &halStream, deviceAddressToHal(device).c_str()); 1516e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov ALOGV("open_output_stream status %d stream %p", status, halStream); 15210548295023bee99108e418499aff09fe578211eMikhail Naganov sp<IStreamOut> streamOut; 15310548295023bee99108e418499aff09fe578211eMikhail Naganov if (status == OK) { 154936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov streamOut = new StreamOut(this, halStream); 15510548295023bee99108e418499aff09fe578211eMikhail Naganov } 1566e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov AudioConfig suggestedConfig; 1576e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig); 15882cb03632c15976838407c231fd85804de9bf84cKevin Rocard _hidl_cb(analyzeStatus("open_output_stream", status), streamOut, suggestedConfig); 15910548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 16010548295023bee99108e418499aff09fe578211eMikhail Naganov} 16110548295023bee99108e418499aff09fe578211eMikhail Naganov 16282cb03632c15976838407c231fd85804de9bf84cKevin RocardReturn<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, 1635ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard const AudioConfig& config, AudioInputFlagBitfield flags, 16482cb03632c15976838407c231fd85804de9bf84cKevin Rocard AudioSource source, openInputStream_cb _hidl_cb) { 16510548295023bee99108e418499aff09fe578211eMikhail Naganov audio_config_t halConfig; 1666e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioConfigToHal(config, &halConfig); 16772e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard audio_stream_in_t* halStream; 16872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ALOGV( 16972e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "open_input_stream handle: %d devices: %x flags: %#x " 17072e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "srate: %d format %#x channels %x address %s source %d", 17172e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard ioHandle, static_cast<audio_devices_t>(device.device), 17282cb03632c15976838407c231fd85804de9bf84cKevin Rocard static_cast<audio_input_flags_t>(flags), halConfig.sample_rate, halConfig.format, 17382cb03632c15976838407c231fd85804de9bf84cKevin Rocard halConfig.channel_mask, deviceAddressToHal(device).c_str(), 17472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard static_cast<audio_source_t>(source)); 17510548295023bee99108e418499aff09fe578211eMikhail Naganov int status = mDevice->open_input_stream( 17682cb03632c15976838407c231fd85804de9bf84cKevin Rocard mDevice, ioHandle, static_cast<audio_devices_t>(device.device), &halConfig, &halStream, 17782cb03632c15976838407c231fd85804de9bf84cKevin Rocard static_cast<audio_input_flags_t>(flags), deviceAddressToHal(device).c_str(), 17872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard static_cast<audio_source_t>(source)); 1796e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov ALOGV("open_input_stream status %d stream %p", status, halStream); 18010548295023bee99108e418499aff09fe578211eMikhail Naganov sp<IStreamIn> streamIn; 18110548295023bee99108e418499aff09fe578211eMikhail Naganov if (status == OK) { 182936279e1ffe6bf7e842c46f9a94d98a48dce6754Mikhail Naganov streamIn = new StreamIn(this, halStream); 18310548295023bee99108e418499aff09fe578211eMikhail Naganov } 1846e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov AudioConfig suggestedConfig; 1856e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioConfigFromHal(halConfig, &suggestedConfig); 18682cb03632c15976838407c231fd85804de9bf84cKevin Rocard _hidl_cb(analyzeStatus("open_input_stream", status), streamIn, suggestedConfig); 18710548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 18810548295023bee99108e418499aff09fe578211eMikhail Naganov} 18910548295023bee99108e418499aff09fe578211eMikhail Naganov 1905ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#ifdef AUDIO_HAL_VERSION_4_0 1915ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardReturn<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, 1925ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard const AudioConfig& config, AudioInputFlagBitfield flags, 1935ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard const SinkMetadata& sinkMetadata, 1945ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard openInputStream_cb _hidl_cb) { 1955ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard if (sinkMetadata.tracks.size() == 0) { 1965ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard // This should never happen, the framework must not create as stream 1975ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard // if there is no client 1985ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard ALOGE("openInputStream called without tracks connected"); 1995ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig()); 2005ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return Void(); 2015ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard } 2025ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard // Pick the first one as the main until the legacy API is update 2035ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard AudioSource source = sinkMetadata.tracks[0].source; 2045ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return openInputStream(ioHandle, device, config, flags, source, _hidl_cb); 2055ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard} 2065ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#endif 2075ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard 2086e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail NaganovReturn<bool> Device::supportsAudioPatches() { 2096e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov return version() >= AUDIO_DEVICE_API_VERSION_3_0; 2106e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov} 2116e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov 21272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources, 21372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard const hidl_vec<AudioPortConfig>& sinks, 21472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard createAudioPatch_cb _hidl_cb) { 21510548295023bee99108e418499aff09fe578211eMikhail Naganov Result retval(Result::NOT_SUPPORTED); 21610548295023bee99108e418499aff09fe578211eMikhail Naganov AudioPatchHandle patch = 0; 21710548295023bee99108e418499aff09fe578211eMikhail Naganov if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 21882cb03632c15976838407c231fd85804de9bf84cKevin Rocard std::unique_ptr<audio_port_config[]> halSources(HidlUtils::audioPortConfigsToHal(sources)); 21982cb03632c15976838407c231fd85804de9bf84cKevin Rocard std::unique_ptr<audio_port_config[]> halSinks(HidlUtils::audioPortConfigsToHal(sinks)); 220ab24ecd9524b990bc82be778fa684691455f0002Derek Chen audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE; 22182cb03632c15976838407c231fd85804de9bf84cKevin Rocard retval = analyzeStatus("create_audio_patch", 22282cb03632c15976838407c231fd85804de9bf84cKevin Rocard mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0], 22382cb03632c15976838407c231fd85804de9bf84cKevin Rocard sinks.size(), &halSinks[0], &halPatch)); 22410548295023bee99108e418499aff09fe578211eMikhail Naganov if (retval == Result::OK) { 22510548295023bee99108e418499aff09fe578211eMikhail Naganov patch = static_cast<AudioPatchHandle>(halPatch); 22610548295023bee99108e418499aff09fe578211eMikhail Naganov } 22710548295023bee99108e418499aff09fe578211eMikhail Naganov } 22810548295023bee99108e418499aff09fe578211eMikhail Naganov _hidl_cb(retval, patch); 22910548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 23010548295023bee99108e418499aff09fe578211eMikhail Naganov} 23110548295023bee99108e418499aff09fe578211eMikhail Naganov 23272e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<Result> Device::releaseAudioPatch(int32_t patch) { 23310548295023bee99108e418499aff09fe578211eMikhail Naganov if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 23410548295023bee99108e418499aff09fe578211eMikhail Naganov return analyzeStatus( 23572e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin Rocard "release_audio_patch", 23682cb03632c15976838407c231fd85804de9bf84cKevin Rocard mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch))); 23710548295023bee99108e418499aff09fe578211eMikhail Naganov } 23810548295023bee99108e418499aff09fe578211eMikhail Naganov return Result::NOT_SUPPORTED; 23910548295023bee99108e418499aff09fe578211eMikhail Naganov} 24010548295023bee99108e418499aff09fe578211eMikhail Naganov 24182cb03632c15976838407c231fd85804de9bf84cKevin RocardReturn<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { 24210548295023bee99108e418499aff09fe578211eMikhail Naganov audio_port halPort; 2436e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioPortToHal(port, &halPort); 24482cb03632c15976838407c231fd85804de9bf84cKevin Rocard Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort)); 24510548295023bee99108e418499aff09fe578211eMikhail Naganov AudioPort resultPort = port; 24610548295023bee99108e418499aff09fe578211eMikhail Naganov if (retval == Result::OK) { 2476e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioPortFromHal(halPort, &resultPort); 24810548295023bee99108e418499aff09fe578211eMikhail Naganov } 24910548295023bee99108e418499aff09fe578211eMikhail Naganov _hidl_cb(retval, resultPort); 25010548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 25110548295023bee99108e418499aff09fe578211eMikhail Naganov} 25210548295023bee99108e418499aff09fe578211eMikhail Naganov 25372e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<Result> Device::setAudioPortConfig(const AudioPortConfig& config) { 25410548295023bee99108e418499aff09fe578211eMikhail Naganov if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 25510548295023bee99108e418499aff09fe578211eMikhail Naganov struct audio_port_config halPortConfig; 2566e81e9bb3c13d8c51fde503cf8be2bfb56e1ca1dMikhail Naganov HidlUtils::audioPortConfigToHal(config, &halPortConfig); 25782cb03632c15976838407c231fd85804de9bf84cKevin Rocard return analyzeStatus("set_audio_port_config", 25882cb03632c15976838407c231fd85804de9bf84cKevin Rocard mDevice->set_audio_port_config(mDevice, &halPortConfig)); 25910548295023bee99108e418499aff09fe578211eMikhail Naganov } 26010548295023bee99108e418499aff09fe578211eMikhail Naganov return Result::NOT_SUPPORTED; 26110548295023bee99108e418499aff09fe578211eMikhail Naganov} 26210548295023bee99108e418499aff09fe578211eMikhail Naganov 2635ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#ifdef AUDIO_HAL_VERSION_2_0 26472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<AudioHwSync> Device::getHwAvSync() { 26510548295023bee99108e418499aff09fe578211eMikhail Naganov int halHwAvSync; 26686685f56da0941027406d1ffba67bd4272faa526Mikhail Naganov Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); 26710548295023bee99108e418499aff09fe578211eMikhail Naganov return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID; 26810548295023bee99108e418499aff09fe578211eMikhail Naganov} 2695ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#elif defined(AUDIO_HAL_VERSION_4_0) 2705ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardReturn<void> Device::getHwAvSync(getHwAvSync_cb _hidl_cb) { 2715ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard int halHwAvSync; 2725ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); 2735ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard _hidl_cb(retval, halHwAvSync); 2745ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return Void(); 2755ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard} 2765ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#endif 27710548295023bee99108e418499aff09fe578211eMikhail Naganov 27872e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<Result> Device::setScreenState(bool turnedOn) { 27986685f56da0941027406d1ffba67bd4272faa526Mikhail Naganov return setParam(AudioParameter::keyScreenState, turnedOn); 28010548295023bee99108e418499aff09fe578211eMikhail Naganov} 28110548295023bee99108e418499aff09fe578211eMikhail Naganov 2825ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#ifdef AUDIO_HAL_VERSION_2_0 28382cb03632c15976838407c231fd85804de9bf84cKevin RocardReturn<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { 2845ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard getParametersImpl({}, keys, _hidl_cb); 28510548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 28610548295023bee99108e418499aff09fe578211eMikhail Naganov} 28710548295023bee99108e418499aff09fe578211eMikhail Naganov 28882cb03632c15976838407c231fd85804de9bf84cKevin RocardReturn<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) { 2895ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return setParametersImpl({} /* context */, parameters); 2905ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard} 2915ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#elif defined(AUDIO_HAL_VERSION_4_0) 2925ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardReturn<void> Device::getParameters(const hidl_vec<ParameterValue>& context, 2935ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { 2945ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard getParametersImpl(context, keys, _hidl_cb); 2955ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return Void(); 2965ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard} 2975ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardReturn<Result> Device::setParameters(const hidl_vec<ParameterValue>& context, 2985ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard const hidl_vec<ParameterValue>& parameters) { 2995ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return setParametersImpl(context, parameters); 30010548295023bee99108e418499aff09fe578211eMikhail Naganov} 3015ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#endif 30210548295023bee99108e418499aff09fe578211eMikhail Naganov 3035ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#ifdef AUDIO_HAL_VERSION_2_0 30472e50e2ef1480fc3d90f0d88c7e9e3595622e75cKevin RocardReturn<void> Device::debugDump(const hidl_handle& fd) { 3055ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return debug(fd, {}); 3065ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard} 3075ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#endif 3085ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard 3095ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardReturn<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) { 3103e6fe754f647db202a7a455adcf1ab5d686105d3Mikhail Naganov if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { 31110548295023bee99108e418499aff09fe578211eMikhail Naganov analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0])); 31210548295023bee99108e418499aff09fe578211eMikhail Naganov } 31310548295023bee99108e418499aff09fe578211eMikhail Naganov return Void(); 31410548295023bee99108e418499aff09fe578211eMikhail Naganov} 31510548295023bee99108e418499aff09fe578211eMikhail Naganov 3165ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#ifdef AUDIO_HAL_VERSION_4_0 3175ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardReturn<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) { 3181b09e2690922338773350723b60eaee656a7226cjiabin Result retval = Result::NOT_SUPPORTED; 3191b09e2690922338773350723b60eaee656a7226cjiabin size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT; 3201b09e2690922338773350723b60eaee656a7226cjiabin audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT]; 3211b09e2690922338773350723b60eaee656a7226cjiabin 3221b09e2690922338773350723b60eaee656a7226cjiabin hidl_vec<MicrophoneInfo> microphones; 3231b09e2690922338773350723b60eaee656a7226cjiabin if (mDevice->get_microphones != NULL && 3241b09e2690922338773350723b60eaee656a7226cjiabin mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) { 3251b09e2690922338773350723b60eaee656a7226cjiabin microphones.resize(actual_mics); 3261b09e2690922338773350723b60eaee656a7226cjiabin for (size_t i = 0; i < actual_mics; ++i) { 3271b09e2690922338773350723b60eaee656a7226cjiabin halToMicrophoneCharacteristics(µphones[i], mic_array[i]); 3281b09e2690922338773350723b60eaee656a7226cjiabin } 3291b09e2690922338773350723b60eaee656a7226cjiabin retval = Result::OK; 3301b09e2690922338773350723b60eaee656a7226cjiabin } 3311b09e2690922338773350723b60eaee656a7226cjiabin _hidl_cb(retval, microphones); 3325ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return Void(); 3335ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard} 3345ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard 3355ec293316e7ea1f768161695a113e50b0ea41d45Kevin RocardReturn<Result> Device::setConnectedState(const DeviceAddress& address, bool connected) { 3365ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard auto key = connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect; 3375ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard return setParam(key, address); 3385ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard} 3395ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard#endif 3405ec293316e7ea1f768161695a113e50b0ea41d45Kevin Rocard 34110548295023bee99108e418499aff09fe578211eMikhail Naganov} // namespace implementation 342e9e4e16564c2949960bf9dd3ab49c9dee2273f3cKevin Rocard} // namespace AUDIO_HAL_VERSION 34310548295023bee99108e418499aff09fe578211eMikhail Naganov} // namespace audio 34410548295023bee99108e418499aff09fe578211eMikhail Naganov} // namespace hardware 34510548295023bee99108e418499aff09fe578211eMikhail Naganov} // namespace android 346