blob: 12acebd44ae164356608cf4b6cf9ba8eb76a4dee [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
Mikhail Naganov6718c392022-01-27 22:17:21 +000049DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
Mikhail Naganov288a3432022-03-25 00:29:56 +000050 : CoreConversionHelperHidl("DeviceHalHidl"), mDevice(device) {
Mikhail Naganov6718c392022-01-27 22:17:21 +000051}
Eric Laurentb82e6b72019-11-22 17:25:04 -080052
Mikhail Naganov6718c392022-01-27 22:17:21 +000053DeviceHalHidl::DeviceHalHidl(
54 const sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice>& device)
Mikhail Naganov288a3432022-03-25 00:29:56 +000055 : CoreConversionHelperHidl("DeviceHalHidl"),
Mikhail Naganov6718c392022-01-27 22:17:21 +000056#if MAJOR_VERSION <= 6 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
57 mDevice(device),
58#endif
59 mPrimaryDevice(device) {
60#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
61 auto getDeviceRet = mPrimaryDevice->getDevice();
62 if (getDeviceRet.isOk()) {
63 mDevice = getDeviceRet;
64 } else {
65 ALOGE("Call to IPrimaryDevice.getDevice has failed: %s",
66 getDeviceRet.description().c_str());
67 }
68#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080069}
70
71DeviceHalHidl::~DeviceHalHidl() {
72 if (mDevice != 0) {
Mikhail Naganov3355e442019-11-20 14:20:01 -080073#if MAJOR_VERSION <= 5
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080074 mDevice.clear();
75 hardware::IPCThreadState::self()->flushCommands();
Mikhail Naganov3355e442019-11-20 14:20:01 -080076#elif MAJOR_VERSION >= 6
77 mDevice->close();
78#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080079 }
80}
81
82status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
83 // Obsolete.
84 return INVALID_OPERATION;
85}
86
87status_t DeviceHalHidl::initCheck() {
Andy Hung224f82f2022-03-22 00:00:49 -070088 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080089 if (mDevice == 0) return NO_INIT;
90 return processReturn("initCheck", mDevice->initCheck());
91}
92
93status_t DeviceHalHidl::setVoiceVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -070094 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080095 if (mDevice == 0) return NO_INIT;
96 if (mPrimaryDevice == 0) return INVALID_OPERATION;
97 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
98}
99
100status_t DeviceHalHidl::setMasterVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700101 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800102 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800103 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800104}
105
106status_t DeviceHalHidl::getMasterVolume(float *volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700107 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800108 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800109 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800110 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800111 [&](Result r, float v) {
112 retval = r;
113 if (retval == Result::OK) {
114 *volume = v;
115 }
116 });
117 return processReturn("getMasterVolume", ret, retval);
118}
119
120status_t DeviceHalHidl::setMode(audio_mode_t mode) {
Andy Hung224f82f2022-03-22 00:00:49 -0700121 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800122 if (mDevice == 0) return NO_INIT;
123 if (mPrimaryDevice == 0) return INVALID_OPERATION;
124 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
125}
126
127status_t DeviceHalHidl::setMicMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700128 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800129 if (mDevice == 0) return NO_INIT;
130 return processReturn("setMicMute", mDevice->setMicMute(state));
131}
132
133status_t DeviceHalHidl::getMicMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700134 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800135 if (mDevice == 0) return NO_INIT;
136 Result retval;
137 Return<void> ret = mDevice->getMicMute(
138 [&](Result r, bool mute) {
139 retval = r;
140 if (retval == Result::OK) {
141 *state = mute;
142 }
143 });
144 return processReturn("getMicMute", ret, retval);
145}
146
147status_t DeviceHalHidl::setMasterMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700148 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800149 if (mDevice == 0) return NO_INIT;
150 return processReturn("setMasterMute", mDevice->setMasterMute(state));
151}
152
153status_t DeviceHalHidl::getMasterMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700154 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800155 if (mDevice == 0) return NO_INIT;
156 Result retval;
157 Return<void> ret = mDevice->getMasterMute(
158 [&](Result r, bool mute) {
159 retval = r;
160 if (retval == Result::OK) {
161 *state = mute;
162 }
163 });
164 return processReturn("getMasterMute", ret, retval);
165}
166
167status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
Andy Hung224f82f2022-03-22 00:00:49 -0700168 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800169 if (mDevice == 0) return NO_INIT;
170 hidl_vec<ParameterValue> hidlParams;
171 status_t status = parametersFromHal(kvPairs, &hidlParams);
172 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800173 // TODO: change the API so that context and kvPairs are separated
174 return processReturn("setParameters",
175 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800176}
177
178status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
Andy Hung224f82f2022-03-22 00:00:49 -0700179 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800180 values->clear();
181 if (mDevice == 0) return NO_INIT;
182 hidl_vec<hidl_string> hidlKeys;
183 status_t status = keysFromHal(keys, &hidlKeys);
184 if (status != OK) return status;
185 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800186 Return<void> ret = utils::getParameters(mDevice,
187 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800188 hidlKeys,
189 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
190 retval = r;
191 if (retval == Result::OK) {
192 parametersToHal(parameters, values);
193 }
194 });
195 return processReturn("getParameters", ret, retval);
196}
197
198status_t DeviceHalHidl::getInputBufferSize(
199 const struct audio_config *config, size_t *size) {
Andy Hung224f82f2022-03-22 00:00:49 -0700200 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800201 if (mDevice == 0) return NO_INIT;
202 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000203 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800204 Result retval;
205 Return<void> ret = mDevice->getInputBufferSize(
206 hidlConfig,
207 [&](Result r, uint64_t bufferSize) {
208 retval = r;
209 if (retval == Result::OK) {
210 *size = static_cast<size_t>(bufferSize);
211 }
212 });
213 return processReturn("getInputBufferSize", ret, retval);
214}
215
216status_t DeviceHalHidl::openOutputStream(
217 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700218 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800219 audio_output_flags_t flags,
220 struct audio_config *config,
221 const char *address,
222 sp<StreamOutHalInterface> *outStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700223 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800224 if (mDevice == 0) return NO_INIT;
225 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000226 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
227 status != OK) {
228 return status;
229 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800230 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000231 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
232 status != OK) {
233 return status;
234 }
Eric Laurente28c66d2022-01-21 13:40:41 +0100235
236#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1)
237 //TODO: b/193496180 use spatializer flag at audio HAL when available
238 if ((flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
239 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_SPATIALIZER);
240 flags = (audio_output_flags_t)
241 (flags | AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
242 }
243#endif
244
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000245 CoreUtils::AudioOutputFlags hidlFlags;
246 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
247 return status;
248 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800249 Result retval = Result::NOT_INITIALIZED;
Mikhail Naganov6718c392022-01-27 22:17:21 +0000250#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
251 Return<void> ret = mDevice->openOutputStream_7_1(
252#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800253 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000254#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000255 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800256#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800257 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700258#endif
Mikhail Naganov6718c392022-01-27 22:17:21 +0000259 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& result,
260 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800261 retval = r;
262 if (retval == Result::OK) {
263 *outStream = new StreamOutHalHidl(result);
264 }
265 HidlUtils::audioConfigToHal(suggestedConfig, config);
266 });
267 return processReturn("openOutputStream", ret, retval);
268}
269
270status_t DeviceHalHidl::openInputStream(
271 audio_io_handle_t handle,
272 audio_devices_t devices,
273 struct audio_config *config,
274 audio_input_flags_t flags,
275 const char *address,
276 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800277 audio_devices_t outputDevice,
278 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800279 sp<StreamInHalInterface> *inStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700280 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800281 if (mDevice == 0) return NO_INIT;
282 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000283 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
284 status != OK) {
285 return status;
286 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800287 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000288 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
289 status != OK) {
290 return status;
291 }
292 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100293#if MAJOR_VERSION <= 5
294 // Some flags were specific to framework and must not leak to the HAL.
295 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
296#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000297 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
298 return status;
299 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800300 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700301#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800302 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800303#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800304 // TODO: correctly propagate the tracks sources and volume
305 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000306 AudioSource hidlSource;
307 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
308 return status;
309 }
310 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700311#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800312#if MAJOR_VERSION < 5
313 (void)outputDevice;
314 (void)outputDeviceAddress;
315#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800316#if MAJOR_VERSION >= 7
317 (void)HidlUtils::audioChannelMaskFromHal(
318 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
319#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800320 if (outputDevice != AUDIO_DEVICE_NONE) {
321 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000322 if (status_t status = CoreUtils::deviceAddressFromHal(
323 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
324 return status;
325 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800326 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
327 }
328#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800329 Return<void> ret = mDevice->openInputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000330 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Mikhail Naganovaccbe8a2022-02-03 23:45:36 +0000331 [&](Result r,
332 const sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn>& result,
Mikhail Naganov6718c392022-01-27 22:17:21 +0000333 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800334 retval = r;
335 if (retval == Result::OK) {
336 *inStream = new StreamInHalHidl(result);
337 }
338 HidlUtils::audioConfigToHal(suggestedConfig, config);
339 });
340 return processReturn("openInputStream", ret, retval);
341}
342
343status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
Andy Hung224f82f2022-03-22 00:00:49 -0700344 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800345 if (mDevice == 0) return NO_INIT;
346 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
347}
348
349status_t DeviceHalHidl::createAudioPatch(
350 unsigned int num_sources,
351 const struct audio_port_config *sources,
352 unsigned int num_sinks,
353 const struct audio_port_config *sinks,
354 audio_patch_handle_t *patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700355 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800356 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700357 if (patch == nullptr) return BAD_VALUE;
358
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800359#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700360 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
361 status_t status = releaseAudioPatch(*patch);
362 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
363 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800364 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700365 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800366#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700367
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800368 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
369 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
370 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800371 Result retval = Result::OK;
372 Return<void> ret;
373 std::string methodName = "createAudioPatch";
374 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
375 ret = mDevice->createAudioPatch(
376 hidlSources, hidlSinks,
377 [&](Result r, AudioPatchHandle hidlPatch) {
378 retval = r;
379 if (retval == Result::OK) {
380 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
381 }
382 });
383 } else {
384#if MAJOR_VERSION >= 6
385 ret = mDevice->updateAudioPatch(
386 *patch,
387 hidlSources, hidlSinks,
388 [&](Result r, AudioPatchHandle hidlPatch) {
389 retval = r;
390 if (retval == Result::OK) {
391 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
392 }
393 });
394 methodName = "updateAudioPatch";
395#endif
396 }
397 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800398}
399
400status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700401 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800402 if (mDevice == 0) return NO_INIT;
403 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
404}
405
Mikhail Naganov720cc432021-03-24 20:42:49 -0700406template <typename HalPort>
407status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800408 if (mDevice == 0) return NO_INIT;
409 AudioPort hidlPort;
410 HidlUtils::audioPortFromHal(*port, &hidlPort);
411 Result retval;
412 Return<void> ret = mDevice->getAudioPort(
413 hidlPort,
414 [&](Result r, const AudioPort& p) {
415 retval = r;
416 if (retval == Result::OK) {
417 HidlUtils::audioPortToHal(p, port);
418 }
419 });
420 return processReturn("getAudioPort", ret, retval);
421}
422
Mikhail Naganov720cc432021-03-24 20:42:49 -0700423status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700424 TIME_CHECK();
Mikhail Naganov720cc432021-03-24 20:42:49 -0700425 return getAudioPortImpl(port);
426}
427
jiabinb4fed192020-09-22 14:45:40 -0700428status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700429 TIME_CHECK();
jiabinb4fed192020-09-22 14:45:40 -0700430#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700431 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700432#else
433 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700434 status_t result = NO_ERROR;
435 if (!audio_populate_audio_port(port, &audioPort)) {
436 ALOGE("Failed to populate legacy audio port from audio_port_v7");
437 result = BAD_VALUE;
438 }
439 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700440 if (status == NO_ERROR) {
441 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700442 } else {
443 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700444 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700445 return result;
jiabinb4fed192020-09-22 14:45:40 -0700446#endif
jiabinb4fed192020-09-22 14:45:40 -0700447}
448
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800449status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
Andy Hung224f82f2022-03-22 00:00:49 -0700450 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800451 if (mDevice == 0) return NO_INIT;
452 AudioPortConfig hidlConfig;
453 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
454 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
455}
456
Kevin Rocard070e7512018-05-22 09:29:13 -0700457#if MAJOR_VERSION == 2
458status_t DeviceHalHidl::getMicrophones(
Shunkai Yao51202502022-12-12 06:11:46 +0000459 std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
Kevin Rocard070e7512018-05-22 09:29:13 -0700460 if (mDevice == 0) return NO_INIT;
461 return INVALID_OPERATION;
462}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800463#elif MAJOR_VERSION >= 4
Shunkai Yao51202502022-12-12 06:11:46 +0000464status_t DeviceHalHidl::getMicrophones(
465 std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
Andy Hung224f82f2022-03-22 00:00:49 -0700466 TIME_CHECK();
jiabin9ff780e2018-03-19 18:19:52 -0700467 if (mDevice == 0) return NO_INIT;
468 Result retval;
469 Return<void> ret = mDevice->getMicrophones(
470 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
471 retval = r;
472 for (size_t k = 0; k < micArrayHal.size(); k++) {
473 audio_microphone_characteristic_t dst;
474 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000475 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
Shunkai Yao51202502022-12-12 06:11:46 +0000476 microphonesInfo->push_back(dst);
jiabin9ff780e2018-03-19 18:19:52 -0700477 }
478 });
479 return processReturn("getMicrophones", ret, retval);
480}
Kevin Rocard070e7512018-05-22 09:29:13 -0700481#endif
jiabin9ff780e2018-03-19 18:19:52 -0700482
Eric Laurentb82e6b72019-11-22 17:25:04 -0800483#if MAJOR_VERSION >= 6
484status_t DeviceHalHidl::addDeviceEffect(
485 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700486 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800487 if (mDevice == 0) return NO_INIT;
488 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000489 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800490}
491#else
492status_t DeviceHalHidl::addDeviceEffect(
493 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
494 return INVALID_OPERATION;
495}
496#endif
497
498#if MAJOR_VERSION >= 6
499status_t DeviceHalHidl::removeDeviceEffect(
500 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700501 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800502 if (mDevice == 0) return NO_INIT;
503 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000504 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800505}
506#else
507status_t DeviceHalHidl::removeDeviceEffect(
508 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
509 return INVALID_OPERATION;
510}
511#endif
512
Mikhail Naganov516d3982022-02-01 23:53:59 +0000513status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
Andy Hung224f82f2022-03-22 00:00:49 -0700514 TIME_CHECK();
Mikhail Naganov516d3982022-02-01 23:53:59 +0000515 if (mDevice == 0) return NO_INIT;
516#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
517 if (supportsSetConnectedState7_1) {
518 AudioPort hidlPort;
519 if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
520 return result;
521 }
522 Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
523 if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
524 return processReturn("setConnectedState_7_1", ret);
525 } else if (ret == Result::OK) {
526 return NO_ERROR;
527 }
528 supportsSetConnectedState7_1 = false;
529 }
530#endif
531 DeviceAddress hidlAddress;
532 if (status_t result = CoreUtils::deviceAddressFromHal(
533 port->ext.device.type, port->ext.device.address, &hidlAddress);
534 result != NO_ERROR) {
535 return result;
536 }
537 return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
538}
539
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800540error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
Andy Hung224f82f2022-03-22 00:00:49 -0700541 TIME_CHECK();
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800542 if (mDevice == 0) return NO_INIT;
543 audio_hw_sync_t value;
544 Result result;
545 Return<void> ret = mDevice->getHwAvSync([&value, &result](Result r, audio_hw_sync_t v) {
546 value = v;
547 result = r;
548 });
549 RETURN_IF_ERROR(processReturn("getHwAvSync", ret, result));
550 return value;
551}
552
Andy Hung61589a42021-06-16 09:37:53 -0700553status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
Andy Hung224f82f2022-03-22 00:00:49 -0700554 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800555 if (mDevice == 0) return NO_INIT;
556 native_handle_t* hidlHandle = native_handle_create(1, 0);
557 hidlHandle->data[0] = fd;
Andy Hung61589a42021-06-16 09:37:53 -0700558 hidl_vec<hidl_string> hidlArgs;
559 argsFromHal(args, &hidlArgs);
560 Return<void> ret = mDevice->debug(hidlHandle, hidlArgs);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800561 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700562
563 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
564 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
565 // when the remote binder thread removes the last refcount to the fd blocks in the
566 // kernel for binder activity. We send a Binder ping() command to unblock the thread
567 // and complete the fd close / release.
568 //
569 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
570 // EffectsFactoryHalHidl::dumpEffects().
571
572 (void)mDevice->ping(); // synchronous Binder call
573
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800574 return processReturn("dump", ret);
575}
576
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800577} // namespace android