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(&microphones[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