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 "StreamHAL" 18 19 #include "core/default/Stream.h" 20 #include "common/all-versions/default/EffectMap.h" 21 #include "core/default/Conversions.h" 22 #include "core/default/Util.h" 23 24 #include <inttypes.h> 25 26 #include <android/log.h> 27 #include <hardware/audio.h> 28 #include <hardware/audio_effect.h> 29 #include <media/TypeConverter.h> 30 #include <utils/SortedVector.h> 31 #include <utils/Vector.h> 32 33 namespace android { 34 namespace hardware { 35 namespace audio { 36 namespace CPP_VERSION { 37 namespace implementation { 38 39 Stream::Stream(audio_stream_t* stream) : mStream(stream) {} 40 41 Stream::~Stream() { 42 mStream = nullptr; 43 } 44 45 // static 46 Result Stream::analyzeStatus(const char* funcName, int status) { 47 return util::analyzeStatus("stream", funcName, status); 48 } 49 50 // static 51 Result Stream::analyzeStatus(const char* funcName, int status, 52 const std::vector<int>& ignoreErrors) { 53 return util::analyzeStatus("stream", funcName, status, ignoreErrors); 54 } 55 56 char* Stream::halGetParameters(const char* keys) { 57 return mStream->get_parameters(mStream, keys); 58 } 59 60 int Stream::halSetParameters(const char* keysAndValues) { 61 return mStream->set_parameters(mStream, keysAndValues); 62 } 63 64 // Methods from ::android::hardware::audio::CPP_VERSION::IStream follow. 65 Return<uint64_t> Stream::getFrameSize() { 66 // Needs to be implemented by interface subclasses. But can't be declared as pure virtual, 67 // since interface subclasses implementation do not inherit from this class. 68 LOG_ALWAYS_FATAL("Stream::getFrameSize is pure abstract"); 69 return uint64_t{}; 70 } 71 72 Return<uint64_t> Stream::getFrameCount() { 73 int halFrameCount; 74 Result retval = getParam(AudioParameter::keyFrameCount, &halFrameCount); 75 return retval == Result::OK ? halFrameCount : 0; 76 } 77 78 Return<uint64_t> Stream::getBufferSize() { 79 return mStream->get_buffer_size(mStream); 80 } 81 82 Return<uint32_t> Stream::getSampleRate() { 83 return mStream->get_sample_rate(mStream); 84 } 85 86 #if MAJOR_VERSION == 2 87 Return<void> Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { 88 return getSupportedSampleRates(getFormat(), _hidl_cb); 89 } 90 Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { 91 return getSupportedChannelMasks(getFormat(), _hidl_cb); 92 } 93 #endif 94 95 Return<void> Stream::getSupportedSampleRates(AudioFormat format, 96 getSupportedSampleRates_cb _hidl_cb) { 97 AudioParameter context; 98 context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format)); 99 String8 halListValue; 100 Result result = 101 getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue, context); 102 hidl_vec<uint32_t> sampleRates; 103 SortedVector<uint32_t> halSampleRates; 104 if (result == Result::OK) { 105 halSampleRates = 106 samplingRatesFromString(halListValue.string(), AudioParameter::valueListSeparator); 107 sampleRates.setToExternal(halSampleRates.editArray(), halSampleRates.size()); 108 // Legacy get_parameter does not return a status_t, thus can not advertise of failure. 109 // Note that this method must succeed (non empty list) if the format is supported. 110 if (sampleRates.size() == 0) { 111 result = Result::NOT_SUPPORTED; 112 } 113 } 114 #if MAJOR_VERSION == 2 115 _hidl_cb(sampleRates); 116 #elif MAJOR_VERSION >= 4 117 _hidl_cb(result, sampleRates); 118 #endif 119 return Void(); 120 } 121 122 Return<void> Stream::getSupportedChannelMasks(AudioFormat format, 123 getSupportedChannelMasks_cb _hidl_cb) { 124 AudioParameter context; 125 context.addInt(String8(AUDIO_PARAMETER_STREAM_FORMAT), int(format)); 126 String8 halListValue; 127 Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue, context); 128 hidl_vec<AudioChannelBitfield> channelMasks; 129 SortedVector<audio_channel_mask_t> halChannelMasks; 130 if (result == Result::OK) { 131 halChannelMasks = 132 channelMasksFromString(halListValue.string(), AudioParameter::valueListSeparator); 133 channelMasks.resize(halChannelMasks.size()); 134 for (size_t i = 0; i < halChannelMasks.size(); ++i) { 135 channelMasks[i] = AudioChannelBitfield(halChannelMasks[i]); 136 } 137 // Legacy get_parameter does not return a status_t, thus can not advertise of failure. 138 // Note that this method must succeed (non empty list) if the format is supported. 139 if (channelMasks.size() == 0) { 140 result = Result::NOT_SUPPORTED; 141 } 142 } 143 #if MAJOR_VERSION == 2 144 _hidl_cb(channelMasks); 145 #elif MAJOR_VERSION >= 4 146 _hidl_cb(result, channelMasks); 147 #endif 148 return Void(); 149 } 150 151 Return<Result> Stream::setSampleRate(uint32_t sampleRateHz) { 152 return setParam(AudioParameter::keySamplingRate, static_cast<int>(sampleRateHz)); 153 } 154 155 Return<AudioChannelBitfield> Stream::getChannelMask() { 156 return AudioChannelBitfield(mStream->get_channels(mStream)); 157 } 158 159 Return<Result> Stream::setChannelMask(AudioChannelBitfield mask) { 160 return setParam(AudioParameter::keyChannels, static_cast<int>(mask)); 161 } 162 163 Return<AudioFormat> Stream::getFormat() { 164 return AudioFormat(mStream->get_format(mStream)); 165 } 166 167 Return<void> Stream::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { 168 String8 halListValue; 169 Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue); 170 hidl_vec<AudioFormat> formats; 171 Vector<audio_format_t> halFormats; 172 if (result == Result::OK) { 173 halFormats = formatsFromString(halListValue.string(), AudioParameter::valueListSeparator); 174 formats.resize(halFormats.size()); 175 for (size_t i = 0; i < halFormats.size(); ++i) { 176 formats[i] = AudioFormat(halFormats[i]); 177 } 178 } 179 _hidl_cb(formats); 180 return Void(); 181 } 182 183 Return<Result> Stream::setFormat(AudioFormat format) { 184 return setParam(AudioParameter::keyFormat, static_cast<int>(format)); 185 } 186 187 Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { 188 uint32_t halSampleRate = mStream->get_sample_rate(mStream); 189 audio_channel_mask_t halMask = mStream->get_channels(mStream); 190 audio_format_t halFormat = mStream->get_format(mStream); 191 _hidl_cb(halSampleRate, AudioChannelBitfield(halMask), AudioFormat(halFormat)); 192 return Void(); 193 } 194 195 Return<Result> Stream::addEffect(uint64_t effectId) { 196 effect_handle_t halEffect = EffectMap::getInstance().get(effectId); 197 if (halEffect != NULL) { 198 return analyzeStatus("add_audio_effect", mStream->add_audio_effect(mStream, halEffect)); 199 } else { 200 ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); 201 return Result::INVALID_ARGUMENTS; 202 } 203 } 204 205 Return<Result> Stream::removeEffect(uint64_t effectId) { 206 effect_handle_t halEffect = EffectMap::getInstance().get(effectId); 207 if (halEffect != NULL) { 208 return analyzeStatus("remove_audio_effect", 209 mStream->remove_audio_effect(mStream, halEffect)); 210 } else { 211 ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); 212 return Result::INVALID_ARGUMENTS; 213 } 214 } 215 216 Return<Result> Stream::standby() { 217 return analyzeStatus("standby", mStream->standby(mStream)); 218 } 219 220 Return<Result> Stream::setHwAvSync(uint32_t hwAvSync) { 221 return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync)); 222 } 223 224 #if MAJOR_VERSION == 2 225 Return<AudioDevice> Stream::getDevice() { 226 int device = 0; 227 Result retval = getParam(AudioParameter::keyRouting, &device); 228 return retval == Result::OK ? static_cast<AudioDevice>(device) : AudioDevice::NONE; 229 } 230 231 Return<Result> Stream::setDevice(const DeviceAddress& address) { 232 return setParam(AudioParameter::keyRouting, address); 233 } 234 235 Return<void> Stream::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { 236 getParametersImpl({} /* context */, keys, _hidl_cb); 237 return Void(); 238 } 239 240 Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters) { 241 return setParametersImpl({} /* context */, parameters); 242 } 243 244 Return<Result> Stream::setConnectedState(const DeviceAddress& address, bool connected) { 245 return setParam( 246 connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect, 247 address); 248 } 249 #elif MAJOR_VERSION >= 4 250 Return<void> Stream::getDevices(getDevices_cb _hidl_cb) { 251 int device = 0; 252 Result retval = getParam(AudioParameter::keyRouting, &device); 253 hidl_vec<DeviceAddress> devices; 254 if (retval == Result::OK) { 255 devices.resize(1); 256 devices[0].device = static_cast<AudioDevice>(device); 257 } 258 _hidl_cb(retval, devices); 259 return Void(); 260 } 261 262 Return<Result> Stream::setDevices(const hidl_vec<DeviceAddress>& devices) { 263 // FIXME: can the legacy API set multiple device with address ? 264 if (devices.size() > 1) { 265 return Result::NOT_SUPPORTED; 266 } 267 DeviceAddress address; 268 if (devices.size() == 1) { 269 address = devices[0]; 270 } else { 271 address.device = AudioDevice::NONE; 272 } 273 return setParam(AudioParameter::keyRouting, address); 274 } 275 Return<void> Stream::getParameters(const hidl_vec<ParameterValue>& context, 276 const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { 277 getParametersImpl(context, keys, _hidl_cb); 278 return Void(); 279 } 280 281 Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& context, 282 const hidl_vec<ParameterValue>& parameters) { 283 return setParametersImpl(context, parameters); 284 } 285 #endif 286 287 Return<Result> Stream::start() { 288 return Result::NOT_SUPPORTED; 289 } 290 291 Return<Result> Stream::stop() { 292 return Result::NOT_SUPPORTED; 293 } 294 295 Return<void> Stream::createMmapBuffer(int32_t minSizeFrames __unused, 296 createMmapBuffer_cb _hidl_cb) { 297 Result retval(Result::NOT_SUPPORTED); 298 MmapBufferInfo info; 299 _hidl_cb(retval, info); 300 return Void(); 301 } 302 303 Return<void> Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) { 304 Result retval(Result::NOT_SUPPORTED); 305 MmapPosition position; 306 _hidl_cb(retval, position); 307 return Void(); 308 } 309 310 Return<Result> Stream::close() { 311 return Result::NOT_SUPPORTED; 312 } 313 314 Return<void> Stream::debug(const hidl_handle& fd, const hidl_vec<hidl_string>& /* options */) { 315 if (fd.getNativeHandle() != nullptr && fd->numFds == 1) { 316 analyzeStatus("dump", mStream->dump(mStream, fd->data[0])); 317 } 318 return Void(); 319 } 320 321 #if MAJOR_VERSION == 2 322 Return<void> Stream::debugDump(const hidl_handle& fd) { 323 return debug(fd, {} /* options */); 324 } 325 #endif 326 327 } // namespace implementation 328 } // namespace CPP_VERSION 329 } // namespace audio 330 } // namespace hardware 331 } // namespace android 332