blob: 8b7cb5c5b81c7933b70ac09bad77335c23837ec8 [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>
23#include <hwbinder/IPCThreadState.h>
jiabindaf49952019-11-22 14:10:57 -080024#include <media/AudioContainers.h>
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080025#include <utils/Log.h>
26
Mikhail Naganov247b5f92021-01-15 19:16:12 +000027#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
28#include <HidlUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080029#include <common/all-versions/VersionUtils.h>
Mikhail Naganov247b5f92021-01-15 19:16:12 +000030#include <util/CoreUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080031
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080032#include "DeviceHalHidl.h"
Mikhail Naganov247b5f92021-01-15 19:16:12 +000033#include "ParameterUtils.h"
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080034#include "StreamHalHidl.h"
35
Mikhail Naganovea1f19d2022-01-27 22:17:21 +000036using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
Kevin Rocard7a9f05a2018-11-28 16:52:25 -080037using ::android::hardware::audio::common::utils::EnumBitfield;
Mikhail Naganovea1f19d2022-01-27 22:17:21 +000038using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080039using ::android::hardware::hidl_string;
40using ::android::hardware::hidl_vec;
41
42namespace android {
43
Mikhail Naganovea1f19d2022-01-27 22:17:21 +000044using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
45using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080046
Mikhail Naganovea1f19d2022-01-27 22:17:21 +000047DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
48 : ConversionHelperHidl("Device"), mDevice(device) {
49}
Eric Laurentb82e6b72019-11-22 17:25:04 -080050
Mikhail Naganovea1f19d2022-01-27 22:17:21 +000051DeviceHalHidl::DeviceHalHidl(
52 const sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice>& device)
53 : ConversionHelperHidl("Device"),
54#if MAJOR_VERSION <= 6 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
55 mDevice(device),
56#endif
57 mPrimaryDevice(device) {
58#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
59 auto getDeviceRet = mPrimaryDevice->getDevice();
60 if (getDeviceRet.isOk()) {
61 mDevice = getDeviceRet;
62 } else {
63 ALOGE("Call to IPrimaryDevice.getDevice has failed: %s",
64 getDeviceRet.description().c_str());
65 }
66#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080067}
68
69DeviceHalHidl::~DeviceHalHidl() {
70 if (mDevice != 0) {
Mikhail Naganov3355e442019-11-20 14:20:01 -080071#if MAJOR_VERSION <= 5
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080072 mDevice.clear();
73 hardware::IPCThreadState::self()->flushCommands();
Mikhail Naganov3355e442019-11-20 14:20:01 -080074#elif MAJOR_VERSION >= 6
75 mDevice->close();
76#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080077 }
78}
79
80status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
81 // Obsolete.
82 return INVALID_OPERATION;
83}
84
85status_t DeviceHalHidl::initCheck() {
86 if (mDevice == 0) return NO_INIT;
87 return processReturn("initCheck", mDevice->initCheck());
88}
89
90status_t DeviceHalHidl::setVoiceVolume(float volume) {
91 if (mDevice == 0) return NO_INIT;
92 if (mPrimaryDevice == 0) return INVALID_OPERATION;
93 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
94}
95
96status_t DeviceHalHidl::setMasterVolume(float volume) {
97 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -080098 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080099}
100
101status_t DeviceHalHidl::getMasterVolume(float *volume) {
102 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800103 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800104 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800105 [&](Result r, float v) {
106 retval = r;
107 if (retval == Result::OK) {
108 *volume = v;
109 }
110 });
111 return processReturn("getMasterVolume", ret, retval);
112}
113
114status_t DeviceHalHidl::setMode(audio_mode_t mode) {
115 if (mDevice == 0) return NO_INIT;
116 if (mPrimaryDevice == 0) return INVALID_OPERATION;
117 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
118}
119
120status_t DeviceHalHidl::setMicMute(bool state) {
121 if (mDevice == 0) return NO_INIT;
122 return processReturn("setMicMute", mDevice->setMicMute(state));
123}
124
125status_t DeviceHalHidl::getMicMute(bool *state) {
126 if (mDevice == 0) return NO_INIT;
127 Result retval;
128 Return<void> ret = mDevice->getMicMute(
129 [&](Result r, bool mute) {
130 retval = r;
131 if (retval == Result::OK) {
132 *state = mute;
133 }
134 });
135 return processReturn("getMicMute", ret, retval);
136}
137
138status_t DeviceHalHidl::setMasterMute(bool state) {
139 if (mDevice == 0) return NO_INIT;
140 return processReturn("setMasterMute", mDevice->setMasterMute(state));
141}
142
143status_t DeviceHalHidl::getMasterMute(bool *state) {
144 if (mDevice == 0) return NO_INIT;
145 Result retval;
146 Return<void> ret = mDevice->getMasterMute(
147 [&](Result r, bool mute) {
148 retval = r;
149 if (retval == Result::OK) {
150 *state = mute;
151 }
152 });
153 return processReturn("getMasterMute", ret, retval);
154}
155
156status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
157 if (mDevice == 0) return NO_INIT;
158 hidl_vec<ParameterValue> hidlParams;
159 status_t status = parametersFromHal(kvPairs, &hidlParams);
160 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800161 // TODO: change the API so that context and kvPairs are separated
162 return processReturn("setParameters",
163 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800164}
165
166status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
167 values->clear();
168 if (mDevice == 0) return NO_INIT;
169 hidl_vec<hidl_string> hidlKeys;
170 status_t status = keysFromHal(keys, &hidlKeys);
171 if (status != OK) return status;
172 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800173 Return<void> ret = utils::getParameters(mDevice,
174 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800175 hidlKeys,
176 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
177 retval = r;
178 if (retval == Result::OK) {
179 parametersToHal(parameters, values);
180 }
181 });
182 return processReturn("getParameters", ret, retval);
183}
184
185status_t DeviceHalHidl::getInputBufferSize(
186 const struct audio_config *config, size_t *size) {
187 if (mDevice == 0) return NO_INIT;
188 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000189 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800190 Result retval;
191 Return<void> ret = mDevice->getInputBufferSize(
192 hidlConfig,
193 [&](Result r, uint64_t bufferSize) {
194 retval = r;
195 if (retval == Result::OK) {
196 *size = static_cast<size_t>(bufferSize);
197 }
198 });
199 return processReturn("getInputBufferSize", ret, retval);
200}
201
202status_t DeviceHalHidl::openOutputStream(
203 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700204 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800205 audio_output_flags_t flags,
206 struct audio_config *config,
207 const char *address,
208 sp<StreamOutHalInterface> *outStream) {
209 if (mDevice == 0) return NO_INIT;
210 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000211 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
212 status != OK) {
213 return status;
214 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800215 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000216 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
217 status != OK) {
218 return status;
219 }
220 CoreUtils::AudioOutputFlags hidlFlags;
221 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
222 return status;
223 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800224 Result retval = Result::NOT_INITIALIZED;
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000225#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
226 Return<void> ret = mDevice->openOutputStream_7_1(
227#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800228 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000229#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000230 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800231#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800232 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700233#endif
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000234 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& result,
235 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800236 retval = r;
237 if (retval == Result::OK) {
238 *outStream = new StreamOutHalHidl(result);
239 }
240 HidlUtils::audioConfigToHal(suggestedConfig, config);
241 });
242 return processReturn("openOutputStream", ret, retval);
243}
244
245status_t DeviceHalHidl::openInputStream(
246 audio_io_handle_t handle,
247 audio_devices_t devices,
248 struct audio_config *config,
249 audio_input_flags_t flags,
250 const char *address,
251 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800252 audio_devices_t outputDevice,
253 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800254 sp<StreamInHalInterface> *inStream) {
255 if (mDevice == 0) return NO_INIT;
256 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000257 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
258 status != OK) {
259 return status;
260 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800261 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000262 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
263 status != OK) {
264 return status;
265 }
266 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100267#if MAJOR_VERSION <= 5
268 // Some flags were specific to framework and must not leak to the HAL.
269 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
270#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000271 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
272 return status;
273 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800274 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700275#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800276 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800277#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800278 // TODO: correctly propagate the tracks sources and volume
279 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000280 AudioSource hidlSource;
281 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
282 return status;
283 }
284 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700285#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800286#if MAJOR_VERSION < 5
287 (void)outputDevice;
288 (void)outputDeviceAddress;
289#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800290#if MAJOR_VERSION >= 7
291 (void)HidlUtils::audioChannelMaskFromHal(
292 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
293#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800294 if (outputDevice != AUDIO_DEVICE_NONE) {
295 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000296 if (status_t status = CoreUtils::deviceAddressFromHal(
297 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
298 return status;
299 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800300 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
301 }
302#endif
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000303#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
304 Return<void> ret = mDevice->openInputStream_7_1(
305#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800306 Return<void> ret = mDevice->openInputStream(
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000307#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000308 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000309 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamIn>& result,
310 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800311 retval = r;
312 if (retval == Result::OK) {
313 *inStream = new StreamInHalHidl(result);
314 }
315 HidlUtils::audioConfigToHal(suggestedConfig, config);
316 });
317 return processReturn("openInputStream", ret, retval);
318}
319
320status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
321 if (mDevice == 0) return NO_INIT;
322 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
323}
324
325status_t DeviceHalHidl::createAudioPatch(
326 unsigned int num_sources,
327 const struct audio_port_config *sources,
328 unsigned int num_sinks,
329 const struct audio_port_config *sinks,
330 audio_patch_handle_t *patch) {
331 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700332 if (patch == nullptr) return BAD_VALUE;
333
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800334#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700335 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
336 status_t status = releaseAudioPatch(*patch);
337 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
338 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800339 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700340 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800341#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700342
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800343 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
344 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
345 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800346 Result retval = Result::OK;
347 Return<void> ret;
348 std::string methodName = "createAudioPatch";
349 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
350 ret = mDevice->createAudioPatch(
351 hidlSources, hidlSinks,
352 [&](Result r, AudioPatchHandle hidlPatch) {
353 retval = r;
354 if (retval == Result::OK) {
355 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
356 }
357 });
358 } else {
359#if MAJOR_VERSION >= 6
360 ret = mDevice->updateAudioPatch(
361 *patch,
362 hidlSources, hidlSinks,
363 [&](Result r, AudioPatchHandle hidlPatch) {
364 retval = r;
365 if (retval == Result::OK) {
366 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
367 }
368 });
369 methodName = "updateAudioPatch";
370#endif
371 }
372 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800373}
374
375status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
376 if (mDevice == 0) return NO_INIT;
377 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
378}
379
Mikhail Naganov720cc432021-03-24 20:42:49 -0700380template <typename HalPort>
381status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800382 if (mDevice == 0) return NO_INIT;
383 AudioPort hidlPort;
384 HidlUtils::audioPortFromHal(*port, &hidlPort);
385 Result retval;
386 Return<void> ret = mDevice->getAudioPort(
387 hidlPort,
388 [&](Result r, const AudioPort& p) {
389 retval = r;
390 if (retval == Result::OK) {
391 HidlUtils::audioPortToHal(p, port);
392 }
393 });
394 return processReturn("getAudioPort", ret, retval);
395}
396
Mikhail Naganov720cc432021-03-24 20:42:49 -0700397status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
398 return getAudioPortImpl(port);
399}
400
jiabinb4fed192020-09-22 14:45:40 -0700401status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
jiabinb4fed192020-09-22 14:45:40 -0700402#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700403 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700404#else
405 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700406 status_t result = NO_ERROR;
407 if (!audio_populate_audio_port(port, &audioPort)) {
408 ALOGE("Failed to populate legacy audio port from audio_port_v7");
409 result = BAD_VALUE;
410 }
411 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700412 if (status == NO_ERROR) {
413 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700414 } else {
415 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700416 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700417 return result;
jiabinb4fed192020-09-22 14:45:40 -0700418#endif
jiabinb4fed192020-09-22 14:45:40 -0700419}
420
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800421status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
422 if (mDevice == 0) return NO_INIT;
423 AudioPortConfig hidlConfig;
424 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
425 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
426}
427
Kevin Rocard070e7512018-05-22 09:29:13 -0700428#if MAJOR_VERSION == 2
429status_t DeviceHalHidl::getMicrophones(
430 std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
431 if (mDevice == 0) return NO_INIT;
432 return INVALID_OPERATION;
433}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800434#elif MAJOR_VERSION >= 4
jiabin9ff780e2018-03-19 18:19:52 -0700435status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
436 if (mDevice == 0) return NO_INIT;
437 Result retval;
438 Return<void> ret = mDevice->getMicrophones(
439 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
440 retval = r;
441 for (size_t k = 0; k < micArrayHal.size(); k++) {
442 audio_microphone_characteristic_t dst;
443 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000444 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
jiabin9ff780e2018-03-19 18:19:52 -0700445 media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
446 microphonesInfo->push_back(microphone);
447 }
448 });
449 return processReturn("getMicrophones", ret, retval);
450}
Kevin Rocard070e7512018-05-22 09:29:13 -0700451#endif
jiabin9ff780e2018-03-19 18:19:52 -0700452
Eric Laurentb82e6b72019-11-22 17:25:04 -0800453#if MAJOR_VERSION >= 6
454status_t DeviceHalHidl::addDeviceEffect(
455 audio_port_handle_t device, sp<EffectHalInterface> effect) {
456 if (mDevice == 0) return NO_INIT;
457 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000458 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800459}
460#else
461status_t DeviceHalHidl::addDeviceEffect(
462 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
463 return INVALID_OPERATION;
464}
465#endif
466
467#if MAJOR_VERSION >= 6
468status_t DeviceHalHidl::removeDeviceEffect(
469 audio_port_handle_t device, sp<EffectHalInterface> effect) {
470 if (mDevice == 0) return NO_INIT;
471 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
Mikhail Naganovea1f19d2022-01-27 22:17:21 +0000472 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800473}
474#else
475status_t DeviceHalHidl::removeDeviceEffect(
476 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
477 return INVALID_OPERATION;
478}
479#endif
480
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800481status_t DeviceHalHidl::dump(int fd) {
482 if (mDevice == 0) return NO_INIT;
483 native_handle_t* hidlHandle = native_handle_create(1, 0);
484 hidlHandle->data[0] = fd;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800485 Return<void> ret = mDevice->debug(hidlHandle, {} /* options */);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800486 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700487
488 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
489 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
490 // when the remote binder thread removes the last refcount to the fd blocks in the
491 // kernel for binder activity. We send a Binder ping() command to unblock the thread
492 // and complete the fd close / release.
493 //
494 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
495 // EffectsFactoryHalHidl::dumpEffects().
496
497 (void)mDevice->ping(); // synchronous Binder call
498
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800499 return processReturn("dump", ret);
500}
501
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800502} // namespace android