blob: 05824c7fc5d95a44f4b96567fffcc457277d55ad [file] [log] [blame]
Mikhail Naganov10548292016-10-31 10:39:47 -07001 /*
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#define LOG_TAG "DeviceHAL"
18
19#include <algorithm>
20#include <memory.h>
21#include <string.h>
22
23#include <utils/Log.h>
24
25#include "Conversions.h"
26#include "Device.h"
27#include "StreamIn.h"
28#include "StreamOut.h"
29
30namespace android {
31namespace hardware {
32namespace audio {
33namespace V2_0 {
34namespace implementation {
35
36Device::Device(audio_hw_device_t* device)
37 : mDevice(device) {
38}
39
40Device::~Device() {
41 int status = audio_hw_device_close(mDevice);
42 ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status));
43 mDevice = nullptr;
44}
45
46// static
47void Device::audioConfigToHal(const AudioConfig& config, audio_config_t* halConfig) {
48 memset(halConfig, 0, sizeof(audio_config_t));
49 halConfig->sample_rate = config.sampleRateHz;
50 halConfig->channel_mask = static_cast<audio_channel_mask_t>(config.channelMask);
51 halConfig->format = static_cast<audio_format_t>(config.format);
52 audioOffloadInfoToHal(config.offloadInfo, &halConfig->offload_info);
53 halConfig->frame_count = config.frameCount;
54}
55
56// static
57void Device::audioGainConfigFromHal(
58 const struct audio_gain_config& halConfig, AudioGainConfig* config) {
59 config->index = halConfig.index;
60 config->mode = AudioGainMode(halConfig.mode);
61 config->channelMask = AudioChannelMask(halConfig.channel_mask);
62 for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) {
63 config->values[i] = halConfig.values[i];
64 }
65 config->rampDurationMs = halConfig.ramp_duration_ms;
66}
67
68// static
69void Device::audioGainConfigToHal(
70 const AudioGainConfig& config, struct audio_gain_config* halConfig) {
71 halConfig->index = config.index;
72 halConfig->mode = static_cast<audio_gain_mode_t>(config.mode);
73 halConfig->channel_mask = static_cast<audio_channel_mask_t>(config.channelMask);
74 memset(halConfig->values, 0, sizeof(halConfig->values));
75 for (size_t i = 0; i < sizeof(audio_channel_mask_t) * 8; ++i) {
76 halConfig->values[i] = config.values[i];
77 }
78 halConfig->ramp_duration_ms = config.rampDurationMs;
79}
80
81// static
82void Device::audioGainFromHal(const struct audio_gain& halGain, AudioGain* gain) {
83 gain->mode = AudioGainMode(halGain.mode);
84 gain->channelMask = AudioChannelMask(halGain.channel_mask);
85 gain->minValue = halGain.min_value;
86 gain->maxValue = halGain.max_value;
87 gain->defaultValue = halGain.default_value;
88 gain->stepValue = halGain.step_value;
89 gain->minRampMs = halGain.min_ramp_ms;
90 gain->maxRampMs = halGain.max_ramp_ms;
91}
92
93// static
94void Device::audioGainToHal(const AudioGain& gain, struct audio_gain* halGain) {
95 halGain->mode = static_cast<audio_gain_mode_t>(gain.mode);
96 halGain->channel_mask = static_cast<audio_channel_mask_t>(gain.channelMask);
97 halGain->min_value = gain.minValue;
98 halGain->max_value = gain.maxValue;
99 halGain->default_value = gain.defaultValue;
100 halGain->step_value = gain.stepValue;
101 halGain->min_ramp_ms = gain.minRampMs;
102 halGain->max_ramp_ms = gain.maxRampMs;
103}
104
105// static
106void Device::audioOffloadInfoToHal(
107 const AudioOffloadInfo& offload, audio_offload_info_t* halOffload) {
108 *halOffload = AUDIO_INFO_INITIALIZER;
109 halOffload->sample_rate = offload.sampleRateHz;
110 halOffload->channel_mask = static_cast<audio_channel_mask_t>(offload.channelMask);
111 halOffload->stream_type = static_cast<audio_stream_type_t>(offload.streamType);
112 halOffload->bit_rate = offload.bitRatePerSecond;
113 halOffload->duration_us = offload.durationMicroseconds;
114 halOffload->has_video = offload.hasVideo;
115 halOffload->is_streaming = offload.isStreaming;
116}
117
118// static
119void Device::audioPortConfigFromHal(
120 const struct audio_port_config& halConfig, AudioPortConfig* config) {
121 config->id = halConfig.id;
122 config->role = AudioPortRole(halConfig.role);
123 config->type = AudioPortType(halConfig.type);
124 config->configMask = AudioPortConfigMask(halConfig.config_mask);
125 config->sampleRateHz = halConfig.sample_rate;
126 config->channelMask = AudioChannelMask(halConfig.channel_mask);
127 config->format = AudioFormat(halConfig.format);
128 audioGainConfigFromHal(halConfig.gain, &config->gain);
129 switch (halConfig.type) {
130 case AUDIO_PORT_TYPE_NONE: break;
131 case AUDIO_PORT_TYPE_DEVICE: {
132 config->ext.device.hwModule = halConfig.ext.device.hw_module;
133 config->ext.device.type = AudioDevice(halConfig.ext.device.type);
134 memcpy(config->ext.device.address.data(),
135 halConfig.ext.device.address,
136 AUDIO_DEVICE_MAX_ADDRESS_LEN);
137 break;
138 }
139 case AUDIO_PORT_TYPE_MIX: {
140 config->ext.mix.hwModule = halConfig.ext.mix.hw_module;
141 config->ext.mix.ioHandle = halConfig.ext.mix.handle;
142 if (halConfig.role == AUDIO_PORT_ROLE_SOURCE) {
143 config->ext.mix.useCase.source = AudioSource(halConfig.ext.mix.usecase.source);
144 } else if (halConfig.role == AUDIO_PORT_ROLE_SINK) {
145 config->ext.mix.useCase.stream = AudioStreamType(halConfig.ext.mix.usecase.stream);
146 }
147 break;
148 }
149 case AUDIO_PORT_TYPE_SESSION: {
150 config->ext.session.session = halConfig.ext.session.session;
151 break;
152 }
153 }
154}
155
156// static
157void Device::audioPortConfigToHal(
158 const AudioPortConfig& config, struct audio_port_config* halConfig) {
159 memset(halConfig, 0, sizeof(audio_port_config));
160 halConfig->id = config.id;
161 halConfig->role = static_cast<audio_port_role_t>(config.role);
162 halConfig->type = static_cast<audio_port_type_t>(config.type);
163 halConfig->config_mask = static_cast<unsigned int>(config.configMask);
164 halConfig->sample_rate = config.sampleRateHz;
165 halConfig->channel_mask = static_cast<audio_channel_mask_t>(config.channelMask);
166 halConfig->format = static_cast<audio_format_t>(config.format);
167 audioGainConfigToHal(config.gain, &halConfig->gain);
168 switch (config.type) {
169 case AudioPortType::NONE: break;
170 case AudioPortType::DEVICE: {
171 halConfig->ext.device.hw_module = config.ext.device.hwModule;
172 halConfig->ext.device.type = static_cast<audio_devices_t>(config.ext.device.type);
173 memcpy(halConfig->ext.device.address,
174 config.ext.device.address.data(),
175 AUDIO_DEVICE_MAX_ADDRESS_LEN);
176 break;
177 }
178 case AudioPortType::MIX: {
179 halConfig->ext.mix.hw_module = config.ext.mix.hwModule;
180 halConfig->ext.mix.handle = config.ext.mix.ioHandle;
181 if (config.role == AudioPortRole::SOURCE) {
182 halConfig->ext.mix.usecase.source =
183 static_cast<audio_source_t>(config.ext.mix.useCase.source);
184 } else if (config.role == AudioPortRole::SINK) {
185 halConfig->ext.mix.usecase.stream =
186 static_cast<audio_stream_type_t>(config.ext.mix.useCase.stream);
187 }
188 break;
189 }
190 case AudioPortType::SESSION: {
191 halConfig->ext.session.session =
192 static_cast<audio_session_t>(config.ext.session.session);
193 break;
194 }
195 }
196}
197
198// static
199std::unique_ptr<audio_port_config[]> Device::audioPortConfigsToHal(
200 const hidl_vec<AudioPortConfig>& configs) {
201 std::unique_ptr<audio_port_config[]> halConfigs(new audio_port_config[configs.size()]);
202 for (size_t i = 0; i < configs.size(); ++i) {
203 audioPortConfigToHal(configs[i], &halConfigs[i]);
204 }
205 return halConfigs;
206}
207
208// static
209void Device::audioPortFromHal(const struct audio_port& halPort, AudioPort* port) {
210 port->id = halPort.id;
211 port->role = AudioPortRole(halPort.role);
212 port->type = AudioPortType(halPort.type);
213 port->name.setToExternal(halPort.name, strlen(halPort.name));
214 port->sampleRates.resize(halPort.num_sample_rates);
215 for (size_t i = 0; i < halPort.num_sample_rates; ++i) {
216 port->sampleRates[i] = halPort.sample_rates[i];
217 }
218 port->channelMasks.resize(halPort.num_channel_masks);
219 for (size_t i = 0; i < halPort.num_channel_masks; ++i) {
220 port->channelMasks[i] = AudioChannelMask(halPort.channel_masks[i]);
221 }
222 port->formats.resize(halPort.num_formats);
223 for (size_t i = 0; i < halPort.num_formats; ++i) {
224 port->formats[i] = AudioFormat(halPort.formats[i]);
225 }
226 port->gains.resize(halPort.num_gains);
227 for (size_t i = 0; i < halPort.num_gains; ++i) {
228 audioGainFromHal(halPort.gains[i], &port->gains[i]);
229 }
230 audioPortConfigFromHal(halPort.active_config, &port->activeConfig);
231 switch (halPort.type) {
232 case AUDIO_PORT_TYPE_NONE: break;
233 case AUDIO_PORT_TYPE_DEVICE: {
234 port->ext.device.hwModule = halPort.ext.device.hw_module;
235 port->ext.device.type = AudioDevice(halPort.ext.device.type);
236 memcpy(port->ext.device.address.data(),
237 halPort.ext.device.address,
238 AUDIO_DEVICE_MAX_ADDRESS_LEN);
239 break;
240 }
241 case AUDIO_PORT_TYPE_MIX: {
242 port->ext.mix.hwModule = halPort.ext.mix.hw_module;
243 port->ext.mix.ioHandle = halPort.ext.mix.handle;
244 port->ext.mix.latencyClass = AudioMixLatencyClass(halPort.ext.mix.latency_class);
245 break;
246 }
247 case AUDIO_PORT_TYPE_SESSION: {
248 port->ext.session.session = halPort.ext.session.session;
249 break;
250 }
251 }
252}
253
254// static
255void Device::audioPortToHal(const AudioPort& port, struct audio_port* halPort) {
256 memset(halPort, 0, sizeof(audio_port));
257 halPort->id = port.id;
258 halPort->role = static_cast<audio_port_role_t>(port.role);
259 halPort->type = static_cast<audio_port_type_t>(port.type);
260 memcpy(halPort->name,
261 port.name.c_str(),
262 std::min(port.name.size(), static_cast<size_t>(AUDIO_PORT_MAX_NAME_LEN)));
263 halPort->num_sample_rates =
264 std::min(port.sampleRates.size(), static_cast<size_t>(AUDIO_PORT_MAX_SAMPLING_RATES));
265 for (size_t i = 0; i < halPort->num_sample_rates; ++i) {
266 halPort->sample_rates[i] = port.sampleRates[i];
267 }
268 halPort->num_channel_masks =
269 std::min(port.channelMasks.size(), static_cast<size_t>(AUDIO_PORT_MAX_CHANNEL_MASKS));
270 for (size_t i = 0; i < halPort->num_channel_masks; ++i) {
271 halPort->channel_masks[i] = static_cast<audio_channel_mask_t>(port.channelMasks[i]);
272 }
273 halPort->num_formats =
274 std::min(port.formats.size(), static_cast<size_t>(AUDIO_PORT_MAX_FORMATS));
275 for (size_t i = 0; i < halPort->num_formats; ++i) {
276 halPort->formats[i] = static_cast<audio_format_t>(port.formats[i]);
277 }
278 halPort->num_gains = std::min(port.gains.size(), static_cast<size_t>(AUDIO_PORT_MAX_GAINS));
279 for (size_t i = 0; i < halPort->num_gains; ++i) {
280 audioGainToHal(port.gains[i], &halPort->gains[i]);
281 }
282 audioPortConfigToHal(port.activeConfig, &halPort->active_config);
283 switch (port.type) {
284 case AudioPortType::NONE: break;
285 case AudioPortType::DEVICE: {
286 halPort->ext.device.hw_module = port.ext.device.hwModule;
287 halPort->ext.device.type = static_cast<audio_devices_t>(port.ext.device.type);
288 memcpy(halPort->ext.device.address,
289 port.ext.device.address.data(),
290 AUDIO_DEVICE_MAX_ADDRESS_LEN);
291 break;
292 }
293 case AudioPortType::MIX: {
294 halPort->ext.mix.hw_module = port.ext.mix.hwModule;
295 halPort->ext.mix.handle = port.ext.mix.ioHandle;
296 halPort->ext.mix.latency_class =
297 static_cast<audio_mix_latency_class_t>(port.ext.mix.latencyClass);
298 break;
299 }
300 case AudioPortType::SESSION: {
301 halPort->ext.session.session = static_cast<audio_session_t>(port.ext.session.session);
302 break;
303 }
304 }
305}
306
307Result Device::analyzeStatus(const char* funcName, int status) {
308 if (status != 0) {
309 ALOGW("Device %p %s: %s", mDevice, funcName, strerror(-status));
310 }
311 switch (status) {
312 case 0: return Result::OK;
313 case -EINVAL: return Result::INVALID_ARGUMENTS;
314 case -ENODATA: return Result::INVALID_STATE;
315 case -ENODEV: return Result::NOT_INITIALIZED;
316 case -ENOSYS: return Result::NOT_SUPPORTED;
317 default: return Result::INVALID_STATE;
318 }
319}
320
321char* Device::halGetParameters(const char* keys) {
322 return mDevice->get_parameters(mDevice, keys);
323}
324
325int Device::halSetParameters(const char* keysAndValues) {
326 return mDevice->set_parameters(mDevice, keysAndValues);
327}
328
329// Methods from ::android::hardware::audio::V2_0::IDevice follow.
330Return<Result> Device::initCheck() {
331 return analyzeStatus("init_check", mDevice->init_check(mDevice));
332}
333
334Return<Result> Device::setMasterVolume(float volume) {
335 Result retval(Result::NOT_SUPPORTED);
336 if (mDevice->set_master_volume != NULL) {
337 retval = analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume));
338 }
339 return retval;
340}
341
342Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) {
343 Result retval(Result::NOT_SUPPORTED);
344 float volume = 0;
345 if (mDevice->get_master_volume != NULL) {
346 retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume));
347 }
348 _hidl_cb(retval, volume);
349 return Void();
350}
351
352Return<Result> Device::setMicMute(bool mute) {
353 return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute));
354}
355
356Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) {
357 bool mute = false;
358 Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute));
359 _hidl_cb(retval, mute);
360 return Void();
361}
362
363Return<Result> Device::setMasterMute(bool mute) {
364 Result retval(Result::NOT_SUPPORTED);
365 if (mDevice->set_master_mute != NULL) {
366 retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute));
367 }
368 return retval;
369}
370
371Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) {
372 Result retval(Result::NOT_SUPPORTED);
373 bool mute = false;
374 if (mDevice->get_master_mute != NULL) {
375 retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute));
376 }
377 _hidl_cb(retval, mute);
378 return Void();
379}
380
381Return<void> Device::getInputBufferSize(
382 const AudioConfig& config, getInputBufferSize_cb _hidl_cb) {
383 audio_config_t halConfig;
384 audioConfigToHal(config, &halConfig);
385 size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig);
386 Result retval(Result::INVALID_ARGUMENTS);
387 uint64_t bufferSize = 0;
388 if (halBufferSize != 0) {
389 retval = Result::OK;
390 bufferSize = halBufferSize;
391 }
392 _hidl_cb(retval, bufferSize);
393 return Void();
394}
395
396Return<void> Device::openOutputStream(
397 int32_t ioHandle,
398 const DeviceAddress& device,
399 const AudioConfig& config,
400 AudioOutputFlag flags,
401 openOutputStream_cb _hidl_cb) {
402 audio_config_t halConfig;
403 audioConfigToHal(config, &halConfig);
404 audio_stream_out_t *halStream;
405 int status = mDevice->open_output_stream(
406 mDevice,
407 ioHandle,
408 static_cast<audio_devices_t>(device.device),
409 static_cast<audio_output_flags_t>(flags),
410 &halConfig,
411 &halStream,
412 deviceAddressToHal(device).c_str());
413 sp<IStreamOut> streamOut;
414 if (status == OK) {
415 streamOut = new StreamOut(mDevice, halStream);
416 }
417 _hidl_cb(analyzeStatus("open_output_stream", status), streamOut);
418 return Void();
419}
420
421Return<void> Device::openInputStream(
422 int32_t ioHandle,
423 const DeviceAddress& device,
424 const AudioConfig& config,
425 AudioInputFlag flags,
426 AudioSource source,
427 openInputStream_cb _hidl_cb) {
428 audio_config_t halConfig;
429 audioConfigToHal(config, &halConfig);
430 audio_stream_in_t *halStream;
431 int status = mDevice->open_input_stream(
432 mDevice,
433 ioHandle,
434 static_cast<audio_devices_t>(device.device),
435 &halConfig,
436 &halStream,
437 static_cast<audio_input_flags_t>(flags),
438 deviceAddressToHal(device).c_str(),
439 static_cast<audio_source_t>(source));
440 sp<IStreamIn> streamIn;
441 if (status == OK) {
442 streamIn = new StreamIn(mDevice, halStream);
443 }
444 _hidl_cb(analyzeStatus("open_input_stream", status), streamIn);
445 return Void();
446}
447
448Return<void> Device::createAudioPatch(
449 const hidl_vec<AudioPortConfig>& sources,
450 const hidl_vec<AudioPortConfig>& sinks,
451 createAudioPatch_cb _hidl_cb) {
452 Result retval(Result::NOT_SUPPORTED);
453 AudioPatchHandle patch = 0;
454 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
455 std::unique_ptr<audio_port_config[]> halSources(audioPortConfigsToHal(sources));
456 std::unique_ptr<audio_port_config[]> halSinks(audioPortConfigsToHal(sinks));
457 audio_patch_handle_t halPatch;
458 retval = analyzeStatus(
459 "create_audio_patch",
460 mDevice->create_audio_patch(
461 mDevice,
462 sources.size(), &halSources[0],
463 sinks.size(), &halSinks[0],
464 &halPatch));
465 if (retval == Result::OK) {
466 patch = static_cast<AudioPatchHandle>(halPatch);
467 }
468 }
469 _hidl_cb(retval, patch);
470 return Void();
471}
472
473Return<Result> Device::releaseAudioPatch(int32_t patch) {
474 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
475 return analyzeStatus(
476 "release_audio_patch",
477 mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch)));
478 }
479 return Result::NOT_SUPPORTED;
480}
481
482Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) {
483 audio_port halPort;
484 audioPortToHal(port, &halPort);
485 Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort));
486 AudioPort resultPort = port;
487 if (retval == Result::OK) {
488 audioPortFromHal(halPort, &resultPort);
489 }
490 _hidl_cb(retval, resultPort);
491 return Void();
492}
493
494Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) {
495 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) {
496 struct audio_port_config halPortConfig;
497 audioPortConfigToHal(config, &halPortConfig);
498 return analyzeStatus(
499 "set_audio_port_config", mDevice->set_audio_port_config(mDevice, &halPortConfig));
500 }
501 return Result::NOT_SUPPORTED;
502}
503
504Return<AudioHwSync> Device::getHwAvSync() {
505 int halHwAvSync;
506 Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync);
507 return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID;
508}
509
510Return<Result> Device::setScreenState(bool turnedOn) {
511 return setParam(AudioParameter::keyScreenState, turnedOn);
512}
513
514Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) {
515 getParametersImpl(keys, _hidl_cb);
516 return Void();
517}
518
519Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) {
520 return setParametersImpl(parameters);
521}
522
523Return<void> Device::debugDump(const native_handle_t* fd) {
524 if (fd->numFds == 1) {
525 analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0]));
526 }
527 return Void();
528}
529
530} // namespace implementation
531} // namespace V2_0
532} // namespace audio
533} // namespace hardware
534} // namespace android