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