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