blob: 47acb19f11eb9982876dfffc6af3441955df56d5 [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>
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080026#include <utils/Log.h>
27
Mikhail Naganov247b5f92021-01-15 19:16:12 +000028#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
29#include <HidlUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080030#include <common/all-versions/VersionUtils.h>
Mikhail Naganov247b5f92021-01-15 19:16:12 +000031#include <util/CoreUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080032
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080033#include "DeviceHalHidl.h"
Eric Laurentb82e6b72019-11-22 17:25:04 -080034#include "EffectHalHidl.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 Naganov9ccaa162018-12-12 10:27:29 -080038using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
Kevin Rocard7a9f05a2018-11-28 16:52:25 -080039using ::android::hardware::audio::common::utils::EnumBitfield;
Mikhail Naganov247b5f92021-01-15 19:16:12 +000040using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080041using ::android::hardware::hidl_string;
42using ::android::hardware::hidl_vec;
43
44namespace android {
Kevin Rocard070e7512018-05-22 09:29:13 -070045namespace CPP_VERSION {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080046
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080047using namespace ::android::hardware::audio::common::CPP_VERSION;
48using namespace ::android::hardware::audio::CPP_VERSION;
49
Eric Laurentb82e6b72019-11-22 17:25:04 -080050using EffectHalHidl = ::android::effect::CPP_VERSION::EffectHalHidl;
51
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080052DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
53 : ConversionHelperHidl("Device"), mDevice(device),
54 mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
55}
56
57DeviceHalHidl::~DeviceHalHidl() {
58 if (mDevice != 0) {
Mikhail Naganov3355e442019-11-20 14:20:01 -080059#if MAJOR_VERSION <= 5
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080060 mDevice.clear();
61 hardware::IPCThreadState::self()->flushCommands();
Mikhail Naganov3355e442019-11-20 14:20:01 -080062#elif MAJOR_VERSION >= 6
63 mDevice->close();
64#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080065 }
66}
67
68status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
69 // Obsolete.
70 return INVALID_OPERATION;
71}
72
73status_t DeviceHalHidl::initCheck() {
74 if (mDevice == 0) return NO_INIT;
75 return processReturn("initCheck", mDevice->initCheck());
76}
77
78status_t DeviceHalHidl::setVoiceVolume(float volume) {
79 if (mDevice == 0) return NO_INIT;
80 if (mPrimaryDevice == 0) return INVALID_OPERATION;
81 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
82}
83
84status_t DeviceHalHidl::setMasterVolume(float volume) {
85 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -080086 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080087}
88
89status_t DeviceHalHidl::getMasterVolume(float *volume) {
90 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080091 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -080092 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080093 [&](Result r, float v) {
94 retval = r;
95 if (retval == Result::OK) {
96 *volume = v;
97 }
98 });
99 return processReturn("getMasterVolume", ret, retval);
100}
101
102status_t DeviceHalHidl::setMode(audio_mode_t mode) {
103 if (mDevice == 0) return NO_INIT;
104 if (mPrimaryDevice == 0) return INVALID_OPERATION;
105 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
106}
107
108status_t DeviceHalHidl::setMicMute(bool state) {
109 if (mDevice == 0) return NO_INIT;
110 return processReturn("setMicMute", mDevice->setMicMute(state));
111}
112
113status_t DeviceHalHidl::getMicMute(bool *state) {
114 if (mDevice == 0) return NO_INIT;
115 Result retval;
116 Return<void> ret = mDevice->getMicMute(
117 [&](Result r, bool mute) {
118 retval = r;
119 if (retval == Result::OK) {
120 *state = mute;
121 }
122 });
123 return processReturn("getMicMute", ret, retval);
124}
125
126status_t DeviceHalHidl::setMasterMute(bool state) {
127 if (mDevice == 0) return NO_INIT;
128 return processReturn("setMasterMute", mDevice->setMasterMute(state));
129}
130
131status_t DeviceHalHidl::getMasterMute(bool *state) {
132 if (mDevice == 0) return NO_INIT;
133 Result retval;
134 Return<void> ret = mDevice->getMasterMute(
135 [&](Result r, bool mute) {
136 retval = r;
137 if (retval == Result::OK) {
138 *state = mute;
139 }
140 });
141 return processReturn("getMasterMute", ret, retval);
142}
143
144status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
145 if (mDevice == 0) return NO_INIT;
146 hidl_vec<ParameterValue> hidlParams;
147 status_t status = parametersFromHal(kvPairs, &hidlParams);
148 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800149 // TODO: change the API so that context and kvPairs are separated
150 return processReturn("setParameters",
151 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800152}
153
154status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
155 values->clear();
156 if (mDevice == 0) return NO_INIT;
157 hidl_vec<hidl_string> hidlKeys;
158 status_t status = keysFromHal(keys, &hidlKeys);
159 if (status != OK) return status;
160 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800161 Return<void> ret = utils::getParameters(mDevice,
162 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800163 hidlKeys,
164 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
165 retval = r;
166 if (retval == Result::OK) {
167 parametersToHal(parameters, values);
168 }
169 });
170 return processReturn("getParameters", ret, retval);
171}
172
173status_t DeviceHalHidl::getInputBufferSize(
174 const struct audio_config *config, size_t *size) {
175 if (mDevice == 0) return NO_INIT;
176 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000177 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800178 Result retval;
179 Return<void> ret = mDevice->getInputBufferSize(
180 hidlConfig,
181 [&](Result r, uint64_t bufferSize) {
182 retval = r;
183 if (retval == Result::OK) {
184 *size = static_cast<size_t>(bufferSize);
185 }
186 });
187 return processReturn("getInputBufferSize", ret, retval);
188}
189
190status_t DeviceHalHidl::openOutputStream(
191 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700192 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800193 audio_output_flags_t flags,
194 struct audio_config *config,
195 const char *address,
196 sp<StreamOutHalInterface> *outStream) {
197 if (mDevice == 0) return NO_INIT;
198 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000199 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
200 status != OK) {
201 return status;
202 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800203 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000204 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
205 status != OK) {
206 return status;
207 }
208 CoreUtils::AudioOutputFlags hidlFlags;
209 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
210 return status;
211 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800212 Result retval = Result::NOT_INITIALIZED;
213 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000214 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800215#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800216 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700217#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800218 [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
219 retval = r;
220 if (retval == Result::OK) {
221 *outStream = new StreamOutHalHidl(result);
222 }
223 HidlUtils::audioConfigToHal(suggestedConfig, config);
224 });
225 return processReturn("openOutputStream", ret, retval);
226}
227
228status_t DeviceHalHidl::openInputStream(
229 audio_io_handle_t handle,
230 audio_devices_t devices,
231 struct audio_config *config,
232 audio_input_flags_t flags,
233 const char *address,
234 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800235 audio_devices_t outputDevice,
236 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800237 sp<StreamInHalInterface> *inStream) {
238 if (mDevice == 0) return NO_INIT;
239 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000240 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
241 status != OK) {
242 return status;
243 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800244 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000245 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
246 status != OK) {
247 return status;
248 }
249 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100250#if MAJOR_VERSION <= 5
251 // Some flags were specific to framework and must not leak to the HAL.
252 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
253#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000254 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
255 return status;
256 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800257 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700258#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800259 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800260#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800261 // TODO: correctly propagate the tracks sources and volume
262 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000263 AudioSource hidlSource;
264 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
265 return status;
266 }
267 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700268#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800269#if MAJOR_VERSION < 5
270 (void)outputDevice;
271 (void)outputDeviceAddress;
272#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800273#if MAJOR_VERSION >= 7
274 (void)HidlUtils::audioChannelMaskFromHal(
275 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
276#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800277 if (outputDevice != AUDIO_DEVICE_NONE) {
278 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000279 if (status_t status = CoreUtils::deviceAddressFromHal(
280 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
281 return status;
282 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800283 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
284 }
285#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800286 Return<void> ret = mDevice->openInputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000287 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800288 [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
289 retval = r;
290 if (retval == Result::OK) {
291 *inStream = new StreamInHalHidl(result);
292 }
293 HidlUtils::audioConfigToHal(suggestedConfig, config);
294 });
295 return processReturn("openInputStream", ret, retval);
296}
297
298status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
299 if (mDevice == 0) return NO_INIT;
300 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
301}
302
303status_t DeviceHalHidl::createAudioPatch(
304 unsigned int num_sources,
305 const struct audio_port_config *sources,
306 unsigned int num_sinks,
307 const struct audio_port_config *sinks,
308 audio_patch_handle_t *patch) {
309 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700310 if (patch == nullptr) return BAD_VALUE;
311
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800312#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700313 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
314 status_t status = releaseAudioPatch(*patch);
315 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
316 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800317 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700318 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800319#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700320
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800321 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
322 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
323 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800324 Result retval = Result::OK;
325 Return<void> ret;
326 std::string methodName = "createAudioPatch";
327 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
328 ret = mDevice->createAudioPatch(
329 hidlSources, hidlSinks,
330 [&](Result r, AudioPatchHandle hidlPatch) {
331 retval = r;
332 if (retval == Result::OK) {
333 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
334 }
335 });
336 } else {
337#if MAJOR_VERSION >= 6
338 ret = mDevice->updateAudioPatch(
339 *patch,
340 hidlSources, hidlSinks,
341 [&](Result r, AudioPatchHandle hidlPatch) {
342 retval = r;
343 if (retval == Result::OK) {
344 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
345 }
346 });
347 methodName = "updateAudioPatch";
348#endif
349 }
350 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800351}
352
353status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
354 if (mDevice == 0) return NO_INIT;
355 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
356}
357
Mikhail Naganov720cc432021-03-24 20:42:49 -0700358template <typename HalPort>
359status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800360 if (mDevice == 0) return NO_INIT;
361 AudioPort hidlPort;
362 HidlUtils::audioPortFromHal(*port, &hidlPort);
363 Result retval;
364 Return<void> ret = mDevice->getAudioPort(
365 hidlPort,
366 [&](Result r, const AudioPort& p) {
367 retval = r;
368 if (retval == Result::OK) {
369 HidlUtils::audioPortToHal(p, port);
370 }
371 });
372 return processReturn("getAudioPort", ret, retval);
373}
374
Mikhail Naganov720cc432021-03-24 20:42:49 -0700375status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
376 return getAudioPortImpl(port);
377}
378
jiabinb4fed192020-09-22 14:45:40 -0700379status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
jiabinb4fed192020-09-22 14:45:40 -0700380#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700381 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700382#else
383 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700384 status_t result = NO_ERROR;
385 if (!audio_populate_audio_port(port, &audioPort)) {
386 ALOGE("Failed to populate legacy audio port from audio_port_v7");
387 result = BAD_VALUE;
388 }
389 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700390 if (status == NO_ERROR) {
391 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700392 } else {
393 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700394 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700395 return result;
jiabinb4fed192020-09-22 14:45:40 -0700396#endif
jiabinb4fed192020-09-22 14:45:40 -0700397}
398
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800399status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
400 if (mDevice == 0) return NO_INIT;
401 AudioPortConfig hidlConfig;
402 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
403 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
404}
405
Kevin Rocard070e7512018-05-22 09:29:13 -0700406#if MAJOR_VERSION == 2
407status_t DeviceHalHidl::getMicrophones(
408 std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
409 if (mDevice == 0) return NO_INIT;
410 return INVALID_OPERATION;
411}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800412#elif MAJOR_VERSION >= 4
jiabin9ff780e2018-03-19 18:19:52 -0700413status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
414 if (mDevice == 0) return NO_INIT;
415 Result retval;
416 Return<void> ret = mDevice->getMicrophones(
417 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
418 retval = r;
419 for (size_t k = 0; k < micArrayHal.size(); k++) {
420 audio_microphone_characteristic_t dst;
421 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000422 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
jiabin9ff780e2018-03-19 18:19:52 -0700423 media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
424 microphonesInfo->push_back(microphone);
425 }
426 });
427 return processReturn("getMicrophones", ret, retval);
428}
Kevin Rocard070e7512018-05-22 09:29:13 -0700429#endif
jiabin9ff780e2018-03-19 18:19:52 -0700430
Eric Laurentb82e6b72019-11-22 17:25:04 -0800431#if MAJOR_VERSION >= 6
432status_t DeviceHalHidl::addDeviceEffect(
433 audio_port_handle_t device, sp<EffectHalInterface> effect) {
434 if (mDevice == 0) return NO_INIT;
435 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
436 static_cast<AudioPortHandle>(device),
437 static_cast<EffectHalHidl*>(effect.get())->effectId()));
438}
439#else
440status_t DeviceHalHidl::addDeviceEffect(
441 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
442 return INVALID_OPERATION;
443}
444#endif
445
446#if MAJOR_VERSION >= 6
447status_t DeviceHalHidl::removeDeviceEffect(
448 audio_port_handle_t device, sp<EffectHalInterface> effect) {
449 if (mDevice == 0) return NO_INIT;
450 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
451 static_cast<AudioPortHandle>(device),
452 static_cast<EffectHalHidl*>(effect.get())->effectId()));
453}
454#else
455status_t DeviceHalHidl::removeDeviceEffect(
456 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
457 return INVALID_OPERATION;
458}
459#endif
460
Andy Hung61589a42021-06-16 09:37:53 -0700461status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800462 if (mDevice == 0) return NO_INIT;
463 native_handle_t* hidlHandle = native_handle_create(1, 0);
464 hidlHandle->data[0] = fd;
Andy Hung61589a42021-06-16 09:37:53 -0700465 hidl_vec<hidl_string> hidlArgs;
466 argsFromHal(args, &hidlArgs);
467 Return<void> ret = mDevice->debug(hidlHandle, hidlArgs);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800468 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700469
470 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
471 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
472 // when the remote binder thread removes the last refcount to the fd blocks in the
473 // kernel for binder activity. We send a Binder ping() command to unblock the thread
474 // and complete the fd close / release.
475 //
476 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
477 // EffectsFactoryHalHidl::dumpEffects().
478
479 (void)mDevice->ping(); // synchronous Binder call
480
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800481 return processReturn("dump", ret);
482}
483
Kevin Rocard070e7512018-05-22 09:29:13 -0700484} // namespace CPP_VERSION
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800485} // namespace android