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