blob: be063abe862e8cfe21b52e2c620e122697d55a58 [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 Naganov247b5f92021-01-15 19:16:12 +000035#include "ParameterUtils.h"
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080036#include "StreamHalHidl.h"
37
Mikhail Naganov6718c392022-01-27 22:17:21 +000038using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
Kevin Rocard7a9f05a2018-11-28 16:52:25 -080039using ::android::hardware::audio::common::utils::EnumBitfield;
Mikhail Naganov6718c392022-01-27 22:17:21 +000040using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080041using ::android::hardware::hidl_string;
42using ::android::hardware::hidl_vec;
43
44namespace android {
45
Mikhail Naganov6718c392022-01-27 22:17:21 +000046using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
47using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080048
Andy Hung224f82f2022-03-22 00:00:49 -070049#define TIME_CHECK() auto timeCheck = \
50 mediautils::makeTimeCheckStatsForClassMethod(getClassName(), __func__)
51
Mikhail Naganov6718c392022-01-27 22:17:21 +000052DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
Mikhail Naganov288a3432022-03-25 00:29:56 +000053 : CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
Mikhail Naganov6718c392022-01-27 22:17:21 +000054}
Eric Laurentb82e6b72019-11-22 17:25:04 -080055
Mikhail Naganov6718c392022-01-27 22:17:21 +000056DeviceHalHidl::DeviceHalHidl(
57 const sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice>& device)
Mikhail Naganov288a3432022-03-25 00:29:56 +000058 : CoreConversionHelperHidl("DeviceHalHidl"),
Mikhail Naganov6718c392022-01-27 22:17:21 +000059#if MAJOR_VERSION <= 6 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
60 mDevice(device),
61#endif
62 mPrimaryDevice(device) {
63#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
64 auto getDeviceRet = mPrimaryDevice->getDevice();
65 if (getDeviceRet.isOk()) {
66 mDevice = getDeviceRet;
67 } else {
68 ALOGE("Call to IPrimaryDevice.getDevice has failed: %s",
69 getDeviceRet.description().c_str());
70 }
71#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080072}
73
74DeviceHalHidl::~DeviceHalHidl() {
75 if (mDevice != 0) {
Mikhail Naganov3355e442019-11-20 14:20:01 -080076#if MAJOR_VERSION <= 5
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080077 mDevice.clear();
78 hardware::IPCThreadState::self()->flushCommands();
Mikhail Naganov3355e442019-11-20 14:20:01 -080079#elif MAJOR_VERSION >= 6
80 mDevice->close();
81#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080082 }
83}
84
85status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
86 // Obsolete.
87 return INVALID_OPERATION;
88}
89
90status_t DeviceHalHidl::initCheck() {
Andy Hung224f82f2022-03-22 00:00:49 -070091 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080092 if (mDevice == 0) return NO_INIT;
93 return processReturn("initCheck", mDevice->initCheck());
94}
95
96status_t DeviceHalHidl::setVoiceVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -070097 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080098 if (mDevice == 0) return NO_INIT;
99 if (mPrimaryDevice == 0) return INVALID_OPERATION;
100 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
101}
102
103status_t DeviceHalHidl::setMasterVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700104 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800105 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800106 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800107}
108
109status_t DeviceHalHidl::getMasterVolume(float *volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700110 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800111 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800112 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800113 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800114 [&](Result r, float v) {
115 retval = r;
116 if (retval == Result::OK) {
117 *volume = v;
118 }
119 });
120 return processReturn("getMasterVolume", ret, retval);
121}
122
123status_t DeviceHalHidl::setMode(audio_mode_t mode) {
Andy Hung224f82f2022-03-22 00:00:49 -0700124 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800125 if (mDevice == 0) return NO_INIT;
126 if (mPrimaryDevice == 0) return INVALID_OPERATION;
127 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
128}
129
130status_t DeviceHalHidl::setMicMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700131 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800132 if (mDevice == 0) return NO_INIT;
133 return processReturn("setMicMute", mDevice->setMicMute(state));
134}
135
136status_t DeviceHalHidl::getMicMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700137 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800138 if (mDevice == 0) return NO_INIT;
139 Result retval;
140 Return<void> ret = mDevice->getMicMute(
141 [&](Result r, bool mute) {
142 retval = r;
143 if (retval == Result::OK) {
144 *state = mute;
145 }
146 });
147 return processReturn("getMicMute", ret, retval);
148}
149
150status_t DeviceHalHidl::setMasterMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700151 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800152 if (mDevice == 0) return NO_INIT;
153 return processReturn("setMasterMute", mDevice->setMasterMute(state));
154}
155
156status_t DeviceHalHidl::getMasterMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700157 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800158 if (mDevice == 0) return NO_INIT;
159 Result retval;
160 Return<void> ret = mDevice->getMasterMute(
161 [&](Result r, bool mute) {
162 retval = r;
163 if (retval == Result::OK) {
164 *state = mute;
165 }
166 });
167 return processReturn("getMasterMute", ret, retval);
168}
169
170status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
Andy Hung224f82f2022-03-22 00:00:49 -0700171 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800172 if (mDevice == 0) return NO_INIT;
173 hidl_vec<ParameterValue> hidlParams;
174 status_t status = parametersFromHal(kvPairs, &hidlParams);
175 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800176 // TODO: change the API so that context and kvPairs are separated
177 return processReturn("setParameters",
178 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800179}
180
181status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
Andy Hung224f82f2022-03-22 00:00:49 -0700182 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800183 values->clear();
184 if (mDevice == 0) return NO_INIT;
185 hidl_vec<hidl_string> hidlKeys;
186 status_t status = keysFromHal(keys, &hidlKeys);
187 if (status != OK) return status;
188 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800189 Return<void> ret = utils::getParameters(mDevice,
190 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800191 hidlKeys,
192 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
193 retval = r;
194 if (retval == Result::OK) {
195 parametersToHal(parameters, values);
196 }
197 });
198 return processReturn("getParameters", ret, retval);
199}
200
201status_t DeviceHalHidl::getInputBufferSize(
202 const struct audio_config *config, size_t *size) {
Andy Hung224f82f2022-03-22 00:00:49 -0700203 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800204 if (mDevice == 0) return NO_INIT;
205 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000206 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800207 Result retval;
208 Return<void> ret = mDevice->getInputBufferSize(
209 hidlConfig,
210 [&](Result r, uint64_t bufferSize) {
211 retval = r;
212 if (retval == Result::OK) {
213 *size = static_cast<size_t>(bufferSize);
214 }
215 });
216 return processReturn("getInputBufferSize", ret, retval);
217}
218
219status_t DeviceHalHidl::openOutputStream(
220 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700221 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800222 audio_output_flags_t flags,
223 struct audio_config *config,
224 const char *address,
225 sp<StreamOutHalInterface> *outStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700226 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800227 if (mDevice == 0) return NO_INIT;
228 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000229 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
230 status != OK) {
231 return status;
232 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800233 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000234 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
235 status != OK) {
236 return status;
237 }
Eric Laurente28c66d2022-01-21 13:40:41 +0100238
239#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1)
240 //TODO: b/193496180 use spatializer flag at audio HAL when available
241 if ((flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
242 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_SPATIALIZER);
243 flags = (audio_output_flags_t)
244 (flags | AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
245 }
246#endif
247
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000248 CoreUtils::AudioOutputFlags hidlFlags;
249 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
250 return status;
251 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800252 Result retval = Result::NOT_INITIALIZED;
Mikhail Naganov6718c392022-01-27 22:17:21 +0000253#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
254 Return<void> ret = mDevice->openOutputStream_7_1(
255#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800256 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000257#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000258 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800259#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800260 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700261#endif
Mikhail Naganov6718c392022-01-27 22:17:21 +0000262 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& result,
263 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800264 retval = r;
265 if (retval == Result::OK) {
266 *outStream = new StreamOutHalHidl(result);
267 }
268 HidlUtils::audioConfigToHal(suggestedConfig, config);
269 });
270 return processReturn("openOutputStream", ret, retval);
271}
272
273status_t DeviceHalHidl::openInputStream(
274 audio_io_handle_t handle,
275 audio_devices_t devices,
276 struct audio_config *config,
277 audio_input_flags_t flags,
278 const char *address,
279 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800280 audio_devices_t outputDevice,
281 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800282 sp<StreamInHalInterface> *inStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700283 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800284 if (mDevice == 0) return NO_INIT;
285 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000286 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
287 status != OK) {
288 return status;
289 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800290 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000291 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
292 status != OK) {
293 return status;
294 }
295 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100296#if MAJOR_VERSION <= 5
297 // Some flags were specific to framework and must not leak to the HAL.
298 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
299#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000300 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
301 return status;
302 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800303 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700304#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800305 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800306#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800307 // TODO: correctly propagate the tracks sources and volume
308 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000309 AudioSource hidlSource;
310 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
311 return status;
312 }
313 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700314#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800315#if MAJOR_VERSION < 5
316 (void)outputDevice;
317 (void)outputDeviceAddress;
318#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800319#if MAJOR_VERSION >= 7
320 (void)HidlUtils::audioChannelMaskFromHal(
321 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
322#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800323 if (outputDevice != AUDIO_DEVICE_NONE) {
324 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000325 if (status_t status = CoreUtils::deviceAddressFromHal(
326 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
327 return status;
328 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800329 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
330 }
331#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800332 Return<void> ret = mDevice->openInputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000333 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Mikhail Naganovaccbe8a2022-02-03 23:45:36 +0000334 [&](Result r,
335 const sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn>& result,
Mikhail Naganov6718c392022-01-27 22:17:21 +0000336 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800337 retval = r;
338 if (retval == Result::OK) {
339 *inStream = new StreamInHalHidl(result);
340 }
341 HidlUtils::audioConfigToHal(suggestedConfig, config);
342 });
343 return processReturn("openInputStream", ret, retval);
344}
345
346status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
Andy Hung224f82f2022-03-22 00:00:49 -0700347 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800348 if (mDevice == 0) return NO_INIT;
349 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
350}
351
352status_t DeviceHalHidl::createAudioPatch(
353 unsigned int num_sources,
354 const struct audio_port_config *sources,
355 unsigned int num_sinks,
356 const struct audio_port_config *sinks,
357 audio_patch_handle_t *patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700358 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800359 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700360 if (patch == nullptr) return BAD_VALUE;
361
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800362#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700363 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
364 status_t status = releaseAudioPatch(*patch);
365 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
366 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800367 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700368 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800369#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700370
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800371 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
372 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
373 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800374 Result retval = Result::OK;
375 Return<void> ret;
376 std::string methodName = "createAudioPatch";
377 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
378 ret = mDevice->createAudioPatch(
379 hidlSources, hidlSinks,
380 [&](Result r, AudioPatchHandle hidlPatch) {
381 retval = r;
382 if (retval == Result::OK) {
383 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
384 }
385 });
386 } else {
387#if MAJOR_VERSION >= 6
388 ret = mDevice->updateAudioPatch(
389 *patch,
390 hidlSources, hidlSinks,
391 [&](Result r, AudioPatchHandle hidlPatch) {
392 retval = r;
393 if (retval == Result::OK) {
394 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
395 }
396 });
397 methodName = "updateAudioPatch";
398#endif
399 }
400 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800401}
402
403status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700404 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800405 if (mDevice == 0) return NO_INIT;
406 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
407}
408
Mikhail Naganov720cc432021-03-24 20:42:49 -0700409template <typename HalPort>
410status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800411 if (mDevice == 0) return NO_INIT;
412 AudioPort hidlPort;
413 HidlUtils::audioPortFromHal(*port, &hidlPort);
414 Result retval;
415 Return<void> ret = mDevice->getAudioPort(
416 hidlPort,
417 [&](Result r, const AudioPort& p) {
418 retval = r;
419 if (retval == Result::OK) {
420 HidlUtils::audioPortToHal(p, port);
421 }
422 });
423 return processReturn("getAudioPort", ret, retval);
424}
425
Mikhail Naganov720cc432021-03-24 20:42:49 -0700426status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700427 TIME_CHECK();
Mikhail Naganov720cc432021-03-24 20:42:49 -0700428 return getAudioPortImpl(port);
429}
430
jiabinb4fed192020-09-22 14:45:40 -0700431status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700432 TIME_CHECK();
jiabinb4fed192020-09-22 14:45:40 -0700433#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700434 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700435#else
436 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700437 status_t result = NO_ERROR;
438 if (!audio_populate_audio_port(port, &audioPort)) {
439 ALOGE("Failed to populate legacy audio port from audio_port_v7");
440 result = BAD_VALUE;
441 }
442 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700443 if (status == NO_ERROR) {
444 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700445 } else {
446 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700447 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700448 return result;
jiabinb4fed192020-09-22 14:45:40 -0700449#endif
jiabinb4fed192020-09-22 14:45:40 -0700450}
451
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800452status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
Andy Hung224f82f2022-03-22 00:00:49 -0700453 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800454 if (mDevice == 0) return NO_INIT;
455 AudioPortConfig hidlConfig;
456 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
457 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
458}
459
Kevin Rocard070e7512018-05-22 09:29:13 -0700460#if MAJOR_VERSION == 2
461status_t DeviceHalHidl::getMicrophones(
Shunkai Yao51202502022-12-12 06:11:46 +0000462 std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
Kevin Rocard070e7512018-05-22 09:29:13 -0700463 if (mDevice == 0) return NO_INIT;
464 return INVALID_OPERATION;
465}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800466#elif MAJOR_VERSION >= 4
Shunkai Yao51202502022-12-12 06:11:46 +0000467status_t DeviceHalHidl::getMicrophones(
468 std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
Andy Hung224f82f2022-03-22 00:00:49 -0700469 TIME_CHECK();
jiabin9ff780e2018-03-19 18:19:52 -0700470 if (mDevice == 0) return NO_INIT;
471 Result retval;
472 Return<void> ret = mDevice->getMicrophones(
473 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
474 retval = r;
475 for (size_t k = 0; k < micArrayHal.size(); k++) {
476 audio_microphone_characteristic_t dst;
477 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000478 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
Shunkai Yao51202502022-12-12 06:11:46 +0000479 microphonesInfo->push_back(dst);
jiabin9ff780e2018-03-19 18:19:52 -0700480 }
481 });
482 return processReturn("getMicrophones", ret, retval);
483}
Kevin Rocard070e7512018-05-22 09:29:13 -0700484#endif
jiabin9ff780e2018-03-19 18:19:52 -0700485
Eric Laurentb82e6b72019-11-22 17:25:04 -0800486#if MAJOR_VERSION >= 6
487status_t DeviceHalHidl::addDeviceEffect(
488 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700489 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800490 if (mDevice == 0) return NO_INIT;
491 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000492 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800493}
494#else
495status_t DeviceHalHidl::addDeviceEffect(
496 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
497 return INVALID_OPERATION;
498}
499#endif
500
501#if MAJOR_VERSION >= 6
502status_t DeviceHalHidl::removeDeviceEffect(
503 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700504 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800505 if (mDevice == 0) return NO_INIT;
506 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000507 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800508}
509#else
510status_t DeviceHalHidl::removeDeviceEffect(
511 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
512 return INVALID_OPERATION;
513}
514#endif
515
Mikhail Naganov516d3982022-02-01 23:53:59 +0000516status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
Andy Hung224f82f2022-03-22 00:00:49 -0700517 TIME_CHECK();
Mikhail Naganov516d3982022-02-01 23:53:59 +0000518 if (mDevice == 0) return NO_INIT;
519#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
520 if (supportsSetConnectedState7_1) {
521 AudioPort hidlPort;
522 if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
523 return result;
524 }
525 Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
526 if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
527 return processReturn("setConnectedState_7_1", ret);
528 } else if (ret == Result::OK) {
529 return NO_ERROR;
530 }
531 supportsSetConnectedState7_1 = false;
532 }
533#endif
534 DeviceAddress hidlAddress;
535 if (status_t result = CoreUtils::deviceAddressFromHal(
536 port->ext.device.type, port->ext.device.address, &hidlAddress);
537 result != NO_ERROR) {
538 return result;
539 }
540 return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
541}
542
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800543error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
Andy Hung224f82f2022-03-22 00:00:49 -0700544 TIME_CHECK();
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800545 if (mDevice == 0) return NO_INIT;
546 audio_hw_sync_t value;
547 Result result;
548 Return<void> ret = mDevice->getHwAvSync([&value, &result](Result r, audio_hw_sync_t v) {
549 value = v;
550 result = r;
551 });
552 RETURN_IF_ERROR(processReturn("getHwAvSync", ret, result));
553 return value;
554}
555
Andy Hung61589a42021-06-16 09:37:53 -0700556status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
Andy Hung224f82f2022-03-22 00:00:49 -0700557 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800558 if (mDevice == 0) return NO_INIT;
559 native_handle_t* hidlHandle = native_handle_create(1, 0);
560 hidlHandle->data[0] = fd;
Andy Hung61589a42021-06-16 09:37:53 -0700561 hidl_vec<hidl_string> hidlArgs;
562 argsFromHal(args, &hidlArgs);
563 Return<void> ret = mDevice->debug(hidlHandle, hidlArgs);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800564 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700565
566 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
567 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
568 // when the remote binder thread removes the last refcount to the fd blocks in the
569 // kernel for binder activity. We send a Binder ping() command to unblock the thread
570 // and complete the fd close / release.
571 //
572 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
573 // EffectsFactoryHalHidl::dumpEffects().
574
575 (void)mDevice->ping(); // synchronous Binder call
576
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800577 return processReturn("dump", ret);
578}
579
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800580} // namespace android