1f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov/*
2f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * Copyright (C) 2016 The Android Open Source Project
3f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov *
4f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License");
5f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * you may not use this file except in compliance with the License.
6f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * You may obtain a copy of the License at
7f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov *
8f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov *      http://www.apache.org/licenses/LICENSE-2.0
9f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov *
10f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * Unless required by applicable law or agreed to in writing, software
11f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS,
12f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * See the License for the specific language governing permissions and
14f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov * limitations under the License.
15f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov */
16f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
17f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <stdio.h>
18f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
19f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#define LOG_TAG "DeviceHalHidl"
20f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov//#define LOG_NDEBUG 0
21f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
22f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <android/hardware/audio/2.0/IPrimaryDevice.h>
23f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <cutils/native_handle.h>
2423feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov#include <hwbinder/IPCThreadState.h>
25f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include <utils/Log.h>
26f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
27f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include "DeviceHalHidl.h"
28f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include "HidlUtils.h"
29f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov#include "StreamHalHidl.h"
30f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
31f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioConfig;
32f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioDevice;
33f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioInputFlag;
34f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioOutputFlag;
35f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioPatchHandle;
36f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioPort;
37f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioPortConfig;
38f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioMode;
39f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioSource;
40f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::V2_0::DeviceAddress;
41f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::V2_0::IPrimaryDevice;
42f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::V2_0::ParameterValue;
43f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::audio::V2_0::Result;
44f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::hidl_string;
45f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovusing ::android::hardware::hidl_vec;
46f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
47f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovnamespace android {
48f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
49f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovnamespace {
50f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
51f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t deviceAddressFromHal(
52f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_devices_t device, const char* halAddress, DeviceAddress* address) {
53f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    address->device = AudioDevice(device);
542c37fd3a0ab8ad01bd21af0f1a1efbc240a2c0bdEric Laurent
552c37fd3a0ab8ad01bd21af0f1a1efbc240a2c0bdEric Laurent    if (address == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
562c37fd3a0ab8ad01bd21af0f1a1efbc240a2c0bdEric Laurent        return OK;
572c37fd3a0ab8ad01bd21af0f1a1efbc240a2c0bdEric Laurent    }
58f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
59f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
60f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
61f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
62f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        int status = sscanf(halAddress,
63f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
64f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
65f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
66f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        return status == 6 ? OK : BAD_VALUE;
67f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
68f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
69f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        int status = sscanf(halAddress,
70f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                "%hhu.%hhu.%hhu.%hhu",
71f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                &address->address.ipv4[0], &address->address.ipv4[1],
72f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                &address->address.ipv4[2], &address->address.ipv4[3]);
73f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        return status == 4 ? OK : BAD_VALUE;
74f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
75f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
76f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        int status = sscanf(halAddress,
77f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                "card=%d;device=%d",
78f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                &address->address.alsa.card, &address->address.alsa.device);
79f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        return status == 2 ? OK : BAD_VALUE;
80f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
81f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
82f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        if (halAddress != NULL) {
83f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            address->busAddress = halAddress;
84f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            return OK;
85f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        }
86f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        return BAD_VALUE;
87f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
88f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
89f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        if (halAddress != NULL) {
90f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            address->rSubmixAddress = halAddress;
91f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            return OK;
92f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        }
93f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        return BAD_VALUE;
94f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    }
95f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return OK;
96f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
97f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
98f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}  // namespace
99f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
100f558e0218d2677a813c9c600886f673894eec927Mikhail NaganovDeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
1019063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov        : ConversionHelperHidl("Device"), mDevice(device),
1029063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov          mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
103f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
104f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
105f558e0218d2677a813c9c600886f673894eec927Mikhail NaganovDeviceHalHidl::~DeviceHalHidl() {
10623feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov    if (mDevice != 0) {
10723feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov        mDevice.clear();
10823feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov        hardware::IPCThreadState::self()->flushCommands();
10923feba2593973e8ab251db8b63d8c2e228acbd51Mikhail Naganov    }
110f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
111f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
112f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
113f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    // Obsolete.
114f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return INVALID_OPERATION;
115f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
116f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
117f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::initCheck() {
118f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
119f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("initCheck", mDevice->initCheck());
120f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
121f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
122f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::setVoiceVolume(float volume) {
123f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
1249063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    if (mPrimaryDevice == 0) return INVALID_OPERATION;
1259063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
126f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
127f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
128f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::setMasterVolume(float volume) {
129f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
1309063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    if (mPrimaryDevice == 0) return INVALID_OPERATION;
1319063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    return processReturn("setMasterVolume", mPrimaryDevice->setMasterVolume(volume));
132f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
133f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
134f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::getMasterVolume(float *volume) {
135f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
1369063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    if (mPrimaryDevice == 0) return INVALID_OPERATION;
137f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval;
1389063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    Return<void> ret = mPrimaryDevice->getMasterVolume(
139f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, float v) {
140f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
141f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
142f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    *volume = v;
143f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
144f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
145f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("getMasterVolume", ret, retval);
146f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
147f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
148f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::setMode(audio_mode_t mode) {
149f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
1509063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    if (mPrimaryDevice == 0) return INVALID_OPERATION;
1519063fa7966a6d531595d8ada46d7667c569fc308Mikhail Naganov    return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
152f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
153f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
154f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::setMicMute(bool state) {
155f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
156f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("setMicMute", mDevice->setMicMute(state));
157f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
158f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
159f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::getMicMute(bool *state) {
160f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
161f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval;
162f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->getMicMute(
163f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, bool mute) {
164f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
165f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
166f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    *state = mute;
167f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
168f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
169f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("getMicMute", ret, retval);
170f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
171f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
172f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::setMasterMute(bool state) {
173f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
174f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("setMasterMute", mDevice->setMasterMute(state));
175f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
176f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
177f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::getMasterMute(bool *state) {
178f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
179f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval;
180f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->getMasterMute(
181f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, bool mute) {
182f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
183f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
184f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    *state = mute;
185f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
186f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
187f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("getMasterMute", ret, retval);
188f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
189f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
190f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::setParameters(const String8& kvPairs) {
191f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
192f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    hidl_vec<ParameterValue> hidlParams;
193f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    status_t status = parametersFromHal(kvPairs, &hidlParams);
194f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (status != OK) return status;
195f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("setParameters", mDevice->setParameters(hidlParams));
196f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
197f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
198f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
199f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    values->clear();
200f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
201f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    hidl_vec<hidl_string> hidlKeys;
202f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    status_t status = keysFromHal(keys, &hidlKeys);
203f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (status != OK) return status;
204f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval;
205f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->getParameters(
206f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlKeys,
207f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, const hidl_vec<ParameterValue>& parameters) {
208f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
209f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
210f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    parametersToHal(parameters, values);
211f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
212f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
213f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("getParameters", ret, retval);
214f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
215f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
216f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::getInputBufferSize(
217f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        const struct audio_config *config, size_t *size) {
218f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
219f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    AudioConfig hidlConfig;
220f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
221f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval;
222f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->getInputBufferSize(
223f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlConfig,
224f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, uint64_t bufferSize) {
225f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
226f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
227f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    *size = static_cast<size_t>(bufferSize);
228f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
229f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
230f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("getInputBufferSize", ret, retval);
231f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
232f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
233f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::openOutputStream(
234f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_io_handle_t handle,
235f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_devices_t devices,
236f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_output_flags_t flags,
237f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        struct audio_config *config,
238f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        const char *address,
239f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        sp<StreamOutHalInterface> *outStream) {
240f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
241f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    DeviceAddress hidlDevice;
242f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
243f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (status != OK) return status;
244f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    AudioConfig hidlConfig;
245f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
246f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval = Result::NOT_INITIALIZED;
247f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->openOutputStream(
248f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            handle,
249f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlDevice,
250f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlConfig,
251f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            AudioOutputFlag(flags),
252f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
253f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
254f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
255f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    *outStream = new StreamOutHalHidl(result);
256f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
257f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                HidlUtils::audioConfigToHal(suggestedConfig, config);
258f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
259f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("openOutputStream", ret, retval);
260f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
261f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
262f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::openInputStream(
263f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_io_handle_t handle,
264f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_devices_t devices,
265f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        struct audio_config *config,
266f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_input_flags_t flags,
267f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        const char *address,
268f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_source_t source,
269f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        sp<StreamInHalInterface> *inStream) {
270f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
271f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    DeviceAddress hidlDevice;
272f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
273f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (status != OK) return status;
274f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    AudioConfig hidlConfig;
275f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    HidlUtils::audioConfigFromHal(*config, &hidlConfig);
276f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval = Result::NOT_INITIALIZED;
277f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->openInputStream(
278f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            handle,
279f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlDevice,
280f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlConfig,
281f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            AudioInputFlag(flags),
282f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            AudioSource(source),
283f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
284f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
285f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
286f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    *inStream = new StreamInHalHidl(result);
287f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
288f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                HidlUtils::audioConfigToHal(suggestedConfig, config);
289f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
290f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("openInputStream", ret, retval);
291f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
292f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
293f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
294f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
295f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
296f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
297f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
298f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::createAudioPatch(
299f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        unsigned int num_sources,
300f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        const struct audio_port_config *sources,
301f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        unsigned int num_sinks,
302f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        const struct audio_port_config *sinks,
303f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov        audio_patch_handle_t *patch) {
304f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
305f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
306f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
307f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
308f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval;
309f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->createAudioPatch(
310f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlSources, hidlSinks,
311f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, AudioPatchHandle hidlPatch) {
312f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
313f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
314f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    *patch = static_cast<audio_patch_handle_t>(hidlPatch);
315f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
316f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
317f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("createAudioPatch", ret, retval);
318f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
319f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
320f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
321f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
322f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
323f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
324f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
325f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
326f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
327f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    AudioPort hidlPort;
328f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    HidlUtils::audioPortFromHal(*port, &hidlPort);
329f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Result retval;
330f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->getAudioPort(
331f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            hidlPort,
332f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            [&](Result r, const AudioPort& p) {
333f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                retval = r;
334f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                if (retval == Result::OK) {
335f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                    HidlUtils::audioPortToHal(p, port);
336f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov                }
337f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov            });
338f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("getAudioPort", ret, retval);
339f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
340f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
341f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
342f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
343f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    AudioPortConfig hidlConfig;
344f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
345f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
346f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
347f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
348f558e0218d2677a813c9c600886f673894eec927Mikhail Naganovstatus_t DeviceHalHidl::dump(int fd) {
349f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    if (mDevice == 0) return NO_INIT;
350f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    native_handle_t* hidlHandle = native_handle_create(1, 0);
351f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    hidlHandle->data[0] = fd;
352f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    Return<void> ret = mDevice->debugDump(hidlHandle);
353f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    native_handle_delete(hidlHandle);
354f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov    return processReturn("dump", ret);
355f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov}
356f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov
357f558e0218d2677a813c9c600886f673894eec927Mikhail Naganov} // namespace android
358