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