blob: 826461f9a504b2b518b5db41dd531c580aad58be [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
Mikhail Naganovffd97712023-05-03 17:45:36 -0700116status_t DeviceHalHidl::getSupportedModes(
117 std::vector<media::audio::common::AudioMode> *modes __unused) {
118 return INVALID_OPERATION;
119}
120
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800121status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
122 // Obsolete.
123 return INVALID_OPERATION;
124}
125
126status_t DeviceHalHidl::initCheck() {
Andy Hung224f82f2022-03-22 00:00:49 -0700127 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800128 if (mDevice == 0) return NO_INIT;
129 return processReturn("initCheck", mDevice->initCheck());
130}
131
132status_t DeviceHalHidl::setVoiceVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700133 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800134 if (mDevice == 0) return NO_INIT;
135 if (mPrimaryDevice == 0) return INVALID_OPERATION;
136 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
137}
138
139status_t DeviceHalHidl::setMasterVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700140 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800141 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800142 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800143}
144
145status_t DeviceHalHidl::getMasterVolume(float *volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700146 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800147 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800148 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800149 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800150 [&](Result r, float v) {
151 retval = r;
152 if (retval == Result::OK) {
153 *volume = v;
154 }
155 });
156 return processReturn("getMasterVolume", ret, retval);
157}
158
159status_t DeviceHalHidl::setMode(audio_mode_t mode) {
Andy Hung224f82f2022-03-22 00:00:49 -0700160 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800161 if (mDevice == 0) return NO_INIT;
162 if (mPrimaryDevice == 0) return INVALID_OPERATION;
163 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
164}
165
166status_t DeviceHalHidl::setMicMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700167 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800168 if (mDevice == 0) return NO_INIT;
169 return processReturn("setMicMute", mDevice->setMicMute(state));
170}
171
172status_t DeviceHalHidl::getMicMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700173 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800174 if (mDevice == 0) return NO_INIT;
175 Result retval;
176 Return<void> ret = mDevice->getMicMute(
177 [&](Result r, bool mute) {
178 retval = r;
179 if (retval == Result::OK) {
180 *state = mute;
181 }
182 });
183 return processReturn("getMicMute", ret, retval);
184}
185
186status_t DeviceHalHidl::setMasterMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700187 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800188 if (mDevice == 0) return NO_INIT;
189 return processReturn("setMasterMute", mDevice->setMasterMute(state));
190}
191
192status_t DeviceHalHidl::getMasterMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700193 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800194 if (mDevice == 0) return NO_INIT;
195 Result retval;
196 Return<void> ret = mDevice->getMasterMute(
197 [&](Result r, bool mute) {
198 retval = r;
199 if (retval == Result::OK) {
200 *state = mute;
201 }
202 });
203 return processReturn("getMasterMute", ret, retval);
204}
205
206status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
Andy Hung224f82f2022-03-22 00:00:49 -0700207 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800208 if (mDevice == 0) return NO_INIT;
209 hidl_vec<ParameterValue> hidlParams;
210 status_t status = parametersFromHal(kvPairs, &hidlParams);
211 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800212 // TODO: change the API so that context and kvPairs are separated
213 return processReturn("setParameters",
214 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800215}
216
217status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
Andy Hung224f82f2022-03-22 00:00:49 -0700218 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800219 values->clear();
220 if (mDevice == 0) return NO_INIT;
221 hidl_vec<hidl_string> hidlKeys;
222 status_t status = keysFromHal(keys, &hidlKeys);
223 if (status != OK) return status;
224 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800225 Return<void> ret = utils::getParameters(mDevice,
226 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800227 hidlKeys,
228 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
229 retval = r;
230 if (retval == Result::OK) {
231 parametersToHal(parameters, values);
232 }
233 });
234 return processReturn("getParameters", ret, retval);
235}
236
237status_t DeviceHalHidl::getInputBufferSize(
238 const struct audio_config *config, size_t *size) {
Andy Hung224f82f2022-03-22 00:00:49 -0700239 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800240 if (mDevice == 0) return NO_INIT;
241 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000242 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800243 Result retval;
244 Return<void> ret = mDevice->getInputBufferSize(
245 hidlConfig,
246 [&](Result r, uint64_t bufferSize) {
247 retval = r;
248 if (retval == Result::OK) {
249 *size = static_cast<size_t>(bufferSize);
250 }
251 });
252 return processReturn("getInputBufferSize", ret, retval);
253}
254
255status_t DeviceHalHidl::openOutputStream(
256 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700257 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800258 audio_output_flags_t flags,
259 struct audio_config *config,
260 const char *address,
261 sp<StreamOutHalInterface> *outStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700262 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800263 if (mDevice == 0) return NO_INIT;
264 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000265 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
266 status != OK) {
267 return status;
268 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800269 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000270 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
271 status != OK) {
272 return status;
273 }
Eric Laurente28c66d2022-01-21 13:40:41 +0100274
275#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1)
276 //TODO: b/193496180 use spatializer flag at audio HAL when available
277 if ((flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
278 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_SPATIALIZER);
279 flags = (audio_output_flags_t)
280 (flags | AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
281 }
282#endif
283
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000284 CoreUtils::AudioOutputFlags hidlFlags;
285 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
286 return status;
287 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800288 Result retval = Result::NOT_INITIALIZED;
Mikhail Naganov6718c392022-01-27 22:17:21 +0000289#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
290 Return<void> ret = mDevice->openOutputStream_7_1(
291#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800292 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000293#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000294 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800295#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800296 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700297#endif
Mikhail Naganov6718c392022-01-27 22:17:21 +0000298 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& result,
299 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800300 retval = r;
301 if (retval == Result::OK) {
302 *outStream = new StreamOutHalHidl(result);
303 }
304 HidlUtils::audioConfigToHal(suggestedConfig, config);
305 });
306 return processReturn("openOutputStream", ret, retval);
307}
308
309status_t DeviceHalHidl::openInputStream(
310 audio_io_handle_t handle,
311 audio_devices_t devices,
312 struct audio_config *config,
313 audio_input_flags_t flags,
314 const char *address,
315 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800316 audio_devices_t outputDevice,
317 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800318 sp<StreamInHalInterface> *inStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700319 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800320 if (mDevice == 0) return NO_INIT;
321 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000322 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
323 status != OK) {
324 return status;
325 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800326 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000327 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
328 status != OK) {
329 return status;
330 }
331 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100332#if MAJOR_VERSION <= 5
333 // Some flags were specific to framework and must not leak to the HAL.
334 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
335#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000336 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
337 return status;
338 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800339 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700340#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800341 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800342#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800343 // TODO: correctly propagate the tracks sources and volume
344 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000345 AudioSource hidlSource;
346 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
347 return status;
348 }
349 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700350#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800351#if MAJOR_VERSION < 5
352 (void)outputDevice;
353 (void)outputDeviceAddress;
354#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800355#if MAJOR_VERSION >= 7
356 (void)HidlUtils::audioChannelMaskFromHal(
357 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
358#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800359 if (outputDevice != AUDIO_DEVICE_NONE) {
360 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000361 if (status_t status = CoreUtils::deviceAddressFromHal(
362 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
363 return status;
364 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800365 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
366 }
367#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800368 Return<void> ret = mDevice->openInputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000369 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Mikhail Naganovaccbe8a2022-02-03 23:45:36 +0000370 [&](Result r,
371 const sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn>& result,
Mikhail Naganov6718c392022-01-27 22:17:21 +0000372 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800373 retval = r;
374 if (retval == Result::OK) {
375 *inStream = new StreamInHalHidl(result);
376 }
377 HidlUtils::audioConfigToHal(suggestedConfig, config);
378 });
379 return processReturn("openInputStream", ret, retval);
380}
381
382status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
Andy Hung224f82f2022-03-22 00:00:49 -0700383 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800384 if (mDevice == 0) return NO_INIT;
385 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
386}
387
388status_t DeviceHalHidl::createAudioPatch(
389 unsigned int num_sources,
390 const struct audio_port_config *sources,
391 unsigned int num_sinks,
392 const struct audio_port_config *sinks,
393 audio_patch_handle_t *patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700394 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800395 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700396 if (patch == nullptr) return BAD_VALUE;
397
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800398#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700399 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
400 status_t status = releaseAudioPatch(*patch);
401 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
402 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800403 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700404 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800405#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700406
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800407 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
408 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
409 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800410 Result retval = Result::OK;
411 Return<void> ret;
412 std::string methodName = "createAudioPatch";
413 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
414 ret = mDevice->createAudioPatch(
415 hidlSources, hidlSinks,
416 [&](Result r, AudioPatchHandle hidlPatch) {
417 retval = r;
418 if (retval == Result::OK) {
419 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
420 }
421 });
422 } else {
423#if MAJOR_VERSION >= 6
424 ret = mDevice->updateAudioPatch(
425 *patch,
426 hidlSources, hidlSinks,
427 [&](Result r, AudioPatchHandle hidlPatch) {
428 retval = r;
429 if (retval == Result::OK) {
430 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
431 }
432 });
433 methodName = "updateAudioPatch";
434#endif
435 }
436 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800437}
438
439status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700440 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800441 if (mDevice == 0) return NO_INIT;
442 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
443}
444
Mikhail Naganov720cc432021-03-24 20:42:49 -0700445template <typename HalPort>
446status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Mikhail Naganov2d814892023-04-24 13:06:04 -0700447 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800448 if (mDevice == 0) return NO_INIT;
449 AudioPort hidlPort;
450 HidlUtils::audioPortFromHal(*port, &hidlPort);
451 Result retval;
452 Return<void> ret = mDevice->getAudioPort(
453 hidlPort,
454 [&](Result r, const AudioPort& p) {
455 retval = r;
456 if (retval == Result::OK) {
457 HidlUtils::audioPortToHal(p, port);
458 }
459 });
460 return processReturn("getAudioPort", ret, retval);
461}
462
Mikhail Naganov720cc432021-03-24 20:42:49 -0700463status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700464 TIME_CHECK();
Mikhail Naganov720cc432021-03-24 20:42:49 -0700465 return getAudioPortImpl(port);
466}
467
jiabinb4fed192020-09-22 14:45:40 -0700468status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700469 TIME_CHECK();
jiabinb4fed192020-09-22 14:45:40 -0700470#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700471 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700472#else
473 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700474 status_t result = NO_ERROR;
475 if (!audio_populate_audio_port(port, &audioPort)) {
476 ALOGE("Failed to populate legacy audio port from audio_port_v7");
477 result = BAD_VALUE;
478 }
479 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700480 if (status == NO_ERROR) {
481 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700482 } else {
483 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700484 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700485 return result;
jiabinb4fed192020-09-22 14:45:40 -0700486#endif
jiabinb4fed192020-09-22 14:45:40 -0700487}
488
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800489status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
Mikhail Naganov2d814892023-04-24 13:06:04 -0700490 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPortConfig;
Andy Hung224f82f2022-03-22 00:00:49 -0700491 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800492 if (mDevice == 0) return NO_INIT;
493 AudioPortConfig hidlConfig;
494 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
495 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
496}
497
Kevin Rocard070e7512018-05-22 09:29:13 -0700498#if MAJOR_VERSION == 2
499status_t DeviceHalHidl::getMicrophones(
Shunkai Yao51202502022-12-12 06:11:46 +0000500 std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
Kevin Rocard070e7512018-05-22 09:29:13 -0700501 if (mDevice == 0) return NO_INIT;
502 return INVALID_OPERATION;
503}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800504#elif MAJOR_VERSION >= 4
Shunkai Yao51202502022-12-12 06:11:46 +0000505status_t DeviceHalHidl::getMicrophones(
506 std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
Andy Hung224f82f2022-03-22 00:00:49 -0700507 TIME_CHECK();
jiabin9ff780e2018-03-19 18:19:52 -0700508 if (mDevice == 0) return NO_INIT;
509 Result retval;
510 Return<void> ret = mDevice->getMicrophones(
511 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
512 retval = r;
513 for (size_t k = 0; k < micArrayHal.size(); k++) {
514 audio_microphone_characteristic_t dst;
515 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000516 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
Shunkai Yao51202502022-12-12 06:11:46 +0000517 microphonesInfo->push_back(dst);
jiabin9ff780e2018-03-19 18:19:52 -0700518 }
519 });
520 return processReturn("getMicrophones", ret, retval);
521}
Kevin Rocard070e7512018-05-22 09:29:13 -0700522#endif
jiabin9ff780e2018-03-19 18:19:52 -0700523
Eric Laurentb82e6b72019-11-22 17:25:04 -0800524#if MAJOR_VERSION >= 6
525status_t DeviceHalHidl::addDeviceEffect(
526 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700527 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800528 if (mDevice == 0) return NO_INIT;
529 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000530 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800531}
532#else
533status_t DeviceHalHidl::addDeviceEffect(
534 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
535 return INVALID_OPERATION;
536}
537#endif
538
539#if MAJOR_VERSION >= 6
540status_t DeviceHalHidl::removeDeviceEffect(
541 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700542 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800543 if (mDevice == 0) return NO_INIT;
544 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000545 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800546}
547#else
548status_t DeviceHalHidl::removeDeviceEffect(
549 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
550 return INVALID_OPERATION;
551}
552#endif
553
jiabinc0048632023-04-27 22:04:31 +0000554status_t DeviceHalHidl::prepareToDisconnectExternalDevice(const struct audio_port_v7* port) {
555 // For HIDL HAL, there is not API to call notify the HAL to prepare for device connected
556 // state changed. Call `setConnectedState` directly.
557 const status_t status = setConnectedState(port, false /*connected*/);
558 if (status == NO_ERROR) {
559 // Cache the port id so that it won't disconnect twice.
560 mDeviceDisconnectionNotified.insert(port->id);
561 }
562 return status;
563}
564
Mikhail Naganov516d3982022-02-01 23:53:59 +0000565status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
Mikhail Naganov2d814892023-04-24 13:06:04 -0700566 using ::android::hardware::audio::common::COMMON_TYPES_CPP_VERSION::AudioPort;
Andy Hung224f82f2022-03-22 00:00:49 -0700567 TIME_CHECK();
Mikhail Naganov516d3982022-02-01 23:53:59 +0000568 if (mDevice == 0) return NO_INIT;
jiabinc0048632023-04-27 22:04:31 +0000569 if (!connected && mDeviceDisconnectionNotified.erase(port->id) > 0) {
570 // For device disconnection, APM will first call `prepareToDisconnectExternalDevice` and
571 // then call `setConnectedState`. However, in HIDL HAL, there is no API for
572 // `prepareToDisconnectExternalDevice`. In that case, HIDL HAL will call `setConnectedState`
573 // when calling `prepareToDisconnectExternalDevice`. Do not call to the HAL if previous
574 // call is successful. Also remove the cache here to avoid a large cache after a long run.
575 return NO_ERROR;
576 }
Mikhail Naganov516d3982022-02-01 23:53:59 +0000577#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
578 if (supportsSetConnectedState7_1) {
579 AudioPort hidlPort;
580 if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
581 return result;
582 }
583 Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
584 if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
585 return processReturn("setConnectedState_7_1", ret);
586 } else if (ret == Result::OK) {
587 return NO_ERROR;
588 }
589 supportsSetConnectedState7_1 = false;
590 }
591#endif
592 DeviceAddress hidlAddress;
593 if (status_t result = CoreUtils::deviceAddressFromHal(
594 port->ext.device.type, port->ext.device.address, &hidlAddress);
595 result != NO_ERROR) {
596 return result;
597 }
598 return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
599}
600
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800601error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
Andy Hung224f82f2022-03-22 00:00:49 -0700602 TIME_CHECK();
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800603 if (mDevice == 0) return NO_INIT;
604 audio_hw_sync_t value;
605 Result result;
606 Return<void> ret = mDevice->getHwAvSync([&value, &result](Result r, audio_hw_sync_t v) {
607 value = v;
608 result = r;
609 });
610 RETURN_IF_ERROR(processReturn("getHwAvSync", ret, result));
611 return value;
612}
613
Andy Hung61589a42021-06-16 09:37:53 -0700614status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
Andy Hung224f82f2022-03-22 00:00:49 -0700615 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800616 if (mDevice == 0) return NO_INIT;
617 native_handle_t* hidlHandle = native_handle_create(1, 0);
618 hidlHandle->data[0] = fd;
Andy Hung61589a42021-06-16 09:37:53 -0700619 hidl_vec<hidl_string> hidlArgs;
620 argsFromHal(args, &hidlArgs);
621 Return<void> ret = mDevice->debug(hidlHandle, hidlArgs);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800622 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700623
624 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
625 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
626 // when the remote binder thread removes the last refcount to the fd blocks in the
627 // kernel for binder activity. We send a Binder ping() command to unblock the thread
628 // and complete the fd close / release.
629 //
630 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
631 // EffectsFactoryHalHidl::dumpEffects().
632
633 (void)mDevice->ping(); // synchronous Binder call
634
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800635 return processReturn("dump", ret);
636}
637
Vlad Popa03bd5bc2023-01-17 16:16:51 +0100638#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
639status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
640 ::ndk::SpAIBinder* soundDoseBinder) {
641 if (mSoundDoseWrapper->mSoundDose != nullptr) {
642 *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
643 return OK;
644 }
645
646 if (mSoundDoseWrapper->mSoundDoseFactory == nullptr) {
647 std::string interface =
648 std::string(ISoundDoseFactory::descriptor) + kSoundDoseInterfaceModule.data();
649 AIBinder* binder = AServiceManager_checkService(interface.c_str());
650 if (binder == nullptr) {
651 ALOGW("%s service %s doesn't exist", __func__, interface.c_str());
652 return NO_INIT;
653 }
654 mSoundDoseWrapper->mSoundDoseFactory =
655 ISoundDoseFactory::fromBinder(ndk::SpAIBinder(binder));
656 }
657
658 auto result = mSoundDoseWrapper->mSoundDoseFactory->getSoundDose(
659 module, &mSoundDoseWrapper->mSoundDose);
660 if (!result.isOk()) {
661 ALOGW("%s could not get sound dose interface: %s", __func__, result.getMessage());
662 return BAD_VALUE;
663 }
664
665 if (mSoundDoseWrapper->mSoundDose == nullptr) {
666 ALOGW("%s standalone sound dose interface is not implemented", __func__);
667 *soundDoseBinder = nullptr;
668 return OK;
669 }
670
671 *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
672 ALOGI("%s using standalone sound dose interface", __func__);
673 return OK;
674}
675#else
676status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
677 ::ndk::SpAIBinder* soundDoseBinder) {
678 (void)module; // avoid unused param
679 (void)soundDoseBinder; // avoid unused param
680 return INVALID_OPERATION;
681}
682#endif
683
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800684} // namespace android