Stream.cpp revision fd067c3f54669b84b267047d173d15392d178dc4
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 <inttypes.h> 18 19#define LOG_TAG "StreamHAL" 20 21#include <hardware/audio.h> 22#include <hardware/audio_effect.h> 23#include <media/TypeConverter.h> 24#include <android/log.h> 25#include <utils/SortedVector.h> 26#include <utils/Vector.h> 27 28#include "Conversions.h" 29#include "EffectMap.h" 30#include "Stream.h" 31 32namespace android { 33namespace hardware { 34namespace audio { 35namespace V2_0 { 36namespace implementation { 37 38Stream::Stream(audio_stream_t* stream) 39 : mStream(stream) { 40} 41 42Stream::~Stream() { 43 mStream = nullptr; 44} 45 46// static 47Result Stream::analyzeStatus(const char* funcName, int status, int ignoreError, int ignoreError2) { 48 if (status != 0 && status != -ignoreError && status != -ignoreError2) { 49 ALOGW("Error from HAL stream in function %s: %s", funcName, strerror(-status)); 50 } 51 switch (status) { 52 case 0: return Result::OK; 53 case -EINVAL: return Result::INVALID_ARGUMENTS; 54 case -ENODATA: return Result::INVALID_STATE; 55 case -ENODEV: return Result::NOT_INITIALIZED; 56 case -ENOSYS: return Result::NOT_SUPPORTED; 57 default: return Result::INVALID_STATE; 58 } 59} 60 61char* Stream::halGetParameters(const char* keys) { 62 return mStream->get_parameters(mStream, keys); 63} 64 65int Stream::halSetParameters(const char* keysAndValues) { 66 return mStream->set_parameters(mStream, keysAndValues); 67} 68 69// Methods from ::android::hardware::audio::V2_0::IStream follow. 70Return<uint64_t> Stream::getFrameSize() { 71 // Needs to be implemented by interface subclasses. But can't be declared as pure virtual, 72 // since interface subclasses implementation do not inherit from this class. 73 LOG_ALWAYS_FATAL("Stream::getFrameSize is pure abstract"); 74 return uint64_t {}; 75} 76 77Return<uint64_t> Stream::getFrameCount() { 78 int halFrameCount; 79 Result retval = getParam(AudioParameter::keyFrameCount, &halFrameCount); 80 return retval == Result::OK ? halFrameCount : 0; 81} 82 83Return<uint64_t> Stream::getBufferSize() { 84 return mStream->get_buffer_size(mStream); 85} 86 87Return<uint32_t> Stream::getSampleRate() { 88 return mStream->get_sample_rate(mStream); 89} 90 91Return<void> Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) { 92 String8 halListValue; 93 Result result = getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue); 94 hidl_vec<uint32_t> sampleRates; 95 SortedVector<uint32_t> halSampleRates; 96 if (result == Result::OK) { 97 halSampleRates = samplingRatesFromString( 98 halListValue.string(), AudioParameter::valueListSeparator); 99 sampleRates.setToExternal(halSampleRates.editArray(), halSampleRates.size()); 100 } 101 _hidl_cb(sampleRates); 102 return Void(); 103} 104 105Return<Result> Stream::setSampleRate(uint32_t sampleRateHz) { 106 return setParam(AudioParameter::keySamplingRate, static_cast<int>(sampleRateHz)); 107} 108 109Return<AudioChannelMask> Stream::getChannelMask() { 110 return AudioChannelMask(mStream->get_channels(mStream)); 111} 112 113Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) { 114 String8 halListValue; 115 Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue); 116 hidl_vec<AudioChannelMask> channelMasks; 117 SortedVector<audio_channel_mask_t> halChannelMasks; 118 if (result == Result::OK) { 119 halChannelMasks = channelMasksFromString( 120 halListValue.string(), AudioParameter::valueListSeparator); 121 channelMasks.resize(halChannelMasks.size()); 122 for (size_t i = 0; i < halChannelMasks.size(); ++i) { 123 channelMasks[i] = AudioChannelMask(halChannelMasks[i]); 124 } 125 } 126 _hidl_cb(channelMasks); 127 return Void(); 128} 129 130Return<Result> Stream::setChannelMask(AudioChannelMask mask) { 131 return setParam(AudioParameter::keyChannels, static_cast<int>(mask)); 132} 133 134Return<AudioFormat> Stream::getFormat() { 135 return AudioFormat(mStream->get_format(mStream)); 136} 137 138Return<void> Stream::getSupportedFormats(getSupportedFormats_cb _hidl_cb) { 139 String8 halListValue; 140 Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue); 141 hidl_vec<AudioFormat> formats; 142 Vector<audio_format_t> halFormats; 143 if (result == Result::OK) { 144 halFormats = formatsFromString(halListValue.string(), AudioParameter::valueListSeparator); 145 formats.resize(halFormats.size()); 146 for (size_t i = 0; i < halFormats.size(); ++i) { 147 formats[i] = AudioFormat(halFormats[i]); 148 } 149 } 150 _hidl_cb(formats); 151 return Void(); 152} 153 154Return<Result> Stream::setFormat(AudioFormat format) { 155 return setParam(AudioParameter::keyFormat, static_cast<int>(format)); 156} 157 158Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb) { 159 uint32_t halSampleRate = mStream->get_sample_rate(mStream); 160 audio_channel_mask_t halMask = mStream->get_channels(mStream); 161 audio_format_t halFormat = mStream->get_format(mStream); 162 _hidl_cb(halSampleRate, AudioChannelMask(halMask), AudioFormat(halFormat)); 163 return Void(); 164} 165 166Return<Result> Stream::addEffect(uint64_t effectId) { 167 effect_handle_t halEffect = EffectMap::getInstance().get(effectId); 168 if (halEffect != NULL) { 169 return analyzeStatus("add_audio_effect", mStream->add_audio_effect(mStream, halEffect)); 170 } else { 171 ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); 172 return Result::INVALID_ARGUMENTS; 173 } 174} 175 176Return<Result> Stream::removeEffect(uint64_t effectId) { 177 effect_handle_t halEffect = EffectMap::getInstance().get(effectId); 178 if (halEffect != NULL) { 179 return analyzeStatus( 180 "remove_audio_effect", mStream->remove_audio_effect(mStream, halEffect)); 181 } else { 182 ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId); 183 return Result::INVALID_ARGUMENTS; 184 } 185} 186 187Return<Result> Stream::standby() { 188 return analyzeStatus("standby", mStream->standby(mStream)); 189} 190 191Return<AudioDevice> Stream::getDevice() { 192 int device; 193 Result retval = getParam(AudioParameter::keyRouting, &device); 194 return retval == Result::OK ? static_cast<AudioDevice>(device) : AudioDevice::NONE; 195} 196 197Return<Result> Stream::setDevice(const DeviceAddress& address) { 198 char* halDeviceAddress = 199 audio_device_address_to_parameter( 200 static_cast<audio_devices_t>(address.device), 201 deviceAddressToHal(address).c_str()); 202 AudioParameter params((String8(halDeviceAddress))); 203 free(halDeviceAddress); 204 params.addInt( 205 String8(AudioParameter::keyRouting), static_cast<audio_devices_t>(address.device)); 206 return setParams(params); 207} 208 209Return<Result> Stream::setConnectedState(const DeviceAddress& address, bool connected) { 210 return setParam( 211 connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect, 212 deviceAddressToHal(address).c_str()); 213} 214 215Return<Result> Stream::setHwAvSync(uint32_t hwAvSync) { 216 return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync)); 217} 218 219Return<void> Stream::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) { 220 getParametersImpl(keys, _hidl_cb); 221 return Void(); 222} 223 224Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters) { 225 return setParametersImpl(parameters); 226} 227 228Return<void> Stream::debugDump(const hidl_handle& fd) { 229 if (fd->numFds == 1) { 230 analyzeStatus("dump", mStream->dump(mStream, fd->data[0])); 231 } 232 return Void(); 233} 234 235Return<Result> Stream::start() { 236 return Result::NOT_SUPPORTED; 237} 238 239Return<Result> Stream::stop() { 240 return Result::NOT_SUPPORTED; 241} 242 243Return<void> Stream::createMmapBuffer(int32_t minSizeFrames __unused, 244 createMmapBuffer_cb _hidl_cb) { 245 Result retval(Result::NOT_SUPPORTED); 246 MmapBufferInfo info; 247 _hidl_cb(retval, info); 248 return Void(); 249} 250 251Return<void> Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) { 252 Result retval(Result::NOT_SUPPORTED); 253 MmapPosition position; 254 _hidl_cb(retval, position); 255 return Void(); 256} 257 258Return<Result> Stream::close() { 259 return Result::NOT_SUPPORTED; 260} 261 262} // namespace implementation 263} // namespace V2_0 264} // namespace audio 265} // namespace hardware 266} // namespace android 267