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