blob: 7b6d1f8df5d45455b0ea222d1f73e663508f3d1e [file] [log] [blame]
Kevin Rocard4bcd67f2018-02-28 14:33:38 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdio.h>
18
19#define LOG_TAG "DeviceHalHidl"
20//#define LOG_NDEBUG 0
21
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080022#include <cutils/native_handle.h>
23#include <hwbinder/IPCThreadState.h>
jiabindaf49952019-11-22 14:10:57 -080024#include <media/AudioContainers.h>
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080025#include <utils/Log.h>
26
Mikhail Naganovcc73ef02020-11-06 10:09:52 -080027#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
28#include <HidlUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080029#include <common/all-versions/VersionUtils.h>
Mikhail Naganovcc73ef02020-11-06 10:09:52 -080030#include <util/CoreUtils.h>
Kevin Rocardb9cfbf12018-02-23 19:11:06 -080031
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080032#include "DeviceHalHidl.h"
Eric Laurentb82e6b72019-11-22 17:25:04 -080033#include "EffectHalHidl.h"
Mikhail Naganovcc73ef02020-11-06 10:09:52 -080034#include "ParameterUtils.h"
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080035#include "StreamHalHidl.h"
36
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080037using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
Kevin Rocard7a9f05a2018-11-28 16:52:25 -080038using ::android::hardware::audio::common::utils::EnumBitfield;
Mikhail Naganovcc73ef02020-11-06 10:09:52 -080039using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080040using ::android::hardware::hidl_string;
41using ::android::hardware::hidl_vec;
42
43namespace android {
Kevin Rocard070e7512018-05-22 09:29:13 -070044namespace CPP_VERSION {
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080045
Mikhail Naganov9ccaa162018-12-12 10:27:29 -080046using namespace ::android::hardware::audio::common::CPP_VERSION;
47using namespace ::android::hardware::audio::CPP_VERSION;
48
Eric Laurentb82e6b72019-11-22 17:25:04 -080049using EffectHalHidl = ::android::effect::CPP_VERSION::EffectHalHidl;
50
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080051DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
52 : ConversionHelperHidl("Device"), mDevice(device),
53 mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
54}
55
56DeviceHalHidl::~DeviceHalHidl() {
57 if (mDevice != 0) {
Mikhail Naganov3355e442019-11-20 14:20:01 -080058#if MAJOR_VERSION <= 5
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080059 mDevice.clear();
60 hardware::IPCThreadState::self()->flushCommands();
Mikhail Naganov3355e442019-11-20 14:20:01 -080061#elif MAJOR_VERSION >= 6
62 mDevice->close();
63#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080064 }
65}
66
67status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
68 // Obsolete.
69 return INVALID_OPERATION;
70}
71
72status_t DeviceHalHidl::initCheck() {
73 if (mDevice == 0) return NO_INIT;
74 return processReturn("initCheck", mDevice->initCheck());
75}
76
77status_t DeviceHalHidl::setVoiceVolume(float volume) {
78 if (mDevice == 0) return NO_INIT;
79 if (mPrimaryDevice == 0) return INVALID_OPERATION;
80 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
81}
82
83status_t DeviceHalHidl::setMasterVolume(float volume) {
84 if (mDevice == 0) return NO_INIT;
Mikhail Naganovae1f6622019-02-21 15:20:05 -080085 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080086}
87
88status_t DeviceHalHidl::getMasterVolume(float *volume) {
89 if (mDevice == 0) return NO_INIT;
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080090 Result retval;
Mikhail Naganovae1f6622019-02-21 15:20:05 -080091 Return<void> ret = mDevice->getMasterVolume(
Kevin Rocard4bcd67f2018-02-28 14:33:38 -080092 [&](Result r, float v) {
93 retval = r;
94 if (retval == Result::OK) {
95 *volume = v;
96 }
97 });
98 return processReturn("getMasterVolume", ret, retval);
99}
100
101status_t DeviceHalHidl::setMode(audio_mode_t mode) {
102 if (mDevice == 0) return NO_INIT;
103 if (mPrimaryDevice == 0) return INVALID_OPERATION;
104 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
105}
106
107status_t DeviceHalHidl::setMicMute(bool state) {
108 if (mDevice == 0) return NO_INIT;
109 return processReturn("setMicMute", mDevice->setMicMute(state));
110}
111
112status_t DeviceHalHidl::getMicMute(bool *state) {
113 if (mDevice == 0) return NO_INIT;
114 Result retval;
115 Return<void> ret = mDevice->getMicMute(
116 [&](Result r, bool mute) {
117 retval = r;
118 if (retval == Result::OK) {
119 *state = mute;
120 }
121 });
122 return processReturn("getMicMute", ret, retval);
123}
124
125status_t DeviceHalHidl::setMasterMute(bool state) {
126 if (mDevice == 0) return NO_INIT;
127 return processReturn("setMasterMute", mDevice->setMasterMute(state));
128}
129
130status_t DeviceHalHidl::getMasterMute(bool *state) {
131 if (mDevice == 0) return NO_INIT;
132 Result retval;
133 Return<void> ret = mDevice->getMasterMute(
134 [&](Result r, bool mute) {
135 retval = r;
136 if (retval == Result::OK) {
137 *state = mute;
138 }
139 });
140 return processReturn("getMasterMute", ret, retval);
141}
142
143status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
144 if (mDevice == 0) return NO_INIT;
145 hidl_vec<ParameterValue> hidlParams;
146 status_t status = parametersFromHal(kvPairs, &hidlParams);
147 if (status != OK) return status;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800148 // TODO: change the API so that context and kvPairs are separated
149 return processReturn("setParameters",
150 utils::setParameters(mDevice, {} /* context */, hidlParams));
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800151}
152
153status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
154 values->clear();
155 if (mDevice == 0) return NO_INIT;
156 hidl_vec<hidl_string> hidlKeys;
157 status_t status = keysFromHal(keys, &hidlKeys);
158 if (status != OK) return status;
159 Result retval;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800160 Return<void> ret = utils::getParameters(mDevice,
161 {} /* context */,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800162 hidlKeys,
163 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
164 retval = r;
165 if (retval == Result::OK) {
166 parametersToHal(parameters, values);
167 }
168 });
169 return processReturn("getParameters", ret, retval);
170}
171
172status_t DeviceHalHidl::getInputBufferSize(
173 const struct audio_config *config, size_t *size) {
174 if (mDevice == 0) return NO_INIT;
175 AudioConfig hidlConfig;
Mikhail Naganovf242ab22020-12-14 23:19:54 +0000176 HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800177 Result retval;
178 Return<void> ret = mDevice->getInputBufferSize(
179 hidlConfig,
180 [&](Result r, uint64_t bufferSize) {
181 retval = r;
182 if (retval == Result::OK) {
183 *size = static_cast<size_t>(bufferSize);
184 }
185 });
186 return processReturn("getInputBufferSize", ret, retval);
187}
188
189status_t DeviceHalHidl::openOutputStream(
190 audio_io_handle_t handle,
jiabin43810402019-10-24 14:58:31 -0700191 audio_devices_t deviceType,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800192 audio_output_flags_t flags,
193 struct audio_config *config,
194 const char *address,
195 sp<StreamOutHalInterface> *outStream) {
196 if (mDevice == 0) return NO_INIT;
197 DeviceAddress hidlDevice;
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800198 if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
199 status != OK) {
200 return status;
201 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800202 AudioConfig hidlConfig;
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800203 if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
204 status != OK) {
205 return status;
206 }
207 CoreUtils::AudioOutputFlags hidlFlags;
208 if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
209 return status;
210 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800211 Result retval = Result::NOT_INITIALIZED;
212 Return<void> ret = mDevice->openOutputStream(
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800213 handle, hidlDevice, hidlConfig, hidlFlags,
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800214#if MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800215 {} /* metadata */,
Kevin Rocard070e7512018-05-22 09:29:13 -0700216#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800217 [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
218 retval = r;
219 if (retval == Result::OK) {
220 *outStream = new StreamOutHalHidl(result);
221 }
222 HidlUtils::audioConfigToHal(suggestedConfig, config);
223 });
224 return processReturn("openOutputStream", ret, retval);
225}
226
227status_t DeviceHalHidl::openInputStream(
228 audio_io_handle_t handle,
229 audio_devices_t devices,
230 struct audio_config *config,
231 audio_input_flags_t flags,
232 const char *address,
233 audio_source_t source,
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800234 audio_devices_t outputDevice,
235 const char *outputDeviceAddress,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800236 sp<StreamInHalInterface> *inStream) {
237 if (mDevice == 0) return NO_INIT;
238 DeviceAddress hidlDevice;
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800239 if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
240 status != OK) {
241 return status;
242 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800243 AudioConfig hidlConfig;
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800244 if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
245 status != OK) {
246 return status;
247 }
248 CoreUtils::AudioInputFlags hidlFlags;
249 if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
250 return status;
251 }
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800252 Result retval = Result::NOT_INITIALIZED;
Kevin Rocard070e7512018-05-22 09:29:13 -0700253#if MAJOR_VERSION == 2
Mikhail Naganovd9499eb2018-12-17 16:23:22 -0800254 auto sinkMetadata = AudioSource(source);
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800255#elif MAJOR_VERSION >= 4
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800256 // TODO: correctly propagate the tracks sources and volume
257 // for now, only send the main source at 1dbfs
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800258 AudioSource hidlSource;
259 if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
260 return status;
261 }
262 SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
Kevin Rocard070e7512018-05-22 09:29:13 -0700263#endif
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800264#if MAJOR_VERSION < 5
265 (void)outputDevice;
266 (void)outputDeviceAddress;
267#else
268 if (outputDevice != AUDIO_DEVICE_NONE) {
269 DeviceAddress hidlOutputDevice;
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800270 if (status_t status = CoreUtils::deviceAddressFromHal(
271 outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
272 return status;
273 }
Mikhail Naganovb4e037e2019-01-14 15:56:33 -0800274 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
275 }
276#endif
Mikhail Naganovbad15102019-12-10 16:44:19 -0800277#if MAJOR_VERSION <= 5
278 // Some flags were specific to framework and must not leak to the HAL.
279 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
280#endif
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800281 Return<void> ret = mDevice->openInputStream(
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800282 handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800283 [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
284 retval = r;
285 if (retval == Result::OK) {
286 *inStream = new StreamInHalHidl(result);
287 }
288 HidlUtils::audioConfigToHal(suggestedConfig, config);
289 });
290 return processReturn("openInputStream", ret, retval);
291}
292
293status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
294 if (mDevice == 0) return NO_INIT;
295 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
296}
297
298status_t DeviceHalHidl::createAudioPatch(
299 unsigned int num_sources,
300 const struct audio_port_config *sources,
301 unsigned int num_sinks,
302 const struct audio_port_config *sinks,
303 audio_patch_handle_t *patch) {
304 if (mDevice == 0) return NO_INIT;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700305 if (patch == nullptr) return BAD_VALUE;
306
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800307#if MAJOR_VERSION < 6
Eric Laurent8711cfd2019-06-10 18:06:33 -0700308 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
309 status_t status = releaseAudioPatch(*patch);
310 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
311 __func__, status, *patch);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800312 *patch = AUDIO_PATCH_HANDLE_NONE;
Eric Laurent8711cfd2019-06-10 18:06:33 -0700313 }
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800314#endif
Eric Laurent8711cfd2019-06-10 18:06:33 -0700315
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800316 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
317 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
318 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
Mikhail Naganov73bdf572019-12-11 12:34:15 -0800319 Result retval = Result::OK;
320 Return<void> ret;
321 std::string methodName = "createAudioPatch";
322 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
323 ret = mDevice->createAudioPatch(
324 hidlSources, hidlSinks,
325 [&](Result r, AudioPatchHandle hidlPatch) {
326 retval = r;
327 if (retval == Result::OK) {
328 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
329 }
330 });
331 } else {
332#if MAJOR_VERSION >= 6
333 ret = mDevice->updateAudioPatch(
334 *patch,
335 hidlSources, hidlSinks,
336 [&](Result r, AudioPatchHandle hidlPatch) {
337 retval = r;
338 if (retval == Result::OK) {
339 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
340 }
341 });
342 methodName = "updateAudioPatch";
343#endif
344 }
345 return processReturn(methodName.c_str(), ret, retval);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800346}
347
348status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
349 if (mDevice == 0) return NO_INIT;
350 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
351}
352
353status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
354 if (mDevice == 0) return NO_INIT;
355 AudioPort hidlPort;
356 HidlUtils::audioPortFromHal(*port, &hidlPort);
357 Result retval;
358 Return<void> ret = mDevice->getAudioPort(
359 hidlPort,
360 [&](Result r, const AudioPort& p) {
361 retval = r;
362 if (retval == Result::OK) {
363 HidlUtils::audioPortToHal(p, port);
364 }
365 });
366 return processReturn("getAudioPort", ret, retval);
367}
368
369status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
370 if (mDevice == 0) return NO_INIT;
371 AudioPortConfig hidlConfig;
372 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
373 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
374}
375
Kevin Rocard070e7512018-05-22 09:29:13 -0700376#if MAJOR_VERSION == 2
377status_t DeviceHalHidl::getMicrophones(
378 std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
379 if (mDevice == 0) return NO_INIT;
380 return INVALID_OPERATION;
381}
Kevin Rocard3d48dce2018-11-08 17:16:57 -0800382#elif MAJOR_VERSION >= 4
jiabin9ff780e2018-03-19 18:19:52 -0700383status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
384 if (mDevice == 0) return NO_INIT;
385 Result retval;
386 Return<void> ret = mDevice->getMicrophones(
387 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
388 retval = r;
389 for (size_t k = 0; k < micArrayHal.size(); k++) {
390 audio_microphone_characteristic_t dst;
391 //convert
Mikhail Naganovcc73ef02020-11-06 10:09:52 -0800392 (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
jiabin9ff780e2018-03-19 18:19:52 -0700393 media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
394 microphonesInfo->push_back(microphone);
395 }
396 });
397 return processReturn("getMicrophones", ret, retval);
398}
Kevin Rocard070e7512018-05-22 09:29:13 -0700399#endif
jiabin9ff780e2018-03-19 18:19:52 -0700400
Eric Laurentb82e6b72019-11-22 17:25:04 -0800401#if MAJOR_VERSION >= 6
402status_t DeviceHalHidl::addDeviceEffect(
403 audio_port_handle_t device, sp<EffectHalInterface> effect) {
404 if (mDevice == 0) return NO_INIT;
405 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
406 static_cast<AudioPortHandle>(device),
407 static_cast<EffectHalHidl*>(effect.get())->effectId()));
408}
409#else
410status_t DeviceHalHidl::addDeviceEffect(
411 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
412 return INVALID_OPERATION;
413}
414#endif
415
416#if MAJOR_VERSION >= 6
417status_t DeviceHalHidl::removeDeviceEffect(
418 audio_port_handle_t device, sp<EffectHalInterface> effect) {
419 if (mDevice == 0) return NO_INIT;
420 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
421 static_cast<AudioPortHandle>(device),
422 static_cast<EffectHalHidl*>(effect.get())->effectId()));
423}
424#else
425status_t DeviceHalHidl::removeDeviceEffect(
426 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
427 return INVALID_OPERATION;
428}
429#endif
430
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800431status_t DeviceHalHidl::dump(int fd) {
432 if (mDevice == 0) return NO_INIT;
433 native_handle_t* hidlHandle = native_handle_create(1, 0);
434 hidlHandle->data[0] = fd;
Kevin Rocardb9cfbf12018-02-23 19:11:06 -0800435 Return<void> ret = mDevice->debug(hidlHandle, {} /* options */);
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800436 native_handle_delete(hidlHandle);
437 return processReturn("dump", ret);
438}
439
Kevin Rocard070e7512018-05-22 09:29:13 -0700440} // namespace CPP_VERSION
Kevin Rocard4bcd67f2018-02-28 14:33:38 -0800441} // namespace android