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