blob: 4066f3ce2d8d32133932996396389abb3bd55082 [file] [log] [blame]
Kevin Rocard4bcd67f2018-02-28 14:33:38 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18
19#define LOG_TAG "DeviceHalHidl"
20//#define LOG_NDEBUG 0
21
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080022#include <cutils/native_handle.h>
Jiabin Huangebe64102021-09-07 20:01:07 +000023#include <cutils/properties.h>
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080024#include <hwbinder/IPCThreadState.h>
jiabindaf49952019-11-22 14:10:57 -080025#include <media/AudioContainers.h>
Andy Hung224f82f2022-03-22 00:00:49 -070026#include <mediautils/TimeCheck.h>
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080027#include <utils/Log.h>
28
Mikhail Naganov247b5f92021-01-15 19:16:12 +000029#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
30#include <HidlUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080031#include <common/all-versions/VersionUtils.h>
Mikhail Naganov247b5f92021-01-15 19:16:12 +000032#include <util/CoreUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080033
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080034#include "DeviceHalHidl.h"
Mikhail Naganov89c22e42023-06-14 15:49:59 -070035#include "EffectHalHidl.h"
Mikhail Naganov247b5f92021-01-15 19:16:12 +000036#include "ParameterUtils.h"
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080037#include "StreamHalHidl.h"
38
Mikhail Naganov6718c392022-01-27 22:17:21 +000039using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
Kevin Rocard7a9f05a2018-11-28 16:52:25 -080040using ::android::hardware::audio::common::utils::EnumBitfield;
Mikhail Naganov6718c392022-01-27 22:17:21 +000041using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080042using ::android::hardware::hidl_string;
43using ::android::hardware::hidl_vec;
44
45namespace android {
46
Mikhail Naganov6718c392022-01-27 22:17:21 +000047using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
48using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080049
Mikhail Naganov6718c392022-01-27 22:17:21 +000050DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
Mikhail Naganov288a3432022-03-25 00:29:56 +000051 : CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
Mikhail Naganov6718c392022-01-27 22:17:21 +000052}
Eric Laurentb82e6b72019-11-22 17:25:04 -080053
Mikhail Naganov6718c392022-01-27 22:17:21 +000054DeviceHalHidl::DeviceHalHidl(
55 const sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice>& device)
Mikhail Naganov288a3432022-03-25 00:29:56 +000056 : CoreConversionHelperHidl("DeviceHalHidl"),
Mikhail Naganov6718c392022-01-27 22:17:21 +000057#if MAJOR_VERSION <= 6 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
58 mDevice(device),
59#endif
60 mPrimaryDevice(device) {
61#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
62 auto getDeviceRet = mPrimaryDevice->getDevice();
63 if (getDeviceRet.isOk()) {
64 mDevice = getDeviceRet;
65 } else {
66 ALOGE("Call to IPrimaryDevice.getDevice has failed: %s",
67 getDeviceRet.description().c_str());
68 }
69#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080070}
71
72DeviceHalHidl::~DeviceHalHidl() {
73 if (mDevice != 0) {
Mikhail Naganov3355e442019-11-20 14:20:01 -080074#if MAJOR_VERSION <= 5
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080075 mDevice.clear();
76 hardware::IPCThreadState::self()->flushCommands();
Mikhail Naganov3355e442019-11-20 14:20:01 -080077#elif MAJOR_VERSION >= 6
78 mDevice->close();
79#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080080 }
81}
82
Mikhail Naganovf83b9742023-04-24 13:06:04 -070083status_t DeviceHalHidl::getAudioPorts(
84 std::vector<media::audio::common::AudioPort> *ports __unused) {
85 return INVALID_OPERATION;
86}
87
88status_t DeviceHalHidl::getAudioRoutes(std::vector<media::AudioRoute> *routes __unused) {
89 return INVALID_OPERATION;
90}
91
Mikhail Naganov1fba38c2023-05-03 17:45:36 -070092status_t DeviceHalHidl::getSupportedModes(
93 std::vector<media::audio::common::AudioMode> *modes __unused) {
94 return INVALID_OPERATION;
95}
96
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080097status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
98 // Obsolete.
99 return INVALID_OPERATION;
100}
101
102status_t DeviceHalHidl::initCheck() {
Andy Hung224f82f2022-03-22 00:00:49 -0700103 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800104 if (mDevice == 0) return NO_INIT;
105 return processReturn("initCheck", mDevice->initCheck());
106}
107
108status_t DeviceHalHidl::setVoiceVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700109 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800110 if (mDevice == 0) return NO_INIT;
111 if (mPrimaryDevice == 0) return INVALID_OPERATION;
112 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
113}
114
115status_t DeviceHalHidl::setMasterVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700116 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800117 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800118 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800119}
120
121status_t DeviceHalHidl::getMasterVolume(float *volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700122 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800123 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800124 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800125 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800126 [&](Result r, float v) {
127 retval = r;
128 if (retval == Result::OK) {
129 *volume = v;
130 }
131 });
132 return processReturn("getMasterVolume", ret, retval);
133}
134
135status_t DeviceHalHidl::setMode(audio_mode_t mode) {
Andy Hung224f82f2022-03-22 00:00:49 -0700136 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800137 if (mDevice == 0) return NO_INIT;
138 if (mPrimaryDevice == 0) return INVALID_OPERATION;
139 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
140}
141
142status_t DeviceHalHidl::setMicMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700143 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800144 if (mDevice == 0) return NO_INIT;
145 return processReturn("setMicMute", mDevice->setMicMute(state));
146}
147
148status_t DeviceHalHidl::getMicMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700149 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800150 if (mDevice == 0) return NO_INIT;
151 Result retval;
152 Return<void> ret = mDevice->getMicMute(
153 [&](Result r, bool mute) {
154 retval = r;
155 if (retval == Result::OK) {
156 *state = mute;
157 }
158 });
159 return processReturn("getMicMute", ret, retval);
160}
161
162status_t DeviceHalHidl::setMasterMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700163 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800164 if (mDevice == 0) return NO_INIT;
165 return processReturn("setMasterMute", mDevice->setMasterMute(state));
166}
167
168status_t DeviceHalHidl::getMasterMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700169 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800170 if (mDevice == 0) return NO_INIT;
171 Result retval;
172 Return<void> ret = mDevice->getMasterMute(
173 [&](Result r, bool mute) {
174 retval = r;
175 if (retval == Result::OK) {
176 *state = mute;
177 }
178 });
179 return processReturn("getMasterMute", ret, retval);
180}
181
182status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
Andy Hung224f82f2022-03-22 00:00:49 -0700183 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800184 if (mDevice == 0) return NO_INIT;
185 hidl_vec<ParameterValue> hidlParams;
186 status_t status = parametersFromHal(kvPairs, &hidlParams);
187 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800188 // TODO: change the API so that context and kvPairs are separated
189 return processReturn("setParameters",
190 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800191}
192
193status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
Andy Hung224f82f2022-03-22 00:00:49 -0700194 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800195 values->clear();
196 if (mDevice == 0) return NO_INIT;
197 hidl_vec<hidl_string> hidlKeys;
198 status_t status = keysFromHal(keys, &hidlKeys);
199 if (status != OK) return status;
200 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800201 Return<void> ret = utils::getParameters(mDevice,
202 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800203 hidlKeys,
204 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
205 retval = r;
206 if (retval == Result::OK) {
207 parametersToHal(parameters, values);
208 }
209 });
210 return processReturn("getParameters", ret, retval);
211}
212
213status_t DeviceHalHidl::getInputBufferSize(
214 const struct audio_config *config, size_t *size) {
Andy Hung224f82f2022-03-22 00:00:49 -0700215 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800216 if (mDevice == 0) return NO_INIT;
217 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000218 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800219 Result retval;
220 Return<void> ret = mDevice->getInputBufferSize(
221 hidlConfig,
222 [&](Result r, uint64_t bufferSize) {
223 retval = r;
224 if (retval == Result::OK) {
225 *size = static_cast<size_t>(bufferSize);
226 }
227 });
228 return processReturn("getInputBufferSize", ret, retval);
229}
230
231status_t DeviceHalHidl::openOutputStream(
232 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700233 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800234 audio_output_flags_t flags,
235 struct audio_config *config,
236 const char *address,
237 sp<StreamOutHalInterface> *outStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700238 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800239 if (mDevice == 0) return NO_INIT;
240 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000241 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
242 status != OK) {
243 return status;
244 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800245 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000246 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
247 status != OK) {
248 return status;
249 }
Eric Laurente28c66d2022-01-21 13:40:41 +0100250
251#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1)
252 //TODO: b/193496180 use spatializer flag at audio HAL when available
253 if ((flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
254 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_SPATIALIZER);
255 flags = (audio_output_flags_t)
256 (flags | AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
257 }
258#endif
259
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000260 CoreUtils::AudioOutputFlags hidlFlags;
261 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
262 return status;
263 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800264 Result retval = Result::NOT_INITIALIZED;
Mikhail Naganov6718c392022-01-27 22:17:21 +0000265#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
266 Return<void> ret = mDevice->openOutputStream_7_1(
267#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800268 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000269#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000270 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800271#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800272 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700273#endif
Mikhail Naganov6718c392022-01-27 22:17:21 +0000274 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& result,
275 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800276 retval = r;
277 if (retval == Result::OK) {
278 *outStream = new StreamOutHalHidl(result);
279 }
280 HidlUtils::audioConfigToHal(suggestedConfig, config);
281 });
282 return processReturn("openOutputStream", ret, retval);
283}
284
285status_t DeviceHalHidl::openInputStream(
286 audio_io_handle_t handle,
287 audio_devices_t devices,
288 struct audio_config *config,
289 audio_input_flags_t flags,
290 const char *address,
291 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800292 audio_devices_t outputDevice,
293 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800294 sp<StreamInHalInterface> *inStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700295 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800296 if (mDevice == 0) return NO_INIT;
297 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000298 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
299 status != OK) {
300 return status;
301 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800302 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000303 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
304 status != OK) {
305 return status;
306 }
307 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100308#if MAJOR_VERSION <= 5
309 // Some flags were specific to framework and must not leak to the HAL.
310 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
311#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000312 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
313 return status;
314 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800315 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700316#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800317 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800318#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800319 // TODO: correctly propagate the tracks sources and volume
320 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000321 AudioSource hidlSource;
322 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
323 return status;
324 }
325 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700326#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800327#if MAJOR_VERSION < 5
328 (void)outputDevice;
329 (void)outputDeviceAddress;
330#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800331#if MAJOR_VERSION >= 7
332 (void)HidlUtils::audioChannelMaskFromHal(
333 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
334#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800335 if (outputDevice != AUDIO_DEVICE_NONE) {
336 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000337 if (status_t status = CoreUtils::deviceAddressFromHal(
338 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
339 return status;
340 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800341 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
342 }
343#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800344 Return<void> ret = mDevice->openInputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000345 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Mikhail Naganovaccbe8a2022-02-03 23:45:36 +0000346 [&](Result r,
347 const sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn>& result,
Mikhail Naganov6718c392022-01-27 22:17:21 +0000348 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800349 retval = r;
350 if (retval == Result::OK) {
351 *inStream = new StreamInHalHidl(result);
352 }
353 HidlUtils::audioConfigToHal(suggestedConfig, config);
354 });
355 return processReturn("openInputStream", ret, retval);
356}
357
358status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
Andy Hung224f82f2022-03-22 00:00:49 -0700359 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800360 if (mDevice == 0) return NO_INIT;
361 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
362}
363
364status_t DeviceHalHidl::createAudioPatch(
365 unsigned int num_sources,
366 const struct audio_port_config *sources,
367 unsigned int num_sinks,
368 const struct audio_port_config *sinks,
369 audio_patch_handle_t *patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700370 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800371 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700372 if (patch == nullptr) return BAD_VALUE;
373
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800374#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700375 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
376 status_t status = releaseAudioPatch(*patch);
377 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
378 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800379 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700380 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800381#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700382
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800383 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
384 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
385 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800386 Result retval = Result::OK;
387 Return<void> ret;
388 std::string methodName = "createAudioPatch";
389 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
390 ret = mDevice->createAudioPatch(
391 hidlSources, hidlSinks,
392 [&](Result r, AudioPatchHandle hidlPatch) {
393 retval = r;
394 if (retval == Result::OK) {
395 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
396 }
397 });
398 } else {
399#if MAJOR_VERSION >= 6
400 ret = mDevice->updateAudioPatch(
401 *patch,
402 hidlSources, hidlSinks,
403 [&](Result r, AudioPatchHandle hidlPatch) {
404 retval = r;
405 if (retval == Result::OK) {
406 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
407 }
408 });
409 methodName = "updateAudioPatch";
410#endif
411 }
412 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800413}
414
415status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700416 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800417 if (mDevice == 0) return NO_INIT;
418 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
419}
420
Mikhail Naganov720cc432021-03-24 20:42:49 -0700421template <typename HalPort>
422status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Mikhail Naganovf83b9742023-04-24 13:06:04 -0700423 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800424 if (mDevice == 0) return NO_INIT;
425 AudioPort hidlPort;
426 HidlUtils::audioPortFromHal(*port, &hidlPort);
427 Result retval;
428 Return<void> ret = mDevice->getAudioPort(
429 hidlPort,
430 [&](Result r, const AudioPort& p) {
431 retval = r;
432 if (retval == Result::OK) {
433 HidlUtils::audioPortToHal(p, port);
434 }
435 });
436 return processReturn("getAudioPort", ret, retval);
437}
438
Mikhail Naganov720cc432021-03-24 20:42:49 -0700439status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700440 TIME_CHECK();
Mikhail Naganov720cc432021-03-24 20:42:49 -0700441 return getAudioPortImpl(port);
442}
443
jiabinb4fed192020-09-22 14:45:40 -0700444status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700445 TIME_CHECK();
jiabinb4fed192020-09-22 14:45:40 -0700446#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700447 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700448#else
449 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700450 status_t result = NO_ERROR;
451 if (!audio_populate_audio_port(port, &audioPort)) {
452 ALOGE("Failed to populate legacy audio port from audio_port_v7");
453 result = BAD_VALUE;
454 }
455 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700456 if (status == NO_ERROR) {
457 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700458 } else {
459 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700460 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700461 return result;
jiabinb4fed192020-09-22 14:45:40 -0700462#endif
jiabinb4fed192020-09-22 14:45:40 -0700463}
464
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800465status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
Mikhail Naganovf83b9742023-04-24 13:06:04 -0700466 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPortConfig;
Andy Hung224f82f2022-03-22 00:00:49 -0700467 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800468 if (mDevice == 0) return NO_INIT;
469 AudioPortConfig hidlConfig;
470 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
471 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
472}
473
Kevin Rocard070e7512018-05-22 09:29:13 -0700474#if MAJOR_VERSION == 2
475status_t DeviceHalHidl::getMicrophones(
Shunkai Yao51202502022-12-12 06:11:46 +0000476 std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
Kevin Rocard070e7512018-05-22 09:29:13 -0700477 if (mDevice == 0) return NO_INIT;
478 return INVALID_OPERATION;
479}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800480#elif MAJOR_VERSION >= 4
Shunkai Yao51202502022-12-12 06:11:46 +0000481status_t DeviceHalHidl::getMicrophones(
482 std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
Andy Hung224f82f2022-03-22 00:00:49 -0700483 TIME_CHECK();
jiabin9ff780e2018-03-19 18:19:52 -0700484 if (mDevice == 0) return NO_INIT;
485 Result retval;
486 Return<void> ret = mDevice->getMicrophones(
487 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
488 retval = r;
489 for (size_t k = 0; k < micArrayHal.size(); k++) {
490 audio_microphone_characteristic_t dst;
491 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000492 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
Shunkai Yao51202502022-12-12 06:11:46 +0000493 microphonesInfo->push_back(dst);
jiabin9ff780e2018-03-19 18:19:52 -0700494 }
495 });
496 return processReturn("getMicrophones", ret, retval);
497}
Kevin Rocard070e7512018-05-22 09:29:13 -0700498#endif
jiabin9ff780e2018-03-19 18:19:52 -0700499
Eric Laurentb82e6b72019-11-22 17:25:04 -0800500#if MAJOR_VERSION >= 6
501status_t DeviceHalHidl::addDeviceEffect(
502 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700503 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800504 if (mDevice == 0) return NO_INIT;
Mikhail Naganov89c22e42023-06-14 15:49:59 -0700505 auto hidlEffect = sp<effect::EffectHalHidl>::cast(effect);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800506 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
Mikhail Naganov89c22e42023-06-14 15:49:59 -0700507 static_cast<AudioPortHandle>(device), hidlEffect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800508}
509#else
510status_t DeviceHalHidl::addDeviceEffect(
511 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
512 return INVALID_OPERATION;
513}
514#endif
515
516#if MAJOR_VERSION >= 6
517status_t DeviceHalHidl::removeDeviceEffect(
518 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700519 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800520 if (mDevice == 0) return NO_INIT;
Mikhail Naganov89c22e42023-06-14 15:49:59 -0700521 auto hidlEffect = sp<effect::EffectHalHidl>::cast(effect);
Eric Laurentb82e6b72019-11-22 17:25:04 -0800522 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
Mikhail Naganov89c22e42023-06-14 15:49:59 -0700523 static_cast<AudioPortHandle>(device), hidlEffect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800524}
525#else
526status_t DeviceHalHidl::removeDeviceEffect(
527 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
528 return INVALID_OPERATION;
529}
530#endif
531
jiabin872de702023-04-27 22:04:31 +0000532status_t DeviceHalHidl::prepareToDisconnectExternalDevice(const struct audio_port_v7* port) {
533 // For HIDL HAL, there is not API to call notify the HAL to prepare for device connected
534 // state changed. Call `setConnectedState` directly.
535 const status_t status = setConnectedState(port, false /*connected*/);
536 if (status == NO_ERROR) {
537 // Cache the port id so that it won't disconnect twice.
538 mDeviceDisconnectionNotified.insert(port->id);
539 }
540 return status;
541}
542
Mikhail Naganov516d3982022-02-01 23:53:59 +0000543status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
Mikhail Naganovf83b9742023-04-24 13:06:04 -0700544 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
Andy Hung224f82f2022-03-22 00:00:49 -0700545 TIME_CHECK();
Mikhail Naganov516d3982022-02-01 23:53:59 +0000546 if (mDevice == 0) return NO_INIT;
jiabin872de702023-04-27 22:04:31 +0000547 if (!connected && mDeviceDisconnectionNotified.erase(port->id) > 0) {
548 // For device disconnection, APM will first call `prepareToDisconnectExternalDevice` and
549 // then call `setConnectedState`. However, in HIDL HAL, there is no API for
550 // `prepareToDisconnectExternalDevice`. In that case, HIDL HAL will call `setConnectedState`
551 // when calling `prepareToDisconnectExternalDevice`. Do not call to the HAL if previous
552 // call is successful. Also remove the cache here to avoid a large cache after a long run.
553 return NO_ERROR;
554 }
Mikhail Naganov516d3982022-02-01 23:53:59 +0000555#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
556 if (supportsSetConnectedState7_1) {
557 AudioPort hidlPort;
558 if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
559 return result;
560 }
561 Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
562 if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
563 return processReturn("setConnectedState_7_1", ret);
564 } else if (ret == Result::OK) {
565 return NO_ERROR;
566 }
567 supportsSetConnectedState7_1 = false;
568 }
569#endif
570 DeviceAddress hidlAddress;
571 if (status_t result = CoreUtils::deviceAddressFromHal(
572 port->ext.device.type, port->ext.device.address, &hidlAddress);
573 result != NO_ERROR) {
574 return result;
575 }
576 return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
577}
578
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800579error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
Andy Hung224f82f2022-03-22 00:00:49 -0700580 TIME_CHECK();
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800581 if (mDevice == 0) return NO_INIT;
582 audio_hw_sync_t value;
583 Result result;
584 Return<void> ret = mDevice->getHwAvSync([&value, &result](Result r, audio_hw_sync_t v) {
585 value = v;
586 result = r;
587 });
588 RETURN_IF_ERROR(processReturn("getHwAvSync", ret, result));
589 return value;
590}
591
Andy Hung61589a42021-06-16 09:37:53 -0700592status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
Andy Hung224f82f2022-03-22 00:00:49 -0700593 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800594 if (mDevice == 0) return NO_INIT;
595 native_handle_t* hidlHandle = native_handle_create(1, 0);
596 hidlHandle->data[0] = fd;
Andy Hung61589a42021-06-16 09:37:53 -0700597 hidl_vec<hidl_string> hidlArgs;
598 argsFromHal(args, &hidlArgs);
599 Return<void> ret = mDevice->debug(hidlHandle, hidlArgs);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800600 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700601
602 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
603 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
604 // when the remote binder thread removes the last refcount to the fd blocks in the
605 // kernel for binder activity. We send a Binder ping() command to unblock the thread
606 // and complete the fd close / release.
607 //
608 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
609 // EffectsFactoryHalHidl::dumpEffects().
610
611 (void)mDevice->ping(); // synchronous Binder call
612
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800613 return processReturn("dump", ret);
614}
615
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800616} // namespace android