1 /* 2 * Copyright (C) 2018 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 "core/default/Device.h" 20 #include <HidlUtils.h> 21 #include "core/default/Conversions.h" 22 #include "core/default/StreamIn.h" 23 #include "core/default/StreamOut.h" 24 #include "core/default/Util.h" 25 26 //#define LOG_NDEBUG 0 27 28 #include <memory.h> 29 #include <string.h> 30 #include <algorithm> 31 32 #include <android/log.h> 33 34 namespace android { 35 namespace hardware { 36 namespace audio { 37 namespace CPP_VERSION { 38 namespace implementation { 39 40 using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils; 41 42 Device::Device(audio_hw_device_t* device) : mDevice(device) {} 43 44 Device::~Device() { 45 int status = audio_hw_device_close(mDevice); 46 ALOGW_IF(status, "Error closing audio hw device %p: %s", mDevice, strerror(-status)); 47 mDevice = nullptr; 48 } 49 50 Result Device::analyzeStatus(const char* funcName, int status, 51 const std::vector<int>& ignoreErrors) { 52 return util::analyzeStatus("Device", funcName, status, ignoreErrors); 53 } 54 55 void Device::closeInputStream(audio_stream_in_t* stream) { 56 mDevice->close_input_stream(mDevice, stream); 57 } 58 59 void Device::closeOutputStream(audio_stream_out_t* stream) { 60 mDevice->close_output_stream(mDevice, stream); 61 } 62 63 char* Device::halGetParameters(const char* keys) { 64 return mDevice->get_parameters(mDevice, keys); 65 } 66 67 int Device::halSetParameters(const char* keysAndValues) { 68 return mDevice->set_parameters(mDevice, keysAndValues); 69 } 70 71 // Methods from ::android::hardware::audio::CPP_VERSION::IDevice follow. 72 Return<Result> Device::initCheck() { 73 return analyzeStatus("init_check", mDevice->init_check(mDevice)); 74 } 75 76 Return<Result> Device::setMasterVolume(float volume) { 77 if (mDevice->set_master_volume == NULL) { 78 return Result::NOT_SUPPORTED; 79 } 80 if (!isGainNormalized(volume)) { 81 ALOGW("Can not set a master volume (%f) outside [0,1]", volume); 82 return Result::INVALID_ARGUMENTS; 83 } 84 return analyzeStatus("set_master_volume", mDevice->set_master_volume(mDevice, volume)); 85 } 86 87 Return<void> Device::getMasterVolume(getMasterVolume_cb _hidl_cb) { 88 Result retval(Result::NOT_SUPPORTED); 89 float volume = 0; 90 if (mDevice->get_master_volume != NULL) { 91 retval = analyzeStatus("get_master_volume", mDevice->get_master_volume(mDevice, &volume)); 92 } 93 _hidl_cb(retval, volume); 94 return Void(); 95 } 96 97 Return<Result> Device::setMicMute(bool mute) { 98 return analyzeStatus("set_mic_mute", mDevice->set_mic_mute(mDevice, mute)); 99 } 100 101 Return<void> Device::getMicMute(getMicMute_cb _hidl_cb) { 102 bool mute = false; 103 Result retval = analyzeStatus("get_mic_mute", mDevice->get_mic_mute(mDevice, &mute)); 104 _hidl_cb(retval, mute); 105 return Void(); 106 } 107 108 Return<Result> Device::setMasterMute(bool mute) { 109 Result retval(Result::NOT_SUPPORTED); 110 if (mDevice->set_master_mute != NULL) { 111 retval = analyzeStatus("set_master_mute", mDevice->set_master_mute(mDevice, mute)); 112 } 113 return retval; 114 } 115 116 Return<void> Device::getMasterMute(getMasterMute_cb _hidl_cb) { 117 Result retval(Result::NOT_SUPPORTED); 118 bool mute = false; 119 if (mDevice->get_master_mute != NULL) { 120 retval = analyzeStatus("get_master_mute", mDevice->get_master_mute(mDevice, &mute)); 121 } 122 _hidl_cb(retval, mute); 123 return Void(); 124 } 125 126 Return<void> Device::getInputBufferSize(const AudioConfig& config, getInputBufferSize_cb _hidl_cb) { 127 audio_config_t halConfig; 128 HidlUtils::audioConfigToHal(config, &halConfig); 129 size_t halBufferSize = mDevice->get_input_buffer_size(mDevice, &halConfig); 130 Result retval(Result::INVALID_ARGUMENTS); 131 uint64_t bufferSize = 0; 132 if (halBufferSize != 0) { 133 retval = Result::OK; 134 bufferSize = halBufferSize; 135 } 136 _hidl_cb(retval, bufferSize); 137 return Void(); 138 } 139 140 std::tuple<Result, sp<IStreamOut>> Device::openOutputStreamImpl(int32_t ioHandle, 141 const DeviceAddress& device, 142 const AudioConfig& config, 143 AudioOutputFlagBitfield flags, 144 AudioConfig* suggestedConfig) { 145 audio_config_t halConfig; 146 HidlUtils::audioConfigToHal(config, &halConfig); 147 audio_stream_out_t* halStream; 148 ALOGV( 149 "open_output_stream handle: %d devices: %x flags: %#x " 150 "srate: %d format %#x channels %x address %s", 151 ioHandle, static_cast<audio_devices_t>(device.device), 152 static_cast<audio_output_flags_t>(flags), halConfig.sample_rate, halConfig.format, 153 halConfig.channel_mask, deviceAddressToHal(device).c_str()); 154 int status = 155 mDevice->open_output_stream(mDevice, ioHandle, static_cast<audio_devices_t>(device.device), 156 static_cast<audio_output_flags_t>(flags), &halConfig, 157 &halStream, deviceAddressToHal(device).c_str()); 158 ALOGV("open_output_stream status %d stream %p", status, halStream); 159 sp<IStreamOut> streamOut; 160 if (status == OK) { 161 streamOut = new StreamOut(this, halStream); 162 } 163 HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); 164 return {analyzeStatus("open_output_stream", status, {EINVAL} /*ignore*/), streamOut}; 165 } 166 167 std::tuple<Result, sp<IStreamIn>> Device::openInputStreamImpl( 168 int32_t ioHandle, const DeviceAddress& device, const AudioConfig& config, 169 AudioInputFlagBitfield flags, AudioSource source, AudioConfig* suggestedConfig) { 170 audio_config_t halConfig; 171 HidlUtils::audioConfigToHal(config, &halConfig); 172 audio_stream_in_t* halStream; 173 ALOGV( 174 "open_input_stream handle: %d devices: %x flags: %#x " 175 "srate: %d format %#x channels %x address %s source %d", 176 ioHandle, static_cast<audio_devices_t>(device.device), 177 static_cast<audio_input_flags_t>(flags), halConfig.sample_rate, halConfig.format, 178 halConfig.channel_mask, deviceAddressToHal(device).c_str(), 179 static_cast<audio_source_t>(source)); 180 int status = mDevice->open_input_stream( 181 mDevice, ioHandle, static_cast<audio_devices_t>(device.device), &halConfig, &halStream, 182 static_cast<audio_input_flags_t>(flags), deviceAddressToHal(device).c_str(), 183 static_cast<audio_source_t>(source)); 184 ALOGV("open_input_stream status %d stream %p", status, halStream); 185 sp<IStreamIn> streamIn; 186 if (status == OK) { 187 streamIn = new StreamIn(this, halStream); 188 } 189 HidlUtils::audioConfigFromHal(halConfig, suggestedConfig); 190 return {analyzeStatus("open_input_stream", status, {EINVAL} /*ignore*/), streamIn}; 191 } 192 193 #if MAJOR_VERSION == 2 194 Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, 195 const AudioConfig& config, AudioOutputFlagBitfield flags, 196 openOutputStream_cb _hidl_cb) { 197 AudioConfig suggestedConfig; 198 auto [result, streamOut] = 199 openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig); 200 _hidl_cb(result, streamOut, suggestedConfig); 201 return Void(); 202 } 203 204 Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, 205 const AudioConfig& config, AudioInputFlagBitfield flags, 206 AudioSource source, openInputStream_cb _hidl_cb) { 207 AudioConfig suggestedConfig; 208 auto [result, streamIn] = 209 openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig); 210 _hidl_cb(result, streamIn, suggestedConfig); 211 return Void(); 212 } 213 214 #elif MAJOR_VERSION >= 4 215 Return<void> Device::openOutputStream(int32_t ioHandle, const DeviceAddress& device, 216 const AudioConfig& config, AudioOutputFlagBitfield flags, 217 const SourceMetadata& sourceMetadata, 218 openOutputStream_cb _hidl_cb) { 219 AudioConfig suggestedConfig; 220 auto [result, streamOut] = 221 openOutputStreamImpl(ioHandle, device, config, flags, &suggestedConfig); 222 if (streamOut) { 223 streamOut->updateSourceMetadata(sourceMetadata); 224 } 225 _hidl_cb(result, streamOut, suggestedConfig); 226 return Void(); 227 } 228 229 Return<void> Device::openInputStream(int32_t ioHandle, const DeviceAddress& device, 230 const AudioConfig& config, AudioInputFlagBitfield flags, 231 const SinkMetadata& sinkMetadata, 232 openInputStream_cb _hidl_cb) { 233 if (sinkMetadata.tracks.size() == 0) { 234 // This should never happen, the framework must not create as stream 235 // if there is no client 236 ALOGE("openInputStream called without tracks connected"); 237 _hidl_cb(Result::INVALID_ARGUMENTS, nullptr, AudioConfig()); 238 return Void(); 239 } 240 // Pick the first one as the main. 241 AudioSource source = sinkMetadata.tracks[0].source; 242 AudioConfig suggestedConfig; 243 auto [result, streamIn] = 244 openInputStreamImpl(ioHandle, device, config, flags, source, &suggestedConfig); 245 if (streamIn) { 246 streamIn->updateSinkMetadata(sinkMetadata); 247 } 248 _hidl_cb(result, streamIn, suggestedConfig); 249 return Void(); 250 } 251 #endif /* MAJOR_VERSION */ 252 253 Return<bool> Device::supportsAudioPatches() { 254 return version() >= AUDIO_DEVICE_API_VERSION_3_0; 255 } 256 257 Return<void> Device::createAudioPatch(const hidl_vec<AudioPortConfig>& sources, 258 const hidl_vec<AudioPortConfig>& sinks, 259 createAudioPatch_cb _hidl_cb) { 260 Result retval(Result::NOT_SUPPORTED); 261 AudioPatchHandle patch = 0; 262 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 263 std::unique_ptr<audio_port_config[]> halSources(HidlUtils::audioPortConfigsToHal(sources)); 264 std::unique_ptr<audio_port_config[]> halSinks(HidlUtils::audioPortConfigsToHal(sinks)); 265 audio_patch_handle_t halPatch = AUDIO_PATCH_HANDLE_NONE; 266 retval = analyzeStatus("create_audio_patch", 267 mDevice->create_audio_patch(mDevice, sources.size(), &halSources[0], 268 sinks.size(), &halSinks[0], &halPatch)); 269 if (retval == Result::OK) { 270 patch = static_cast<AudioPatchHandle>(halPatch); 271 } 272 } 273 _hidl_cb(retval, patch); 274 return Void(); 275 } 276 277 Return<Result> Device::releaseAudioPatch(int32_t patch) { 278 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 279 return analyzeStatus( 280 "release_audio_patch", 281 mDevice->release_audio_patch(mDevice, static_cast<audio_patch_handle_t>(patch))); 282 } 283 return Result::NOT_SUPPORTED; 284 } 285 286 Return<void> Device::getAudioPort(const AudioPort& port, getAudioPort_cb _hidl_cb) { 287 audio_port halPort; 288 HidlUtils::audioPortToHal(port, &halPort); 289 Result retval = analyzeStatus("get_audio_port", mDevice->get_audio_port(mDevice, &halPort)); 290 AudioPort resultPort = port; 291 if (retval == Result::OK) { 292 HidlUtils::audioPortFromHal(halPort, &resultPort); 293 } 294 _hidl_cb(retval, resultPort); 295 return Void(); 296 } 297 298 Return<Result> Device::setAudioPortConfig(const AudioPortConfig& config) { 299 if (version() >= AUDIO_DEVICE_API_VERSION_3_0) { 300 struct audio_port_config halPortConfig; 301 HidlUtils::audioPortConfigToHal(config, &halPortConfig); 302 return analyzeStatus("set_audio_port_config", 303 mDevice->set_audio_port_config(mDevice, &halPortConfig)); 304 } 305 return Result::NOT_SUPPORTED; 306 } 307 308 #if MAJOR_VERSION == 2 309 Return<AudioHwSync> Device::getHwAvSync() { 310 int halHwAvSync; 311 Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); 312 return retval == Result::OK ? halHwAvSync : AUDIO_HW_SYNC_INVALID; 313 } 314 #elif MAJOR_VERSION >= 4 315 Return<void> Device::getHwAvSync(getHwAvSync_cb _hidl_cb) { 316 int halHwAvSync; 317 Result retval = getParam(AudioParameter::keyHwAvSync, &halHwAvSync); 318 _hidl_cb(retval, halHwAvSync); 319 return Void(); 320 } 321 #endif 322 323 Return<Result> Device::setScreenState(bool turnedOn) { 324 return setParam(AudioParameter::keyScreenState, turnedOn); 325 } 326 327 #if MAJOR_VERSION == 2 328 Return<void> Device::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { 329 getParametersImpl({}, keys, _hidl_cb); 330 return Void(); 331 } 332 333 Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& parameters) { 334 return setParametersImpl({} /* context */, parameters); 335 } 336 #elif MAJOR_VERSION >= 4 337 Return<void> Device::getParameters(const hidl_vec<ParameterValue>& context, 338 const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { 339 getParametersImpl(context, keys, _hidl_cb); 340 return Void(); 341 } 342 Return<Result> Device::setParameters(const hidl_vec<ParameterValue>& context, 343 const hidl_vec<ParameterValue>& parameters) { 344 return setParametersImpl(context, parameters); 345 } 346 #endif 347 348 #if MAJOR_VERSION == 2 349 Return<void> Device::debugDump(const hidl_handle& fd) { 350 return debug(fd, {}); 351 } 352 #endif 353 354 Return<void> Device::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) { 355 if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { 356 analyzeStatus("dump", mDevice->dump(mDevice, fd->data[0])); 357 } 358 return Void(); 359 } 360 361 #if MAJOR_VERSION >= 4 362 Return<void> Device::getMicrophones(getMicrophones_cb _hidl_cb) { 363 Result retval = Result::NOT_SUPPORTED; 364 size_t actual_mics = AUDIO_MICROPHONE_MAX_COUNT; 365 audio_microphone_characteristic_t mic_array[AUDIO_MICROPHONE_MAX_COUNT]; 366 367 hidl_vec<MicrophoneInfo> microphones; 368 if (mDevice->get_microphones != NULL && 369 mDevice->get_microphones(mDevice, &mic_array[0], &actual_mics) == 0) { 370 microphones.resize(actual_mics); 371 for (size_t i = 0; i < actual_mics; ++i) { 372 halToMicrophoneCharacteristics(µphones[i], mic_array[i]); 373 } 374 retval = Result::OK; 375 } 376 _hidl_cb(retval, microphones); 377 return Void(); 378 } 379 380 Return<Result> Device::setConnectedState(const DeviceAddress& address, bool connected) { 381 auto key = connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect; 382 return setParam(key, address); 383 } 384 #endif 385 386 } // namespace implementation 387 } // namespace CPP_VERSION 388 } // namespace audio 389 } // namespace hardware 390 } // namespace android 391