1 /*
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
22 #include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
23 #include <cutils/native_handle.h>
24 #include <hwbinder/IPCThreadState.h>
25 #include <media/AudioContainers.h>
26 #include <utils/Log.h>
27
28 #include <common/all-versions/VersionUtils.h>
29
30 #include "DeviceHalHidl.h"
31 #include "EffectHalHidl.h"
32 #include "HidlUtils.h"
33 #include "StreamHalHidl.h"
34 #include "VersionUtils.h"
35
36 using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
37 using ::android::hardware::audio::common::utils::EnumBitfield;
38 using ::android::hardware::hidl_string;
39 using ::android::hardware::hidl_vec;
40
41 namespace android {
42 namespace CPP_VERSION {
43
44 using namespace ::android::hardware::audio::common::CPP_VERSION;
45 using namespace ::android::hardware::audio::CPP_VERSION;
46
47 using EffectHalHidl = ::android::effect::CPP_VERSION::EffectHalHidl;
48
49 namespace {
50
deviceAddressFromHal(audio_devices_t device,const char * halAddress,DeviceAddress * address)51 status_t deviceAddressFromHal(
52 audio_devices_t device, const char* halAddress, DeviceAddress* address) {
53 address->device = AudioDevice(device);
54
55 if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
56 return OK;
57 }
58 if (getAudioDeviceOutAllA2dpSet().count(device) > 0
59 || device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
60 int status = sscanf(halAddress,
61 "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
62 &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
63 &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
64 return status == 6 ? OK : BAD_VALUE;
65 } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
66 int status = sscanf(halAddress,
67 "%hhu.%hhu.%hhu.%hhu",
68 &address->address.ipv4[0], &address->address.ipv4[1],
69 &address->address.ipv4[2], &address->address.ipv4[3]);
70 return status == 4 ? OK : BAD_VALUE;
71 } else if (getAudioDeviceOutAllUsbSet().count(device) > 0
72 || getAudioDeviceInAllUsbSet().count(device) > 0) {
73 int status = sscanf(halAddress,
74 "card=%d;device=%d",
75 &address->address.alsa.card, &address->address.alsa.device);
76 return status == 2 ? OK : BAD_VALUE;
77 } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
78 address->busAddress = halAddress;
79 return OK;
80 } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
81 || device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
82 address->rSubmixAddress = halAddress;
83 return OK;
84 }
85 return OK;
86 }
87
88 } // namespace
89
DeviceHalHidl(const sp<IDevice> & device)90 DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
91 : ConversionHelperHidl("Device"), mDevice(device),
92 mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
93 }
94
~DeviceHalHidl()95 DeviceHalHidl::~DeviceHalHidl() {
96 if (mDevice != 0) {
97 #if MAJOR_VERSION <= 5
98 mDevice.clear();
99 hardware::IPCThreadState::self()->flushCommands();
100 #elif MAJOR_VERSION >= 6
101 mDevice->close();
102 #endif
103 }
104 }
105
getSupportedDevices(uint32_t *)106 status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
107 // Obsolete.
108 return INVALID_OPERATION;
109 }
110
initCheck()111 status_t DeviceHalHidl::initCheck() {
112 if (mDevice == 0) return NO_INIT;
113 return processReturn("initCheck", mDevice->initCheck());
114 }
115
setVoiceVolume(float volume)116 status_t DeviceHalHidl::setVoiceVolume(float volume) {
117 if (mDevice == 0) return NO_INIT;
118 if (mPrimaryDevice == 0) return INVALID_OPERATION;
119 return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
120 }
121
setMasterVolume(float volume)122 status_t DeviceHalHidl::setMasterVolume(float volume) {
123 if (mDevice == 0) return NO_INIT;
124 return processReturn("setMasterVolume", mDevice->setMasterVolume(volume));
125 }
126
getMasterVolume(float * volume)127 status_t DeviceHalHidl::getMasterVolume(float *volume) {
128 if (mDevice == 0) return NO_INIT;
129 Result retval;
130 Return<void> ret = mDevice->getMasterVolume(
131 [&](Result r, float v) {
132 retval = r;
133 if (retval == Result::OK) {
134 *volume = v;
135 }
136 });
137 return processReturn("getMasterVolume", ret, retval);
138 }
139
setMode(audio_mode_t mode)140 status_t DeviceHalHidl::setMode(audio_mode_t mode) {
141 if (mDevice == 0) return NO_INIT;
142 if (mPrimaryDevice == 0) return INVALID_OPERATION;
143 return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
144 }
145
setMicMute(bool state)146 status_t DeviceHalHidl::setMicMute(bool state) {
147 if (mDevice == 0) return NO_INIT;
148 return processReturn("setMicMute", mDevice->setMicMute(state));
149 }
150
getMicMute(bool * state)151 status_t DeviceHalHidl::getMicMute(bool *state) {
152 if (mDevice == 0) return NO_INIT;
153 Result retval;
154 Return<void> ret = mDevice->getMicMute(
155 [&](Result r, bool mute) {
156 retval = r;
157 if (retval == Result::OK) {
158 *state = mute;
159 }
160 });
161 return processReturn("getMicMute", ret, retval);
162 }
163
setMasterMute(bool state)164 status_t DeviceHalHidl::setMasterMute(bool state) {
165 if (mDevice == 0) return NO_INIT;
166 return processReturn("setMasterMute", mDevice->setMasterMute(state));
167 }
168
getMasterMute(bool * state)169 status_t DeviceHalHidl::getMasterMute(bool *state) {
170 if (mDevice == 0) return NO_INIT;
171 Result retval;
172 Return<void> ret = mDevice->getMasterMute(
173 [&](Result r, bool mute) {
174 retval = r;
175 if (retval == Result::OK) {
176 *state = mute;
177 }
178 });
179 return processReturn("getMasterMute", ret, retval);
180 }
181
setParameters(const String8 & kvPairs)182 status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
183 if (mDevice == 0) return NO_INIT;
184 hidl_vec<ParameterValue> hidlParams;
185 status_t status = parametersFromHal(kvPairs, &hidlParams);
186 if (status != OK) return status;
187 // TODO: change the API so that context and kvPairs are separated
188 return processReturn("setParameters",
189 utils::setParameters(mDevice, {} /* context */, hidlParams));
190 }
191
getParameters(const String8 & keys,String8 * values)192 status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
193 values->clear();
194 if (mDevice == 0) return NO_INIT;
195 hidl_vec<hidl_string> hidlKeys;
196 status_t status = keysFromHal(keys, &hidlKeys);
197 if (status != OK) return status;
198 Result retval;
199 Return<void> ret = utils::getParameters(mDevice,
200 {} /* context */,
201 hidlKeys,
202 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
203 retval = r;
204 if (retval == Result::OK) {
205 parametersToHal(parameters, values);
206 }
207 });
208 return processReturn("getParameters", ret, retval);
209 }
210
getInputBufferSize(const struct audio_config * config,size_t * size)211 status_t DeviceHalHidl::getInputBufferSize(
212 const struct audio_config *config, size_t *size) {
213 if (mDevice == 0) return NO_INIT;
214 AudioConfig hidlConfig;
215 HidlUtils::audioConfigFromHal(*config, &hidlConfig);
216 Result retval;
217 Return<void> ret = mDevice->getInputBufferSize(
218 hidlConfig,
219 [&](Result r, uint64_t bufferSize) {
220 retval = r;
221 if (retval == Result::OK) {
222 *size = static_cast<size_t>(bufferSize);
223 }
224 });
225 return processReturn("getInputBufferSize", ret, retval);
226 }
227
openOutputStream(audio_io_handle_t handle,audio_devices_t deviceType,audio_output_flags_t flags,struct audio_config * config,const char * address,sp<StreamOutHalInterface> * outStream)228 status_t DeviceHalHidl::openOutputStream(
229 audio_io_handle_t handle,
230 audio_devices_t deviceType,
231 audio_output_flags_t flags,
232 struct audio_config *config,
233 const char *address,
234 sp<StreamOutHalInterface> *outStream) {
235 if (mDevice == 0) return NO_INIT;
236 DeviceAddress hidlDevice;
237 status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice);
238 if (status != OK) return status;
239 AudioConfig hidlConfig;
240 HidlUtils::audioConfigFromHal(*config, &hidlConfig);
241 Result retval = Result::NOT_INITIALIZED;
242 Return<void> ret = mDevice->openOutputStream(
243 handle,
244 hidlDevice,
245 hidlConfig,
246 EnumBitfield<AudioOutputFlag>(flags),
247 #if MAJOR_VERSION >= 4
248 {} /* metadata */,
249 #endif
250 [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
251 retval = r;
252 if (retval == Result::OK) {
253 *outStream = new StreamOutHalHidl(result);
254 }
255 HidlUtils::audioConfigToHal(suggestedConfig, config);
256 });
257 return processReturn("openOutputStream", ret, retval);
258 }
259
openInputStream(audio_io_handle_t handle,audio_devices_t devices,struct audio_config * config,audio_input_flags_t flags,const char * address,audio_source_t source,audio_devices_t outputDevice,const char * outputDeviceAddress,sp<StreamInHalInterface> * inStream)260 status_t DeviceHalHidl::openInputStream(
261 audio_io_handle_t handle,
262 audio_devices_t devices,
263 struct audio_config *config,
264 audio_input_flags_t flags,
265 const char *address,
266 audio_source_t source,
267 audio_devices_t outputDevice,
268 const char *outputDeviceAddress,
269 sp<StreamInHalInterface> *inStream) {
270 if (mDevice == 0) return NO_INIT;
271 DeviceAddress hidlDevice;
272 status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
273 if (status != OK) return status;
274 AudioConfig hidlConfig;
275 HidlUtils::audioConfigFromHal(*config, &hidlConfig);
276 Result retval = Result::NOT_INITIALIZED;
277 #if MAJOR_VERSION == 2
278 auto sinkMetadata = AudioSource(source);
279 #elif MAJOR_VERSION >= 4
280 // TODO: correctly propagate the tracks sources and volume
281 // for now, only send the main source at 1dbfs
282 SinkMetadata sinkMetadata = {{{ .source = AudioSource(source), .gain = 1 }}};
283 #endif
284 #if MAJOR_VERSION < 5
285 (void)outputDevice;
286 (void)outputDeviceAddress;
287 #else
288 if (outputDevice != AUDIO_DEVICE_NONE) {
289 DeviceAddress hidlOutputDevice;
290 status = deviceAddressFromHal(outputDevice, outputDeviceAddress, &hidlOutputDevice);
291 if (status != OK) return status;
292 sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
293 }
294 #endif
295 #if MAJOR_VERSION <= 5
296 // Some flags were specific to framework and must not leak to the HAL.
297 flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
298 #endif
299 Return<void> ret = mDevice->openInputStream(
300 handle,
301 hidlDevice,
302 hidlConfig,
303 EnumBitfield<AudioInputFlag>(flags),
304 sinkMetadata,
305 [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
306 retval = r;
307 if (retval == Result::OK) {
308 *inStream = new StreamInHalHidl(result);
309 }
310 HidlUtils::audioConfigToHal(suggestedConfig, config);
311 });
312 return processReturn("openInputStream", ret, retval);
313 }
314
supportsAudioPatches(bool * supportsPatches)315 status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
316 if (mDevice == 0) return NO_INIT;
317 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
318 }
319
createAudioPatch(unsigned int num_sources,const struct audio_port_config * sources,unsigned int num_sinks,const struct audio_port_config * sinks,audio_patch_handle_t * patch)320 status_t DeviceHalHidl::createAudioPatch(
321 unsigned int num_sources,
322 const struct audio_port_config *sources,
323 unsigned int num_sinks,
324 const struct audio_port_config *sinks,
325 audio_patch_handle_t *patch) {
326 if (mDevice == 0) return NO_INIT;
327 if (patch == nullptr) return BAD_VALUE;
328
329 #if MAJOR_VERSION < 6
330 if (*patch != AUDIO_PATCH_HANDLE_NONE) {
331 status_t status = releaseAudioPatch(*patch);
332 ALOGW_IF(status != NO_ERROR, "%s error %d releasing patch handle %d",
333 __func__, status, *patch);
334 *patch = AUDIO_PATCH_HANDLE_NONE;
335 }
336 #endif
337
338 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
339 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
340 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
341 Result retval = Result::OK;
342 Return<void> ret;
343 std::string methodName = "createAudioPatch";
344 if (*patch == AUDIO_PATCH_HANDLE_NONE) { // always true for MAJOR_VERSION < 6
345 ret = mDevice->createAudioPatch(
346 hidlSources, hidlSinks,
347 [&](Result r, AudioPatchHandle hidlPatch) {
348 retval = r;
349 if (retval == Result::OK) {
350 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
351 }
352 });
353 } else {
354 #if MAJOR_VERSION >= 6
355 ret = mDevice->updateAudioPatch(
356 *patch,
357 hidlSources, hidlSinks,
358 [&](Result r, AudioPatchHandle hidlPatch) {
359 retval = r;
360 if (retval == Result::OK) {
361 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
362 }
363 });
364 methodName = "updateAudioPatch";
365 #endif
366 }
367 return processReturn(methodName.c_str(), ret, retval);
368 }
369
releaseAudioPatch(audio_patch_handle_t patch)370 status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
371 if (mDevice == 0) return NO_INIT;
372 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
373 }
374
getAudioPort(struct audio_port * port)375 status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
376 if (mDevice == 0) return NO_INIT;
377 AudioPort hidlPort;
378 HidlUtils::audioPortFromHal(*port, &hidlPort);
379 Result retval;
380 Return<void> ret = mDevice->getAudioPort(
381 hidlPort,
382 [&](Result r, const AudioPort& p) {
383 retval = r;
384 if (retval == Result::OK) {
385 HidlUtils::audioPortToHal(p, port);
386 }
387 });
388 return processReturn("getAudioPort", ret, retval);
389 }
390
setAudioPortConfig(const struct audio_port_config * config)391 status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
392 if (mDevice == 0) return NO_INIT;
393 AudioPortConfig hidlConfig;
394 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
395 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
396 }
397
398 #if MAJOR_VERSION == 2
getMicrophones(std::vector<media::MicrophoneInfo> * microphonesInfo __unused)399 status_t DeviceHalHidl::getMicrophones(
400 std::vector<media::MicrophoneInfo> *microphonesInfo __unused) {
401 if (mDevice == 0) return NO_INIT;
402 return INVALID_OPERATION;
403 }
404 #elif MAJOR_VERSION >= 4
getMicrophones(std::vector<media::MicrophoneInfo> * microphonesInfo)405 status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
406 if (mDevice == 0) return NO_INIT;
407 Result retval;
408 Return<void> ret = mDevice->getMicrophones(
409 [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
410 retval = r;
411 for (size_t k = 0; k < micArrayHal.size(); k++) {
412 audio_microphone_characteristic_t dst;
413 //convert
414 microphoneInfoToHal(micArrayHal[k], &dst);
415 media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
416 microphonesInfo->push_back(microphone);
417 }
418 });
419 return processReturn("getMicrophones", ret, retval);
420 }
421 #endif
422
423 #if MAJOR_VERSION >= 6
addDeviceEffect(audio_port_handle_t device,sp<EffectHalInterface> effect)424 status_t DeviceHalHidl::addDeviceEffect(
425 audio_port_handle_t device, sp<EffectHalInterface> effect) {
426 if (mDevice == 0) return NO_INIT;
427 return processReturn("addDeviceEffect", mDevice->addDeviceEffect(
428 static_cast<AudioPortHandle>(device),
429 static_cast<EffectHalHidl*>(effect.get())->effectId()));
430 }
431 #else
addDeviceEffect(audio_port_handle_t device __unused,sp<EffectHalInterface> effect __unused)432 status_t DeviceHalHidl::addDeviceEffect(
433 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
434 return INVALID_OPERATION;
435 }
436 #endif
437
438 #if MAJOR_VERSION >= 6
removeDeviceEffect(audio_port_handle_t device,sp<EffectHalInterface> effect)439 status_t DeviceHalHidl::removeDeviceEffect(
440 audio_port_handle_t device, sp<EffectHalInterface> effect) {
441 if (mDevice == 0) return NO_INIT;
442 return processReturn("removeDeviceEffect", mDevice->removeDeviceEffect(
443 static_cast<AudioPortHandle>(device),
444 static_cast<EffectHalHidl*>(effect.get())->effectId()));
445 }
446 #else
removeDeviceEffect(audio_port_handle_t device __unused,sp<EffectHalInterface> effect __unused)447 status_t DeviceHalHidl::removeDeviceEffect(
448 audio_port_handle_t device __unused, sp<EffectHalInterface> effect __unused) {
449 return INVALID_OPERATION;
450 }
451 #endif
452
dump(int fd)453 status_t DeviceHalHidl::dump(int fd) {
454 if (mDevice == 0) return NO_INIT;
455 native_handle_t* hidlHandle = native_handle_create(1, 0);
456 hidlHandle->data[0] = fd;
457 Return<void> ret = mDevice->debug(hidlHandle, {} /* options */);
458 native_handle_delete(hidlHandle);
459 return processReturn("dump", ret);
460 }
461
462 } // namespace CPP_VERSION
463 } // namespace android
464