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