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