blob: 22eb850a75479b59ebae3be913b4319957dfce7e [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"
Vlad Popa03bd5bc2023-01-17 16:16:51 +010020// #define LOG_NDEBUG 0
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080021
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
Vlad Popa03bd5bc2023-01-17 16:16:51 +010038#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
39#include <aidl/android/hardware/audio/core/sounddose/BpSoundDose.h>
40#include <aidl/android/hardware/audio/sounddose/BpSoundDoseFactory.h>
41#include <android/binder_manager.h>
42
43constexpr std::string_view kSoundDoseInterfaceModule = "/default";
44
45using aidl::android::hardware::audio::core::sounddose::ISoundDose;
46using aidl::android::hardware::audio::sounddose::ISoundDoseFactory;
47#endif
48
Mikhail Naganov6718c392022-01-27 22:17:21 +000049using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::implementation::HidlUtils;
Kevin Rocard7a9f05a2018-11-28 16:52:25 -080050using ::android::hardware::audio::common::utils::EnumBitfield;
Mikhail Naganov6718c392022-01-27 22:17:21 +000051using ::android::hardware::audio::CORE_TYPES_CPP_VERSION::implementation::CoreUtils;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080052using ::android::hardware::hidl_string;
53using ::android::hardware::hidl_vec;
54
55namespace android {
56
Mikhail Naganov6718c392022-01-27 22:17:21 +000057using namespace ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION;
58using namespace ::android::hardware::audio::CORE_TYPES_CPP_VERSION;
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080059
Vlad Popa03bd5bc2023-01-17 16:16:51 +010060class DeviceHalHidl::SoundDoseWrapper {
61public:
62 SoundDoseWrapper() = default;
63 ~SoundDoseWrapper() = default;
64
65#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
66 std::shared_ptr<ISoundDoseFactory> mSoundDoseFactory;
67 std::shared_ptr<ISoundDose> mSoundDose;
68#endif
69};
70
Mikhail Naganov6718c392022-01-27 22:17:21 +000071DeviceHalHidl::DeviceHalHidl(const sp<::android::hardware::audio::CPP_VERSION::IDevice>& device)
Vlad Popa03bd5bc2023-01-17 16:16:51 +010072 : CoreConversionHelperHidl("DeviceHalHidl"),
73 mDevice(device),
74 mSoundDoseWrapper(std::make_unique<DeviceHalHidl::SoundDoseWrapper>()) {
Mikhail Naganov6718c392022-01-27 22:17:21 +000075}
Eric Laurentb82e6b72019-11-22 17:25:04 -080076
Mikhail Naganov6718c392022-01-27 22:17:21 +000077DeviceHalHidl::DeviceHalHidl(
78 const sp<::android::hardware::audio::CPP_VERSION::IPrimaryDevice>& device)
Mikhail Naganov288a3432022-03-25 00:29:56 +000079 : CoreConversionHelperHidl("DeviceHalHidl"),
Mikhail Naganov6718c392022-01-27 22:17:21 +000080#if MAJOR_VERSION <= 6 || (MAJOR_VERSION == 7 && MINOR_VERSION == 0)
81 mDevice(device),
82#endif
Vlad Popa03bd5bc2023-01-17 16:16:51 +010083 mPrimaryDevice(device),
84 mSoundDoseWrapper(std::make_unique<DeviceHalHidl::SoundDoseWrapper>()) {
Mikhail Naganov6718c392022-01-27 22:17:21 +000085#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
86 auto getDeviceRet = mPrimaryDevice->getDevice();
87 if (getDeviceRet.isOk()) {
88 mDevice = getDeviceRet;
89 } else {
90 ALOGE("Call to IPrimaryDevice.getDevice has failed: %s",
91 getDeviceRet.description().c_str());
92 }
93#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080094}
95
96DeviceHalHidl::~DeviceHalHidl() {
97 if (mDevice != 0) {
Mikhail Naganov3355e442019-11-20 14:20:01 -080098#if MAJOR_VERSION <= 5
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080099 mDevice.clear();
100 hardware::IPCThreadState::self()->flushCommands();
Mikhail Naganov3355e442019-11-20 14:20:01 -0800101#elif MAJOR_VERSION >= 6
102 mDevice->close();
103#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800104 }
105}
106
Mikhail Naganov2d814892023-04-24 13:06:04 -0700107status_t DeviceHalHidl::getAudioPorts(
108 std::vector<media::audio::common::AudioPort> *ports __unused) {
109 return INVALID_OPERATION;
110}
111
112status_t DeviceHalHidl::getAudioRoutes(std::vector<media::AudioRoute> *routes __unused) {
113 return INVALID_OPERATION;
114}
115
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800116status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
117 // Obsolete.
118 return INVALID_OPERATION;
119}
120
121status_t DeviceHalHidl::initCheck() {
Andy Hung224f82f2022-03-22 00:00:49 -0700122 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800123 if (mDevice == 0) return NO_INIT;
124 return processReturn("initCheck", mDevice->initCheck());
125}
126
127status_t DeviceHalHidl::setVoiceVolume(float volume) {
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 if (mPrimaryDevice == 0) return INVALID_OPERATION;
131 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
132}
133
134status_t DeviceHalHidl::setMasterVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700135 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800136 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800137 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800138}
139
140status_t DeviceHalHidl::getMasterVolume(float *volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700141 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800142 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800143 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800144 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800145 [&](Result r, float v) {
146 retval = r;
147 if (retval == Result::OK) {
148 *volume = v;
149 }
150 });
151 return processReturn("getMasterVolume", ret, retval);
152}
153
154status_t DeviceHalHidl::setMode(audio_mode_t mode) {
Andy Hung224f82f2022-03-22 00:00:49 -0700155 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800156 if (mDevice == 0) return NO_INIT;
157 if (mPrimaryDevice == 0) return INVALID_OPERATION;
158 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
159}
160
161status_t DeviceHalHidl::setMicMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700162 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800163 if (mDevice == 0) return NO_INIT;
164 return processReturn("setMicMute", mDevice->setMicMute(state));
165}
166
167status_t DeviceHalHidl::getMicMute(bool *state) {
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 Result retval;
171 Return<void> ret = mDevice->getMicMute(
172 [&](Result r, bool mute) {
173 retval = r;
174 if (retval == Result::OK) {
175 *state = mute;
176 }
177 });
178 return processReturn("getMicMute", ret, retval);
179}
180
181status_t DeviceHalHidl::setMasterMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700182 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800183 if (mDevice == 0) return NO_INIT;
184 return processReturn("setMasterMute", mDevice->setMasterMute(state));
185}
186
187status_t DeviceHalHidl::getMasterMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700188 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800189 if (mDevice == 0) return NO_INIT;
190 Result retval;
191 Return<void> ret = mDevice->getMasterMute(
192 [&](Result r, bool mute) {
193 retval = r;
194 if (retval == Result::OK) {
195 *state = mute;
196 }
197 });
198 return processReturn("getMasterMute", ret, retval);
199}
200
201status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
Andy Hung224f82f2022-03-22 00:00:49 -0700202 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800203 if (mDevice == 0) return NO_INIT;
204 hidl_vec<ParameterValue> hidlParams;
205 status_t status = parametersFromHal(kvPairs, &hidlParams);
206 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800207 // TODO: change the API so that context and kvPairs are separated
208 return processReturn("setParameters",
209 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800210}
211
212status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
Andy Hung224f82f2022-03-22 00:00:49 -0700213 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800214 values->clear();
215 if (mDevice == 0) return NO_INIT;
216 hidl_vec<hidl_string> hidlKeys;
217 status_t status = keysFromHal(keys, &hidlKeys);
218 if (status != OK) return status;
219 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800220 Return<void> ret = utils::getParameters(mDevice,
221 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800222 hidlKeys,
223 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
224 retval = r;
225 if (retval == Result::OK) {
226 parametersToHal(parameters, values);
227 }
228 });
229 return processReturn("getParameters", ret, retval);
230}
231
232status_t DeviceHalHidl::getInputBufferSize(
233 const struct audio_config *config, size_t *size) {
Andy Hung224f82f2022-03-22 00:00:49 -0700234 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800235 if (mDevice == 0) return NO_INIT;
236 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000237 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800238 Result retval;
239 Return<void> ret = mDevice->getInputBufferSize(
240 hidlConfig,
241 [&](Result r, uint64_t bufferSize) {
242 retval = r;
243 if (retval == Result::OK) {
244 *size = static_cast<size_t>(bufferSize);
245 }
246 });
247 return processReturn("getInputBufferSize", ret, retval);
248}
249
250status_t DeviceHalHidl::openOutputStream(
251 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700252 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800253 audio_output_flags_t flags,
254 struct audio_config *config,
255 const char *address,
256 sp<StreamOutHalInterface> *outStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700257 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800258 if (mDevice == 0) return NO_INIT;
259 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000260 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
261 status != OK) {
262 return status;
263 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800264 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000265 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
266 status != OK) {
267 return status;
268 }
Eric Laurente28c66d2022-01-21 13:40:41 +0100269
270#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1)
271 //TODO: b/193496180 use spatializer flag at audio HAL when available
272 if ((flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
273 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_SPATIALIZER);
274 flags = (audio_output_flags_t)
275 (flags | AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
276 }
277#endif
278
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000279 CoreUtils::AudioOutputFlags hidlFlags;
280 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
281 return status;
282 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800283 Result retval = Result::NOT_INITIALIZED;
Mikhail Naganov6718c392022-01-27 22:17:21 +0000284#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
285 Return<void> ret = mDevice->openOutputStream_7_1(
286#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800287 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000288#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000289 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800290#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800291 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700292#endif
Mikhail Naganov6718c392022-01-27 22:17:21 +0000293 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& result,
294 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800295 retval = r;
296 if (retval == Result::OK) {
297 *outStream = new StreamOutHalHidl(result);
298 }
299 HidlUtils::audioConfigToHal(suggestedConfig, config);
300 });
301 return processReturn("openOutputStream", ret, retval);
302}
303
304status_t DeviceHalHidl::openInputStream(
305 audio_io_handle_t handle,
306 audio_devices_t devices,
307 struct audio_config *config,
308 audio_input_flags_t flags,
309 const char *address,
310 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800311 audio_devices_t outputDevice,
312 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800313 sp<StreamInHalInterface> *inStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700314 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800315 if (mDevice == 0) return NO_INIT;
316 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000317 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
318 status != OK) {
319 return status;
320 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800321 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000322 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
323 status != OK) {
324 return status;
325 }
326 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100327#if MAJOR_VERSION <= 5
328 // Some flags were specific to framework and must not leak to the HAL.
329 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
330#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000331 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
332 return status;
333 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800334 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700335#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800336 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800337#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800338 // TODO: correctly propagate the tracks sources and volume
339 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000340 AudioSource hidlSource;
341 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
342 return status;
343 }
344 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700345#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800346#if MAJOR_VERSION < 5
347 (void)outputDevice;
348 (void)outputDeviceAddress;
349#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800350#if MAJOR_VERSION >= 7
351 (void)HidlUtils::audioChannelMaskFromHal(
352 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
353#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800354 if (outputDevice != AUDIO_DEVICE_NONE) {
355 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000356 if (status_t status = CoreUtils::deviceAddressFromHal(
357 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
358 return status;
359 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800360 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
361 }
362#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800363 Return<void> ret = mDevice->openInputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000364 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Mikhail Naganovaccbe8a2022-02-03 23:45:36 +0000365 [&](Result r,
366 const sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn>& result,
Mikhail Naganov6718c392022-01-27 22:17:21 +0000367 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800368 retval = r;
369 if (retval == Result::OK) {
370 *inStream = new StreamInHalHidl(result);
371 }
372 HidlUtils::audioConfigToHal(suggestedConfig, config);
373 });
374 return processReturn("openInputStream", ret, retval);
375}
376
377status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
Andy Hung224f82f2022-03-22 00:00:49 -0700378 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800379 if (mDevice == 0) return NO_INIT;
380 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
381}
382
383status_t DeviceHalHidl::createAudioPatch(
384 unsigned int num_sources,
385 const struct audio_port_config *sources,
386 unsigned int num_sinks,
387 const struct audio_port_config *sinks,
388 audio_patch_handle_t *patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700389 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800390 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700391 if (patch == nullptr) return BAD_VALUE;
392
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800393#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700394 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
395 status_t status = releaseAudioPatch(*patch);
396 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
397 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800398 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700399 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800400#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700401
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800402 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
403 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
404 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800405 Result retval = Result::OK;
406 Return<void> ret;
407 std::string methodName = "createAudioPatch";
408 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
409 ret = mDevice->createAudioPatch(
410 hidlSources, hidlSinks,
411 [&](Result r, AudioPatchHandle hidlPatch) {
412 retval = r;
413 if (retval == Result::OK) {
414 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
415 }
416 });
417 } else {
418#if MAJOR_VERSION >= 6
419 ret = mDevice->updateAudioPatch(
420 *patch,
421 hidlSources, hidlSinks,
422 [&](Result r, AudioPatchHandle hidlPatch) {
423 retval = r;
424 if (retval == Result::OK) {
425 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
426 }
427 });
428 methodName = "updateAudioPatch";
429#endif
430 }
431 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800432}
433
434status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700435 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800436 if (mDevice == 0) return NO_INIT;
437 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
438}
439
Mikhail Naganov720cc432021-03-24 20:42:49 -0700440template <typename HalPort>
441status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Mikhail Naganov2d814892023-04-24 13:06:04 -0700442 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800443 if (mDevice == 0) return NO_INIT;
444 AudioPort hidlPort;
445 HidlUtils::audioPortFromHal(*port, &hidlPort);
446 Result retval;
447 Return<void> ret = mDevice->getAudioPort(
448 hidlPort,
449 [&](Result r, const AudioPort& p) {
450 retval = r;
451 if (retval == Result::OK) {
452 HidlUtils::audioPortToHal(p, port);
453 }
454 });
455 return processReturn("getAudioPort", ret, retval);
456}
457
Mikhail Naganov720cc432021-03-24 20:42:49 -0700458status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700459 TIME_CHECK();
Mikhail Naganov720cc432021-03-24 20:42:49 -0700460 return getAudioPortImpl(port);
461}
462
jiabinb4fed192020-09-22 14:45:40 -0700463status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700464 TIME_CHECK();
jiabinb4fed192020-09-22 14:45:40 -0700465#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700466 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700467#else
468 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700469 status_t result = NO_ERROR;
470 if (!audio_populate_audio_port(port, &audioPort)) {
471 ALOGE("Failed to populate legacy audio port from audio_port_v7");
472 result = BAD_VALUE;
473 }
474 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700475 if (status == NO_ERROR) {
476 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700477 } else {
478 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700479 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700480 return result;
jiabinb4fed192020-09-22 14:45:40 -0700481#endif
jiabinb4fed192020-09-22 14:45:40 -0700482}
483
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800484status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
Mikhail Naganov2d814892023-04-24 13:06:04 -0700485 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPortConfig;
Andy Hung224f82f2022-03-22 00:00:49 -0700486 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800487 if (mDevice == 0) return NO_INIT;
488 AudioPortConfig hidlConfig;
489 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
490 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
491}
492
Kevin Rocard070e7512018-05-22 09:29:13 -0700493#if MAJOR_VERSION == 2
494status_t DeviceHalHidl::getMicrophones(
Shunkai Yao51202502022-12-12 06:11:46 +0000495 std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
Kevin Rocard070e7512018-05-22 09:29:13 -0700496 if (mDevice == 0) return NO_INIT;
497 return INVALID_OPERATION;
498}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800499#elif MAJOR_VERSION >= 4
Shunkai Yao51202502022-12-12 06:11:46 +0000500status_t DeviceHalHidl::getMicrophones(
501 std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
Andy Hung224f82f2022-03-22 00:00:49 -0700502 TIME_CHECK();
jiabin9ff780e2018-03-19 18:19:52 -0700503 if (mDevice == 0) return NO_INIT;
504 Result retval;
505 Return<void> ret = mDevice->getMicrophones(
506 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
507 retval = r;
508 for (size_t k = 0; k < micArrayHal.size(); k++) {
509 audio_microphone_characteristic_t dst;
510 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000511 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
Shunkai Yao51202502022-12-12 06:11:46 +0000512 microphonesInfo->push_back(dst);
jiabin9ff780e2018-03-19 18:19:52 -0700513 }
514 });
515 return processReturn("getMicrophones", ret, retval);
516}
Kevin Rocard070e7512018-05-22 09:29:13 -0700517#endif
jiabin9ff780e2018-03-19 18:19:52 -0700518
Eric Laurentb82e6b72019-11-22 17:25:04 -0800519#if MAJOR_VERSION >= 6
520status_t DeviceHalHidl::addDeviceEffect(
521 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700522 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800523 if (mDevice == 0) return NO_INIT;
524 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000525 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800526}
527#else
528status_t DeviceHalHidl::addDeviceEffect(
529 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
530 return INVALID_OPERATION;
531}
532#endif
533
534#if MAJOR_VERSION >= 6
535status_t DeviceHalHidl::removeDeviceEffect(
536 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700537 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800538 if (mDevice == 0) return NO_INIT;
539 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000540 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800541}
542#else
543status_t DeviceHalHidl::removeDeviceEffect(
544 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
545 return INVALID_OPERATION;
546}
547#endif
548
Mikhail Naganov516d3982022-02-01 23:53:59 +0000549status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
Mikhail Naganov2d814892023-04-24 13:06:04 -0700550 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
Andy Hung224f82f2022-03-22 00:00:49 -0700551 TIME_CHECK();
Mikhail Naganov516d3982022-02-01 23:53:59 +0000552 if (mDevice == 0) return NO_INIT;
553#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
554 if (supportsSetConnectedState7_1) {
555 AudioPort hidlPort;
556 if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
557 return result;
558 }
559 Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
560 if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
561 return processReturn("setConnectedState_7_1", ret);
562 } else if (ret == Result::OK) {
563 return NO_ERROR;
564 }
565 supportsSetConnectedState7_1 = false;
566 }
567#endif
568 DeviceAddress hidlAddress;
569 if (status_t result = CoreUtils::deviceAddressFromHal(
570 port->ext.device.type, port->ext.device.address, &hidlAddress);
571 result != NO_ERROR) {
572 return result;
573 }
574 return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
575}
576
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800577error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
Andy Hung224f82f2022-03-22 00:00:49 -0700578 TIME_CHECK();
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800579 if (mDevice == 0) return NO_INIT;
580 audio_hw_sync_t value;
581 Result result;
582 Return<void> ret = mDevice->getHwAvSync([&value, &result](Result r, audio_hw_sync_t v) {
583 value = v;
584 result = r;
585 });
586 RETURN_IF_ERROR(processReturn("getHwAvSync", ret, result));
587 return value;
588}
589
Andy Hung61589a42021-06-16 09:37:53 -0700590status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
Andy Hung224f82f2022-03-22 00:00:49 -0700591 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800592 if (mDevice == 0) return NO_INIT;
593 native_handle_t* hidlHandle = native_handle_create(1, 0);
594 hidlHandle->data[0] = fd;
Andy Hung61589a42021-06-16 09:37:53 -0700595 hidl_vec<hidl_string> hidlArgs;
596 argsFromHal(args, &hidlArgs);
597 Return<void> ret = mDevice->debug(hidlHandle, hidlArgs);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800598 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700599
600 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
601 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
602 // when the remote binder thread removes the last refcount to the fd blocks in the
603 // kernel for binder activity. We send a Binder ping() command to unblock the thread
604 // and complete the fd close / release.
605 //
606 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
607 // EffectsFactoryHalHidl::dumpEffects().
608
609 (void)mDevice->ping(); // synchronous Binder call
610
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800611 return processReturn("dump", ret);
612}
613
Vlad Popa03bd5bc2023-01-17 16:16:51 +0100614#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
615status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
616 ::ndk::SpAIBinder* soundDoseBinder) {
617 if (mSoundDoseWrapper->mSoundDose != nullptr) {
618 *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
619 return OK;
620 }
621
622 if (mSoundDoseWrapper->mSoundDoseFactory == nullptr) {
623 std::string interface =
624 std::string(ISoundDoseFactory::descriptor) + kSoundDoseInterfaceModule.data();
625 AIBinder* binder = AServiceManager_checkService(interface.c_str());
626 if (binder == nullptr) {
627 ALOGW("%s service %s doesn't exist", __func__, interface.c_str());
628 return NO_INIT;
629 }
630 mSoundDoseWrapper->mSoundDoseFactory =
631 ISoundDoseFactory::fromBinder(ndk::SpAIBinder(binder));
632 }
633
634 auto result = mSoundDoseWrapper->mSoundDoseFactory->getSoundDose(
635 module, &mSoundDoseWrapper->mSoundDose);
636 if (!result.isOk()) {
637 ALOGW("%s could not get sound dose interface: %s", __func__, result.getMessage());
638 return BAD_VALUE;
639 }
640
641 if (mSoundDoseWrapper->mSoundDose == nullptr) {
642 ALOGW("%s standalone sound dose interface is not implemented", __func__);
643 *soundDoseBinder = nullptr;
644 return OK;
645 }
646
647 *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
648 ALOGI("%s using standalone sound dose interface", __func__);
649 return OK;
650}
651#else
652status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
653 ::ndk::SpAIBinder* soundDoseBinder) {
654 (void)module; // avoid unused param
655 (void)soundDoseBinder; // avoid unused param
656 return INVALID_OPERATION;
657}
658#endif
659
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800660} // namespace android