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