blob: a6ced12093c0868656a4679e9902514db8ab9025 [file] [log] [blame]
Mikhail Naganovf558e022016-11-14 17:45:17 -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
22#include <android/hardware/audio/2.0/IPrimaryDevice.h>
23#include <cutils/native_handle.h>
24#include <utils/Log.h>
25
26#include "DeviceHalHidl.h"
27#include "HidlUtils.h"
28#include "StreamHalHidl.h"
29
30using ::android::hardware::audio::common::V2_0::AudioConfig;
31using ::android::hardware::audio::common::V2_0::AudioDevice;
32using ::android::hardware::audio::common::V2_0::AudioInputFlag;
33using ::android::hardware::audio::common::V2_0::AudioOutputFlag;
34using ::android::hardware::audio::common::V2_0::AudioPatchHandle;
35using ::android::hardware::audio::common::V2_0::AudioPort;
36using ::android::hardware::audio::common::V2_0::AudioPortConfig;
37using ::android::hardware::audio::common::V2_0::AudioMode;
38using ::android::hardware::audio::common::V2_0::AudioSource;
39using ::android::hardware::audio::V2_0::DeviceAddress;
40using ::android::hardware::audio::V2_0::IPrimaryDevice;
41using ::android::hardware::audio::V2_0::ParameterValue;
42using ::android::hardware::audio::V2_0::Result;
43using ::android::hardware::hidl_string;
44using ::android::hardware::hidl_vec;
45
46namespace android {
47
48namespace {
49
50status_t deviceAddressFromHal(
51 audio_devices_t device, const char* halAddress, DeviceAddress* address) {
52 address->device = AudioDevice(device);
53 const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
54 if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
55 if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
56 || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
57 int status = sscanf(halAddress,
58 "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
59 &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
60 &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
61 return status == 6 ? OK : BAD_VALUE;
62 } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
63 || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
64 int status = sscanf(halAddress,
65 "%hhu.%hhu.%hhu.%hhu",
66 &address->address.ipv4[0], &address->address.ipv4[1],
67 &address->address.ipv4[2], &address->address.ipv4[3]);
68 return status == 4 ? OK : BAD_VALUE;
69 } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
70 || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
71 int status = sscanf(halAddress,
72 "card=%d;device=%d",
73 &address->address.alsa.card, &address->address.alsa.device);
74 return status == 2 ? OK : BAD_VALUE;
75 } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
76 || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
77 if (halAddress != NULL) {
78 address->busAddress = halAddress;
79 return OK;
80 }
81 return BAD_VALUE;
82 } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
83 || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
84 if (halAddress != NULL) {
85 address->rSubmixAddress = halAddress;
86 return OK;
87 }
88 return BAD_VALUE;
89 }
90 return OK;
91}
92
93} // namespace
94
95DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
96 : ConversionHelperHidl("Device"), mDevice(device) {
97}
98
99DeviceHalHidl::~DeviceHalHidl() {
100}
101
102status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
103 // Obsolete.
104 return INVALID_OPERATION;
105}
106
107status_t DeviceHalHidl::initCheck() {
108 if (mDevice == 0) return NO_INIT;
109 return processReturn("initCheck", mDevice->initCheck());
110}
111
112status_t DeviceHalHidl::setVoiceVolume(float volume) {
113 if (mDevice == 0) return NO_INIT;
114 sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
115 if (primaryDev == 0) return INVALID_OPERATION;
116 return processReturn("setVoiceVolume", primaryDev->setVoiceVolume(volume));
117}
118
119status_t DeviceHalHidl::setMasterVolume(float volume) {
120 if (mDevice == 0) return NO_INIT;
121 sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
122 if (primaryDev == 0) return INVALID_OPERATION;
123 return processReturn("setMasterVolume", primaryDev->setMasterVolume(volume));
124}
125
126status_t DeviceHalHidl::getMasterVolume(float *volume) {
127 if (mDevice == 0) return NO_INIT;
128 sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
129 if (primaryDev == 0) return INVALID_OPERATION;
130 Result retval;
131 Return<void> ret = primaryDev->getMasterVolume(
132 [&](Result r, float v) {
133 retval = r;
134 if (retval == Result::OK) {
135 *volume = v;
136 }
137 });
138 return processReturn("getMasterVolume", ret, retval);
139}
140
141status_t DeviceHalHidl::setMode(audio_mode_t mode) {
142 if (mDevice == 0) return NO_INIT;
143 sp<IPrimaryDevice> primaryDev = IPrimaryDevice::castFrom(mDevice);
144 if (primaryDev == 0) return INVALID_OPERATION;
145 return processReturn("setMode", primaryDev->setMode(AudioMode(mode)));
146}
147
148status_t DeviceHalHidl::setMicMute(bool state) {
149 if (mDevice == 0) return NO_INIT;
150 return processReturn("setMicMute", mDevice->setMicMute(state));
151}
152
153status_t DeviceHalHidl::getMicMute(bool *state) {
154 if (mDevice == 0) return NO_INIT;
155 Result retval;
156 Return<void> ret = mDevice->getMicMute(
157 [&](Result r, bool mute) {
158 retval = r;
159 if (retval == Result::OK) {
160 *state = mute;
161 }
162 });
163 return processReturn("getMicMute", ret, retval);
164}
165
166status_t DeviceHalHidl::setMasterMute(bool state) {
167 if (mDevice == 0) return NO_INIT;
168 return processReturn("setMasterMute", mDevice->setMasterMute(state));
169}
170
171status_t DeviceHalHidl::getMasterMute(bool *state) {
172 if (mDevice == 0) return NO_INIT;
173 Result retval;
174 Return<void> ret = mDevice->getMasterMute(
175 [&](Result r, bool mute) {
176 retval = r;
177 if (retval == Result::OK) {
178 *state = mute;
179 }
180 });
181 return processReturn("getMasterMute", ret, retval);
182}
183
184status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
185 if (mDevice == 0) return NO_INIT;
186 hidl_vec<ParameterValue> hidlParams;
187 status_t status = parametersFromHal(kvPairs, &hidlParams);
188 if (status != OK) return status;
189 return processReturn("setParameters", mDevice->setParameters(hidlParams));
190}
191
192status_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 = mDevice->getParameters(
200 hidlKeys,
201 [&](Result r, const hidl_vec<ParameterValue>& parameters) {
202 retval = r;
203 if (retval == Result::OK) {
204 parametersToHal(parameters, values);
205 }
206 });
207 return processReturn("getParameters", ret, retval);
208}
209
210status_t DeviceHalHidl::getInputBufferSize(
211 const struct audio_config *config, size_t *size) {
212 if (mDevice == 0) return NO_INIT;
213 AudioConfig hidlConfig;
214 HidlUtils::audioConfigFromHal(*config, &hidlConfig);
215 Result retval;
216 Return<void> ret = mDevice->getInputBufferSize(
217 hidlConfig,
218 [&](Result r, uint64_t bufferSize) {
219 retval = r;
220 if (retval == Result::OK) {
221 *size = static_cast<size_t>(bufferSize);
222 }
223 });
224 return processReturn("getInputBufferSize", ret, retval);
225}
226
227status_t DeviceHalHidl::openOutputStream(
228 audio_io_handle_t handle,
229 audio_devices_t devices,
230 audio_output_flags_t flags,
231 struct audio_config *config,
232 const char *address,
233 sp<StreamOutHalInterface> *outStream) {
234 if (mDevice == 0) return NO_INIT;
235 DeviceAddress hidlDevice;
236 status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
237 if (status != OK) return status;
238 AudioConfig hidlConfig;
239 HidlUtils::audioConfigFromHal(*config, &hidlConfig);
240 Result retval = Result::NOT_INITIALIZED;
241 Return<void> ret = mDevice->openOutputStream(
242 handle,
243 hidlDevice,
244 hidlConfig,
245 AudioOutputFlag(flags),
246 [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
247 retval = r;
248 if (retval == Result::OK) {
249 *outStream = new StreamOutHalHidl(result);
250 }
251 HidlUtils::audioConfigToHal(suggestedConfig, config);
252 });
253 return processReturn("openOutputStream", ret, retval);
254}
255
256status_t DeviceHalHidl::openInputStream(
257 audio_io_handle_t handle,
258 audio_devices_t devices,
259 struct audio_config *config,
260 audio_input_flags_t flags,
261 const char *address,
262 audio_source_t source,
263 sp<StreamInHalInterface> *inStream) {
264 if (mDevice == 0) return NO_INIT;
265 DeviceAddress hidlDevice;
266 status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
267 if (status != OK) return status;
268 AudioConfig hidlConfig;
269 HidlUtils::audioConfigFromHal(*config, &hidlConfig);
270 Result retval = Result::NOT_INITIALIZED;
271 Return<void> ret = mDevice->openInputStream(
272 handle,
273 hidlDevice,
274 hidlConfig,
275 AudioInputFlag(flags),
276 AudioSource(source),
277 [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
278 retval = r;
279 if (retval == Result::OK) {
280 *inStream = new StreamInHalHidl(result);
281 }
282 HidlUtils::audioConfigToHal(suggestedConfig, config);
283 });
284 return processReturn("openInputStream", ret, retval);
285}
286
287status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
288 if (mDevice == 0) return NO_INIT;
289 return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
290}
291
292status_t DeviceHalHidl::createAudioPatch(
293 unsigned int num_sources,
294 const struct audio_port_config *sources,
295 unsigned int num_sinks,
296 const struct audio_port_config *sinks,
297 audio_patch_handle_t *patch) {
298 if (mDevice == 0) return NO_INIT;
299 hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
300 HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
301 HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
302 Result retval;
303 Return<void> ret = mDevice->createAudioPatch(
304 hidlSources, hidlSinks,
305 [&](Result r, AudioPatchHandle hidlPatch) {
306 retval = r;
307 if (retval == Result::OK) {
308 *patch = static_cast<audio_patch_handle_t>(hidlPatch);
309 }
310 });
311 return processReturn("createAudioPatch", ret, retval);
312}
313
314status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
315 if (mDevice == 0) return NO_INIT;
316 return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
317}
318
319status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
320 if (mDevice == 0) return NO_INIT;
321 AudioPort hidlPort;
322 HidlUtils::audioPortFromHal(*port, &hidlPort);
323 Result retval;
324 Return<void> ret = mDevice->getAudioPort(
325 hidlPort,
326 [&](Result r, const AudioPort& p) {
327 retval = r;
328 if (retval == Result::OK) {
329 HidlUtils::audioPortToHal(p, port);
330 }
331 });
332 return processReturn("getAudioPort", ret, retval);
333}
334
335status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
336 if (mDevice == 0) return NO_INIT;
337 AudioPortConfig hidlConfig;
338 HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
339 return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
340}
341
342status_t DeviceHalHidl::dump(int fd) {
343 if (mDevice == 0) return NO_INIT;
344 native_handle_t* hidlHandle = native_handle_create(1, 0);
345 hidlHandle->data[0] = fd;
346 Return<void> ret = mDevice->debugDump(hidlHandle);
347 native_handle_delete(hidlHandle);
348 return processReturn("dump", ret);
349}
350
351} // namespace android