blob: e0b1afb96d03b1ee02323896883d17a52a6fca1a [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
107status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
108 // Obsolete.
109 return INVALID_OPERATION;
110}
111
112status_t DeviceHalHidl::initCheck() {
Andy Hung224f82f2022-03-22 00:00:49 -0700113 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800114 if (mDevice == 0) return NO_INIT;
115 return processReturn("initCheck", mDevice->initCheck());
116}
117
118status_t DeviceHalHidl::setVoiceVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700119 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800120 if (mDevice == 0) return NO_INIT;
121 if (mPrimaryDevice == 0) return INVALID_OPERATION;
122 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
123}
124
125status_t DeviceHalHidl::setMasterVolume(float volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700126 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800127 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800128 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800129}
130
131status_t DeviceHalHidl::getMasterVolume(float *volume) {
Andy Hung224f82f2022-03-22 00:00:49 -0700132 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800133 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800134 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -0800135 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800136 [&](Result r, float v) {
137 retval = r;
138 if (retval == Result::OK) {
139 *volume = v;
140 }
141 });
142 return processReturn("getMasterVolume", ret, retval);
143}
144
145status_t DeviceHalHidl::setMode(audio_mode_t mode) {
Andy Hung224f82f2022-03-22 00:00:49 -0700146 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800147 if (mDevice == 0) return NO_INIT;
148 if (mPrimaryDevice == 0) return INVALID_OPERATION;
149 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
150}
151
152status_t DeviceHalHidl::setMicMute(bool state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700153 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800154 if (mDevice == 0) return NO_INIT;
155 return processReturn("setMicMute", mDevice->setMicMute(state));
156}
157
158status_t DeviceHalHidl::getMicMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700159 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800160 if (mDevice == 0) return NO_INIT;
161 Result retval;
162 Return<void> ret = mDevice->getMicMute(
163 [&](Result r, bool mute) {
164 retval = r;
165 if (retval == Result::OK) {
166 *state = mute;
167 }
168 });
169 return processReturn("getMicMute", ret, retval);
170}
171
172status_t DeviceHalHidl::setMasterMute(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 return processReturn("setMasterMute", mDevice->setMasterMute(state));
176}
177
178status_t DeviceHalHidl::getMasterMute(bool *state) {
Andy Hung224f82f2022-03-22 00:00:49 -0700179 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800180 if (mDevice == 0) return NO_INIT;
181 Result retval;
182 Return<void> ret = mDevice->getMasterMute(
183 [&](Result r, bool mute) {
184 retval = r;
185 if (retval == Result::OK) {
186 *state = mute;
187 }
188 });
189 return processReturn("getMasterMute", ret, retval);
190}
191
192status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
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 hidl_vec<ParameterValue> hidlParams;
196 status_t status = parametersFromHal(kvPairs, &hidlParams);
197 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800198 // TODO: change the API so that context and kvPairs are separated
199 return processReturn("setParameters",
200 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800201}
202
203status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
Andy Hung224f82f2022-03-22 00:00:49 -0700204 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800205 values->clear();
206 if (mDevice == 0) return NO_INIT;
207 hidl_vec<hidl_string> hidlKeys;
208 status_t status = keysFromHal(keys, &hidlKeys);
209 if (status != OK) return status;
210 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800211 Return<void> ret = utils::getParameters(mDevice,
212 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800213 hidlKeys,
214 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
215 retval = r;
216 if (retval == Result::OK) {
217 parametersToHal(parameters, values);
218 }
219 });
220 return processReturn("getParameters", ret, retval);
221}
222
223status_t DeviceHalHidl::getInputBufferSize(
224 const struct audio_config *config, size_t *size) {
Andy Hung224f82f2022-03-22 00:00:49 -0700225 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800226 if (mDevice == 0) return NO_INIT;
227 AudioConfig hidlConfig;
Mikhail Naganov05e03192020-12-14 23:19:54 +0000228 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800229 Result retval;
230 Return<void> ret = mDevice->getInputBufferSize(
231 hidlConfig,
232 [&](Result r, uint64_t bufferSize) {
233 retval = r;
234 if (retval == Result::OK) {
235 *size = static_cast<size_t>(bufferSize);
236 }
237 });
238 return processReturn("getInputBufferSize", ret, retval);
239}
240
241status_t DeviceHalHidl::openOutputStream(
242 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700243 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800244 audio_output_flags_t flags,
245 struct audio_config *config,
246 const char *address,
247 sp<StreamOutHalInterface> *outStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700248 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800249 if (mDevice == 0) return NO_INIT;
250 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000251 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
252 status != OK) {
253 return status;
254 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800255 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000256 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
257 status != OK) {
258 return status;
259 }
Eric Laurente28c66d2022-01-21 13:40:41 +0100260
261#if !(MAJOR_VERSION == 7 && MINOR_VERSION == 1)
262 //TODO: b/193496180 use spatializer flag at audio HAL when available
263 if ((flags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
264 flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_SPATIALIZER);
265 flags = (audio_output_flags_t)
266 (flags | AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
267 }
268#endif
269
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000270 CoreUtils::AudioOutputFlags hidlFlags;
271 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
272 return status;
273 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800274 Result retval = Result::NOT_INITIALIZED;
Mikhail Naganov6718c392022-01-27 22:17:21 +0000275#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
276 Return<void> ret = mDevice->openOutputStream_7_1(
277#else
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800278 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000279#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000280 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800281#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800282 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700283#endif
Mikhail Naganov6718c392022-01-27 22:17:21 +0000284 [&](Result r, const sp<::android::hardware::audio::CPP_VERSION::IStreamOut>& result,
285 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800286 retval = r;
287 if (retval == Result::OK) {
288 *outStream = new StreamOutHalHidl(result);
289 }
290 HidlUtils::audioConfigToHal(suggestedConfig, config);
291 });
292 return processReturn("openOutputStream", ret, retval);
293}
294
295status_t DeviceHalHidl::openInputStream(
296 audio_io_handle_t handle,
297 audio_devices_t devices,
298 struct audio_config *config,
299 audio_input_flags_t flags,
300 const char *address,
301 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800302 audio_devices_t outputDevice,
303 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800304 sp<StreamInHalInterface> *inStream) {
Andy Hung224f82f2022-03-22 00:00:49 -0700305 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800306 if (mDevice == 0) return NO_INIT;
307 DeviceAddress hidlDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000308 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
309 status != OK) {
310 return status;
311 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800312 AudioConfig hidlConfig;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000313 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
314 status != OK) {
315 return status;
316 }
317 CoreUtils::AudioInputFlags hidlFlags;
Dean Wheatleyea186342021-03-12 16:49:47 +1100318#if MAJOR_VERSION <= 5
319 // Some flags were specific to framework and must not leak to the HAL.
320 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
321#endif
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000322 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
323 return status;
324 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800325 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700326#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800327 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800328#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800329 // TODO: correctly propagate the tracks sources and volume
330 // for now, only send the main source at 1dbfs
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000331 AudioSource hidlSource;
332 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
333 return status;
334 }
335 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700336#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800337#if MAJOR_VERSION < 5
338 (void)outputDevice;
339 (void)outputDeviceAddress;
340#else
Mikhail Naganovc4258802021-02-08 17:14:17 -0800341#if MAJOR_VERSION >= 7
342 (void)HidlUtils::audioChannelMaskFromHal(
343 AUDIO_CHANNEL_NONE, true /*isInput*/, &sinkMetadata.tracks[0].channelMask);
344#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800345 if (outputDevice != AUDIO_DEVICE_NONE) {
346 DeviceAddress hidlOutputDevice;
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000347 if (status_t status = CoreUtils::deviceAddressFromHal(
348 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
349 return status;
350 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800351 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
352 }
353#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800354 Return<void> ret = mDevice->openInputStream(
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000355 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Mikhail Naganovaccbe8a2022-02-03 23:45:36 +0000356 [&](Result r,
357 const sp<::android::hardware::audio::CORE_TYPES_CPP_VERSION::IStreamIn>& result,
Mikhail Naganov6718c392022-01-27 22:17:21 +0000358 const AudioConfig& suggestedConfig) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800359 retval = r;
360 if (retval == Result::OK) {
361 *inStream = new StreamInHalHidl(result);
362 }
363 HidlUtils::audioConfigToHal(suggestedConfig, config);
364 });
365 return processReturn("openInputStream", ret, retval);
366}
367
368status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
Andy Hung224f82f2022-03-22 00:00:49 -0700369 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800370 if (mDevice == 0) return NO_INIT;
371 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
372}
373
374status_t DeviceHalHidl::createAudioPatch(
375 unsigned int num_sources,
376 const struct audio_port_config *sources,
377 unsigned int num_sinks,
378 const struct audio_port_config *sinks,
379 audio_patch_handle_t *patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700380 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800381 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700382 if (patch == nullptr) return BAD_VALUE;
383
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800384#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700385 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
386 status_t status = releaseAudioPatch(*patch);
387 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
388 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800389 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700390 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800391#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700392
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800393 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
394 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
395 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800396 Result retval = Result::OK;
397 Return<void> ret;
398 std::string methodName = "createAudioPatch";
399 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
400 ret = mDevice->createAudioPatch(
401 hidlSources, hidlSinks,
402 [&](Result r, AudioPatchHandle hidlPatch) {
403 retval = r;
404 if (retval == Result::OK) {
405 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
406 }
407 });
408 } else {
409#if MAJOR_VERSION >= 6
410 ret = mDevice->updateAudioPatch(
411 *patch,
412 hidlSources, hidlSinks,
413 [&](Result r, AudioPatchHandle hidlPatch) {
414 retval = r;
415 if (retval == Result::OK) {
416 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
417 }
418 });
419 methodName = "updateAudioPatch";
420#endif
421 }
422 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800423}
424
425status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
Andy Hung224f82f2022-03-22 00:00:49 -0700426 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800427 if (mDevice == 0) return NO_INIT;
428 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
429}
430
Mikhail Naganov720cc432021-03-24 20:42:49 -0700431template <typename HalPort>
432status_t DeviceHalHidl::getAudioPortImpl(HalPort *port) {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800433 if (mDevice == 0) return NO_INIT;
434 AudioPort hidlPort;
435 HidlUtils::audioPortFromHal(*port, &hidlPort);
436 Result retval;
437 Return<void> ret = mDevice->getAudioPort(
438 hidlPort,
439 [&](Result r, const AudioPort& p) {
440 retval = r;
441 if (retval == Result::OK) {
442 HidlUtils::audioPortToHal(p, port);
443 }
444 });
445 return processReturn("getAudioPort", ret, retval);
446}
447
Mikhail Naganov720cc432021-03-24 20:42:49 -0700448status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700449 TIME_CHECK();
Mikhail Naganov720cc432021-03-24 20:42:49 -0700450 return getAudioPortImpl(port);
451}
452
jiabinb4fed192020-09-22 14:45:40 -0700453status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
Andy Hung224f82f2022-03-22 00:00:49 -0700454 TIME_CHECK();
jiabinb4fed192020-09-22 14:45:40 -0700455#if MAJOR_VERSION >= 7
Mikhail Naganov720cc432021-03-24 20:42:49 -0700456 return getAudioPortImpl(port);
jiabinb4fed192020-09-22 14:45:40 -0700457#else
458 struct audio_port audioPort = {};
Mikhail Naganov720cc432021-03-24 20:42:49 -0700459 status_t result = NO_ERROR;
460 if (!audio_populate_audio_port(port, &audioPort)) {
461 ALOGE("Failed to populate legacy audio port from audio_port_v7");
462 result = BAD_VALUE;
463 }
464 status_t status = getAudioPort(&audioPort);
jiabinb4fed192020-09-22 14:45:40 -0700465 if (status == NO_ERROR) {
466 audio_populate_audio_port_v7(&audioPort, port);
Mikhail Naganov720cc432021-03-24 20:42:49 -0700467 } else {
468 result = status;
jiabinb4fed192020-09-22 14:45:40 -0700469 }
Mikhail Naganov720cc432021-03-24 20:42:49 -0700470 return result;
jiabinb4fed192020-09-22 14:45:40 -0700471#endif
jiabinb4fed192020-09-22 14:45:40 -0700472}
473
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800474status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
Andy Hung224f82f2022-03-22 00:00:49 -0700475 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800476 if (mDevice == 0) return NO_INIT;
477 AudioPortConfig hidlConfig;
478 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
479 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
480}
481
Kevin Rocard070e7512018-05-22 09:29:13 -0700482#if MAJOR_VERSION == 2
483status_t DeviceHalHidl::getMicrophones(
Shunkai Yao51202502022-12-12 06:11:46 +0000484 std::vector<audio_microphone_characteristic_t> *microphonesInfo __unused) {
Kevin Rocard070e7512018-05-22 09:29:13 -0700485 if (mDevice == 0) return NO_INIT;
486 return INVALID_OPERATION;
487}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800488#elif MAJOR_VERSION >= 4
Shunkai Yao51202502022-12-12 06:11:46 +0000489status_t DeviceHalHidl::getMicrophones(
490 std::vector<audio_microphone_characteristic_t> *microphonesInfo) {
Andy Hung224f82f2022-03-22 00:00:49 -0700491 TIME_CHECK();
jiabin9ff780e2018-03-19 18:19:52 -0700492 if (mDevice == 0) return NO_INIT;
493 Result retval;
494 Return<void> ret = mDevice->getMicrophones(
495 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
496 retval = r;
497 for (size_t k = 0; k < micArrayHal.size(); k++) {
498 audio_microphone_characteristic_t dst;
499 //convert
Mikhail Naganov247b5f92021-01-15 19:16:12 +0000500 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
Shunkai Yao51202502022-12-12 06:11:46 +0000501 microphonesInfo->push_back(dst);
jiabin9ff780e2018-03-19 18:19:52 -0700502 }
503 });
504 return processReturn("getMicrophones", ret, retval);
505}
Kevin Rocard070e7512018-05-22 09:29:13 -0700506#endif
jiabin9ff780e2018-03-19 18:19:52 -0700507
Eric Laurentb82e6b72019-11-22 17:25:04 -0800508#if MAJOR_VERSION >= 6
509status_t DeviceHalHidl::addDeviceEffect(
510 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700511 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800512 if (mDevice == 0) return NO_INIT;
513 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000514 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800515}
516#else
517status_t DeviceHalHidl::addDeviceEffect(
518 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
519 return INVALID_OPERATION;
520}
521#endif
522
523#if MAJOR_VERSION >= 6
524status_t DeviceHalHidl::removeDeviceEffect(
525 audio_port_handle_t device, sp<EffectHalInterface> effect) {
Andy Hung224f82f2022-03-22 00:00:49 -0700526 TIME_CHECK();
Eric Laurentb82e6b72019-11-22 17:25:04 -0800527 if (mDevice == 0) return NO_INIT;
528 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
Mikhail Naganov6718c392022-01-27 22:17:21 +0000529 static_cast<AudioPortHandle>(device), effect->effectId()));
Eric Laurentb82e6b72019-11-22 17:25:04 -0800530}
531#else
532status_t DeviceHalHidl::removeDeviceEffect(
533 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
534 return INVALID_OPERATION;
535}
536#endif
537
Mikhail Naganov516d3982022-02-01 23:53:59 +0000538status_t DeviceHalHidl::setConnectedState(const struct audio_port_v7 *port, bool connected) {
Andy Hung224f82f2022-03-22 00:00:49 -0700539 TIME_CHECK();
Mikhail Naganov516d3982022-02-01 23:53:59 +0000540 if (mDevice == 0) return NO_INIT;
541#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
542 if (supportsSetConnectedState7_1) {
543 AudioPort hidlPort;
544 if (status_t result = HidlUtils::audioPortFromHal(*port, &hidlPort); result != NO_ERROR) {
545 return result;
546 }
547 Return<Result> ret = mDevice->setConnectedState_7_1(hidlPort, connected);
548 if (!ret.isOk() || ret != Result::NOT_SUPPORTED) {
549 return processReturn("setConnectedState_7_1", ret);
550 } else if (ret == Result::OK) {
551 return NO_ERROR;
552 }
553 supportsSetConnectedState7_1 = false;
554 }
555#endif
556 DeviceAddress hidlAddress;
557 if (status_t result = CoreUtils::deviceAddressFromHal(
558 port->ext.device.type, port->ext.device.address, &hidlAddress);
559 result != NO_ERROR) {
560 return result;
561 }
562 return processReturn("setConnectedState", mDevice->setConnectedState(hidlAddress, connected));
563}
564
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800565error::Result<audio_hw_sync_t> DeviceHalHidl::getHwAvSync() {
Andy Hung224f82f2022-03-22 00:00:49 -0700566 TIME_CHECK();
Ytai Ben-Tsvi48287b52021-12-01 15:07:11 -0800567 if (mDevice == 0) return NO_INIT;
568 audio_hw_sync_t value;
569 Result result;
570 Return<void> ret = mDevice->getHwAvSync([&value, &result](Result r, audio_hw_sync_t v) {
571 value = v;
572 result = r;
573 });
574 RETURN_IF_ERROR(processReturn("getHwAvSync", ret, result));
575 return value;
576}
577
Andy Hung61589a42021-06-16 09:37:53 -0700578status_t DeviceHalHidl::dump(int fd, const Vector<String16>& args) {
Andy Hung224f82f2022-03-22 00:00:49 -0700579 TIME_CHECK();
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800580 if (mDevice == 0) return NO_INIT;
581 native_handle_t* hidlHandle = native_handle_create(1, 0);
582 hidlHandle->data[0] = fd;
Andy Hung61589a42021-06-16 09:37:53 -0700583 hidl_vec<hidl_string> hidlArgs;
584 argsFromHal(args, &hidlArgs);
585 Return<void> ret = mDevice->debug(hidlHandle, hidlArgs);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800586 native_handle_delete(hidlHandle);
Andy Hunge72ff022021-08-16 10:16:15 -0700587
588 // TODO(b/111997867, b/177271958) Workaround - remove when fixed.
589 // A Binder transmitted fd may not close immediately due to a race condition b/111997867
590 // when the remote binder thread removes the last refcount to the fd blocks in the
591 // kernel for binder activity. We send a Binder ping() command to unblock the thread
592 // and complete the fd close / release.
593 //
594 // See DeviceHalHidl::dump(), EffectHalHidl::dump(), StreamHalHidl::dump(),
595 // EffectsFactoryHalHidl::dumpEffects().
596
597 (void)mDevice->ping(); // synchronous Binder call
598
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800599 return processReturn("dump", ret);
600}
601
Vlad Popa03bd5bc2023-01-17 16:16:51 +0100602#if MAJOR_VERSION == 7 && MINOR_VERSION == 1
603status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
604 ::ndk::SpAIBinder* soundDoseBinder) {
605 if (mSoundDoseWrapper->mSoundDose != nullptr) {
606 *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
607 return OK;
608 }
609
610 if (mSoundDoseWrapper->mSoundDoseFactory == nullptr) {
611 std::string interface =
612 std::string(ISoundDoseFactory::descriptor) + kSoundDoseInterfaceModule.data();
613 AIBinder* binder = AServiceManager_checkService(interface.c_str());
614 if (binder == nullptr) {
615 ALOGW("%s service %s doesn't exist", __func__, interface.c_str());
616 return NO_INIT;
617 }
618 mSoundDoseWrapper->mSoundDoseFactory =
619 ISoundDoseFactory::fromBinder(ndk::SpAIBinder(binder));
620 }
621
622 auto result = mSoundDoseWrapper->mSoundDoseFactory->getSoundDose(
623 module, &mSoundDoseWrapper->mSoundDose);
624 if (!result.isOk()) {
625 ALOGW("%s could not get sound dose interface: %s", __func__, result.getMessage());
626 return BAD_VALUE;
627 }
628
629 if (mSoundDoseWrapper->mSoundDose == nullptr) {
630 ALOGW("%s standalone sound dose interface is not implemented", __func__);
631 *soundDoseBinder = nullptr;
632 return OK;
633 }
634
635 *soundDoseBinder = mSoundDoseWrapper->mSoundDose->asBinder();
636 ALOGI("%s using standalone sound dose interface", __func__);
637 return OK;
638}
639#else
640status_t DeviceHalHidl::getSoundDoseInterface(const std::string& module,
641 ::ndk::SpAIBinder* soundDoseBinder) {
642 (void)module; // avoid unused param
643 (void)soundDoseBinder; // avoid unused param
644 return INVALID_OPERATION;
645}
646#endif
647
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800648} // namespace android