• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android/hardware/audio/4.0/IPrimaryDevice.h>
23 #include <cutils/native_handle.h>
24 #include <hwbinder/IPCThreadState.h>
25 #include <utils/Log.h>
26 
27 #include <common/all-versions/VersionUtils.h>
28 
29 #include "DeviceHalHidl.h"
30 #include "HidlUtils.h"
31 #include "StreamHalHidl.h"
32 #include "VersionUtils.h"
33 
34 using ::android::hardware::audio::common::V4_0::AudioConfig;
35 using ::android::hardware::audio::common::V4_0::AudioDevice;
36 using ::android::hardware::audio::common::V4_0::AudioInputFlag;
37 using ::android::hardware::audio::common::V4_0::AudioOutputFlag;
38 using ::android::hardware::audio::common::V4_0::AudioPatchHandle;
39 using ::android::hardware::audio::common::V4_0::AudioPort;
40 using ::android::hardware::audio::common::V4_0::AudioPortConfig;
41 using ::android::hardware::audio::common::V4_0::AudioMode;
42 using ::android::hardware::audio::common::V4_0::AudioSource;
43 using ::android::hardware::audio::common::V4_0::HidlUtils;
44 using ::android::hardware::audio::common::utils::mkEnumConverter;
45 using ::android::hardware::audio::V4_0::DeviceAddress;
46 using ::android::hardware::audio::V4_0::IPrimaryDevice;
47 using ::android::hardware::audio::V4_0::ParameterValue;
48 using ::android::hardware::audio::V4_0::Result;
49 using ::android::hardware::audio::V4_0::SinkMetadata;
50 using ::android::hardware::hidl_string;
51 using ::android::hardware::hidl_vec;
52 
53 namespace android {
54 namespace V4_0 {
55 
56 namespace {
57 
deviceAddressFromHal(audio_devices_t device,const char * halAddress,DeviceAddress * address)58 status_t deviceAddressFromHal(
59         audio_devices_t device, const char* halAddress, DeviceAddress* address) {
60     address->device = AudioDevice(device);
61 
62     if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
63         return OK;
64     }
65     const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
66     if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
67     if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0)
68             || (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
69         int status = sscanf(halAddress,
70                 "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
71                 &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
72                 &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
73         return status == 6 ? OK : BAD_VALUE;
74     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0)
75             || (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
76         int status = sscanf(halAddress,
77                 "%hhu.%hhu.%hhu.%hhu",
78                 &address->address.ipv4[0], &address->address.ipv4[1],
79                 &address->address.ipv4[2], &address->address.ipv4[3]);
80         return status == 4 ? OK : BAD_VALUE;
81     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0
82             || (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
83         int status = sscanf(halAddress,
84                 "card=%d;device=%d",
85                 &address->address.alsa.card, &address->address.alsa.device);
86         return status == 2 ? OK : BAD_VALUE;
87     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0)
88             || (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
89         if (halAddress != NULL) {
90             address->busAddress = halAddress;
91             return OK;
92         }
93         return BAD_VALUE;
94     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0
95             || (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
96         if (halAddress != NULL) {
97             address->rSubmixAddress = halAddress;
98             return OK;
99         }
100         return BAD_VALUE;
101     }
102     return OK;
103 }
104 
105 }  // namespace
106 
DeviceHalHidl(const sp<IDevice> & device)107 DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
108         : ConversionHelperHidl("Device"), mDevice(device),
109           mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
110 }
111 
~DeviceHalHidl()112 DeviceHalHidl::~DeviceHalHidl() {
113     if (mDevice != 0) {
114         mDevice.clear();
115         hardware::IPCThreadState::self()->flushCommands();
116     }
117 }
118 
getSupportedDevices(uint32_t *)119 status_t DeviceHalHidl::getSupportedDevices(uint32_t*) {
120     // Obsolete.
121     return INVALID_OPERATION;
122 }
123 
initCheck()124 status_t DeviceHalHidl::initCheck() {
125     if (mDevice == 0) return NO_INIT;
126     return processReturn("initCheck", mDevice->initCheck());
127 }
128 
setVoiceVolume(float volume)129 status_t DeviceHalHidl::setVoiceVolume(float volume) {
130     if (mDevice == 0) return NO_INIT;
131     if (mPrimaryDevice == 0) return INVALID_OPERATION;
132     return processReturn("setVoiceVolume", mPrimaryDevice->setVoiceVolume(volume));
133 }
134 
setMasterVolume(float volume)135 status_t DeviceHalHidl::setMasterVolume(float volume) {
136     if (mDevice == 0) return NO_INIT;
137     if (mPrimaryDevice == 0) return INVALID_OPERATION;
138     return processReturn("setMasterVolume", mPrimaryDevice->setMasterVolume(volume));
139 }
140 
getMasterVolume(float * volume)141 status_t DeviceHalHidl::getMasterVolume(float *volume) {
142     if (mDevice == 0) return NO_INIT;
143     if (mPrimaryDevice == 0) return INVALID_OPERATION;
144     Result retval;
145     Return<void> ret = mPrimaryDevice->getMasterVolume(
146             [&](Result r, float v) {
147                 retval = r;
148                 if (retval == Result::OK) {
149                     *volume = v;
150                 }
151             });
152     return processReturn("getMasterVolume", ret, retval);
153 }
154 
setMode(audio_mode_t mode)155 status_t DeviceHalHidl::setMode(audio_mode_t mode) {
156     if (mDevice == 0) return NO_INIT;
157     if (mPrimaryDevice == 0) return INVALID_OPERATION;
158     return processReturn("setMode", mPrimaryDevice->setMode(AudioMode(mode)));
159 }
160 
setMicMute(bool state)161 status_t DeviceHalHidl::setMicMute(bool state) {
162     if (mDevice == 0) return NO_INIT;
163     return processReturn("setMicMute", mDevice->setMicMute(state));
164 }
165 
getMicMute(bool * state)166 status_t DeviceHalHidl::getMicMute(bool *state) {
167     if (mDevice == 0) return NO_INIT;
168     Result retval;
169     Return<void> ret = mDevice->getMicMute(
170             [&](Result r, bool mute) {
171                 retval = r;
172                 if (retval == Result::OK) {
173                     *state = mute;
174                 }
175             });
176     return processReturn("getMicMute", ret, retval);
177 }
178 
setMasterMute(bool state)179 status_t DeviceHalHidl::setMasterMute(bool state) {
180     if (mDevice == 0) return NO_INIT;
181     return processReturn("setMasterMute", mDevice->setMasterMute(state));
182 }
183 
getMasterMute(bool * state)184 status_t DeviceHalHidl::getMasterMute(bool *state) {
185     if (mDevice == 0) return NO_INIT;
186     Result retval;
187     Return<void> ret = mDevice->getMasterMute(
188             [&](Result r, bool mute) {
189                 retval = r;
190                 if (retval == Result::OK) {
191                     *state = mute;
192                 }
193             });
194     return processReturn("getMasterMute", ret, retval);
195 }
196 
setParameters(const String8 & kvPairs)197 status_t DeviceHalHidl::setParameters(const String8& kvPairs) {
198     if (mDevice == 0) return NO_INIT;
199     hidl_vec<ParameterValue> hidlParams;
200     status_t status = parametersFromHal(kvPairs, &hidlParams);
201     if (status != OK) return status;
202     // TODO: change the API so that context and kvPairs are separated
203     return processReturn("setParameters",
204                          utils::setParameters(mDevice, {} /* context */, hidlParams));
205 }
206 
getParameters(const String8 & keys,String8 * values)207 status_t DeviceHalHidl::getParameters(const String8& keys, String8 *values) {
208     values->clear();
209     if (mDevice == 0) return NO_INIT;
210     hidl_vec<hidl_string> hidlKeys;
211     status_t status = keysFromHal(keys, &hidlKeys);
212     if (status != OK) return status;
213     Result retval;
214     Return<void> ret = utils::getParameters(mDevice,
215             {} /* context */,
216             hidlKeys,
217             [&](Result r, const hidl_vec<ParameterValue>& parameters) {
218                 retval = r;
219                 if (retval == Result::OK) {
220                     parametersToHal(parameters, values);
221                 }
222             });
223     return processReturn("getParameters", ret, retval);
224 }
225 
getInputBufferSize(const struct audio_config * config,size_t * size)226 status_t DeviceHalHidl::getInputBufferSize(
227         const struct audio_config *config, size_t *size) {
228     if (mDevice == 0) return NO_INIT;
229     AudioConfig hidlConfig;
230     HidlUtils::audioConfigFromHal(*config, &hidlConfig);
231     Result retval;
232     Return<void> ret = mDevice->getInputBufferSize(
233             hidlConfig,
234             [&](Result r, uint64_t bufferSize) {
235                 retval = r;
236                 if (retval == Result::OK) {
237                     *size = static_cast<size_t>(bufferSize);
238                 }
239             });
240     return processReturn("getInputBufferSize", ret, retval);
241 }
242 
openOutputStream(audio_io_handle_t handle,audio_devices_t devices,audio_output_flags_t flags,struct audio_config * config,const char * address,sp<StreamOutHalInterface> * outStream)243 status_t DeviceHalHidl::openOutputStream(
244         audio_io_handle_t handle,
245         audio_devices_t devices,
246         audio_output_flags_t flags,
247         struct audio_config *config,
248         const char *address,
249         sp<StreamOutHalInterface> *outStream) {
250     if (mDevice == 0) return NO_INIT;
251     DeviceAddress hidlDevice;
252     status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
253     if (status != OK) return status;
254     AudioConfig hidlConfig;
255     HidlUtils::audioConfigFromHal(*config, &hidlConfig);
256     Result retval = Result::NOT_INITIALIZED;
257     Return<void> ret = mDevice->openOutputStream(
258             handle,
259             hidlDevice,
260             hidlConfig,
261             mkEnumConverter<AudioOutputFlag>(flags),
262             {} /* metadata */,
263             [&](Result r, const sp<IStreamOut>& result, const AudioConfig& suggestedConfig) {
264                 retval = r;
265                 if (retval == Result::OK) {
266                     *outStream = new StreamOutHalHidl(result);
267                 }
268                 HidlUtils::audioConfigToHal(suggestedConfig, config);
269             });
270     return processReturn("openOutputStream", ret, retval);
271 }
272 
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,sp<StreamInHalInterface> * inStream)273 status_t DeviceHalHidl::openInputStream(
274         audio_io_handle_t handle,
275         audio_devices_t devices,
276         struct audio_config *config,
277         audio_input_flags_t flags,
278         const char *address,
279         audio_source_t source,
280         sp<StreamInHalInterface> *inStream) {
281     if (mDevice == 0) return NO_INIT;
282     DeviceAddress hidlDevice;
283     status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
284     if (status != OK) return status;
285     AudioConfig hidlConfig;
286     HidlUtils::audioConfigFromHal(*config, &hidlConfig);
287     Result retval = Result::NOT_INITIALIZED;
288     // TODO: correctly propagate the tracks sources and volume
289     //       for now, only send the main source at 1dbfs
290     SinkMetadata metadata = {{{AudioSource(source), 1}}};
291     Return<void> ret = mDevice->openInputStream(
292             handle,
293             hidlDevice,
294             hidlConfig,
295             flags,
296             metadata,
297             [&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
298                 retval = r;
299                 if (retval == Result::OK) {
300                     *inStream = new StreamInHalHidl(result);
301                 }
302                 HidlUtils::audioConfigToHal(suggestedConfig, config);
303             });
304     return processReturn("openInputStream", ret, retval);
305 }
306 
supportsAudioPatches(bool * supportsPatches)307 status_t DeviceHalHidl::supportsAudioPatches(bool *supportsPatches) {
308     if (mDevice == 0) return NO_INIT;
309     return processReturn("supportsAudioPatches", mDevice->supportsAudioPatches(), supportsPatches);
310 }
311 
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)312 status_t DeviceHalHidl::createAudioPatch(
313         unsigned int num_sources,
314         const struct audio_port_config *sources,
315         unsigned int num_sinks,
316         const struct audio_port_config *sinks,
317         audio_patch_handle_t *patch) {
318     if (mDevice == 0) return NO_INIT;
319     hidl_vec<AudioPortConfig> hidlSources, hidlSinks;
320     HidlUtils::audioPortConfigsFromHal(num_sources, sources, &hidlSources);
321     HidlUtils::audioPortConfigsFromHal(num_sinks, sinks, &hidlSinks);
322     Result retval;
323     Return<void> 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     return processReturn("createAudioPatch", ret, retval);
332 }
333 
releaseAudioPatch(audio_patch_handle_t patch)334 status_t DeviceHalHidl::releaseAudioPatch(audio_patch_handle_t patch) {
335     if (mDevice == 0) return NO_INIT;
336     return processReturn("releaseAudioPatch", mDevice->releaseAudioPatch(patch));
337 }
338 
getAudioPort(struct audio_port * port)339 status_t DeviceHalHidl::getAudioPort(struct audio_port *port) {
340     if (mDevice == 0) return NO_INIT;
341     AudioPort hidlPort;
342     HidlUtils::audioPortFromHal(*port, &hidlPort);
343     Result retval;
344     Return<void> ret = mDevice->getAudioPort(
345             hidlPort,
346             [&](Result r, const AudioPort& p) {
347                 retval = r;
348                 if (retval == Result::OK) {
349                     HidlUtils::audioPortToHal(p, port);
350                 }
351             });
352     return processReturn("getAudioPort", ret, retval);
353 }
354 
setAudioPortConfig(const struct audio_port_config * config)355 status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
356     if (mDevice == 0) return NO_INIT;
357     AudioPortConfig hidlConfig;
358     HidlUtils::audioPortConfigFromHal(*config, &hidlConfig);
359     return processReturn("setAudioPortConfig", mDevice->setAudioPortConfig(hidlConfig));
360 }
361 
getMicrophones(std::vector<media::MicrophoneInfo> * microphonesInfo)362 status_t DeviceHalHidl::getMicrophones(std::vector<media::MicrophoneInfo> *microphonesInfo) {
363     if (mDevice == 0) return NO_INIT;
364     Result retval;
365     Return<void> ret = mDevice->getMicrophones(
366             [&](Result r, hidl_vec<MicrophoneInfo> micArrayHal) {
367         retval = r;
368         for (size_t k = 0; k < micArrayHal.size(); k++) {
369             audio_microphone_characteristic_t dst;
370             //convert
371             microphoneInfoToHal(micArrayHal[k], &dst);
372             media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
373             microphonesInfo->push_back(microphone);
374         }
375     });
376     return processReturn("getMicrophones", ret, retval);
377 }
378 
dump(int fd)379 status_t DeviceHalHidl::dump(int fd) {
380     if (mDevice == 0) return NO_INIT;
381     native_handle_t* hidlHandle = native_handle_create(1, 0);
382     hidlHandle->data[0] = fd;
383     Return<void> ret = mDevice->debug(hidlHandle, {} /* options */);
384     native_handle_delete(hidlHandle);
385     return processReturn("dump", ret);
386 }
387 
388 } // namespace V4_0
389 } // namespace android
390