Home | History | Annotate | Download | only in default
      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 <android/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 
     32 namespace android {
     33 namespace hardware {
     34 namespace audio {
     35 namespace V2_0 {
     36 namespace implementation {
     37 
     38 Stream::Stream(audio_stream_t* stream)
     39         : mStream(stream) {
     40 }
     41 
     42 Stream::~Stream() {
     43     mStream = nullptr;
     44 }
     45 
     46 // static
     47 Result Stream::analyzeStatus(const char* funcName, int status) {
     48     static const std::vector<int> empty;
     49     return analyzeStatus(funcName, status, empty);
     50 }
     51 
     52 template <typename T>
     53 inline bool element_in(T e, const std::vector<T>& v) {
     54     return std::find(v.begin(), v.end(), e) != v.end();
     55 }
     56 
     57 // static
     58 Result Stream::analyzeStatus(const char* funcName, int status,
     59                              const std::vector<int>& ignoreErrors) {
     60     if (status != 0 && (ignoreErrors.empty() || !element_in(-status, ignoreErrors))) {
     61         ALOGW("Error from HAL stream in function %s: %s", funcName, strerror(-status));
     62     }
     63     switch (status) {
     64         case 0: return Result::OK;
     65         case -EINVAL: return Result::INVALID_ARGUMENTS;
     66         case -ENODATA: return Result::INVALID_STATE;
     67         case -ENODEV: return Result::NOT_INITIALIZED;
     68         case -ENOSYS: return Result::NOT_SUPPORTED;
     69         default: return Result::INVALID_STATE;
     70     }
     71 }
     72 
     73 char* Stream::halGetParameters(const char* keys) {
     74     return mStream->get_parameters(mStream, keys);
     75 }
     76 
     77 int Stream::halSetParameters(const char* keysAndValues) {
     78     return mStream->set_parameters(mStream, keysAndValues);
     79 }
     80 
     81 // Methods from ::android::hardware::audio::V2_0::IStream follow.
     82 Return<uint64_t> Stream::getFrameSize()  {
     83     // Needs to be implemented by interface subclasses. But can't be declared as pure virtual,
     84     // since interface subclasses implementation do not inherit from this class.
     85     LOG_ALWAYS_FATAL("Stream::getFrameSize is pure abstract");
     86     return uint64_t {};
     87 }
     88 
     89 Return<uint64_t> Stream::getFrameCount()  {
     90     int halFrameCount;
     91     Result retval = getParam(AudioParameter::keyFrameCount, &halFrameCount);
     92     return retval == Result::OK ? halFrameCount : 0;
     93 }
     94 
     95 Return<uint64_t> Stream::getBufferSize()  {
     96     return mStream->get_buffer_size(mStream);
     97 }
     98 
     99 Return<uint32_t> Stream::getSampleRate()  {
    100     return mStream->get_sample_rate(mStream);
    101 }
    102 
    103 Return<void> Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb)  {
    104     String8 halListValue;
    105     Result result = getParam(AudioParameter::keyStreamSupportedSamplingRates, &halListValue);
    106     hidl_vec<uint32_t> sampleRates;
    107     SortedVector<uint32_t> halSampleRates;
    108     if (result == Result::OK) {
    109         halSampleRates = samplingRatesFromString(
    110                 halListValue.string(), AudioParameter::valueListSeparator);
    111         sampleRates.setToExternal(halSampleRates.editArray(), halSampleRates.size());
    112     }
    113     _hidl_cb(sampleRates);
    114     return Void();
    115 }
    116 
    117 Return<Result> Stream::setSampleRate(uint32_t sampleRateHz)  {
    118     return setParam(AudioParameter::keySamplingRate, static_cast<int>(sampleRateHz));
    119 }
    120 
    121 Return<AudioChannelMask> Stream::getChannelMask()  {
    122     return AudioChannelMask(mStream->get_channels(mStream));
    123 }
    124 
    125 Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb)  {
    126     String8 halListValue;
    127     Result result = getParam(AudioParameter::keyStreamSupportedChannels, &halListValue);
    128     hidl_vec<AudioChannelMask> channelMasks;
    129     SortedVector<audio_channel_mask_t> halChannelMasks;
    130     if (result == Result::OK) {
    131         halChannelMasks = channelMasksFromString(
    132                 halListValue.string(), AudioParameter::valueListSeparator);
    133         channelMasks.resize(halChannelMasks.size());
    134         for (size_t i = 0; i < halChannelMasks.size(); ++i) {
    135             channelMasks[i] = AudioChannelMask(halChannelMasks[i]);
    136         }
    137     }
    138      _hidl_cb(channelMasks);
    139     return Void();
    140 }
    141 
    142 Return<Result> Stream::setChannelMask(AudioChannelMask mask)  {
    143     return setParam(AudioParameter::keyChannels, static_cast<int>(mask));
    144 }
    145 
    146 Return<AudioFormat> Stream::getFormat()  {
    147     return AudioFormat(mStream->get_format(mStream));
    148 }
    149 
    150 Return<void> Stream::getSupportedFormats(getSupportedFormats_cb _hidl_cb)  {
    151     String8 halListValue;
    152     Result result = getParam(AudioParameter::keyStreamSupportedFormats, &halListValue);
    153     hidl_vec<AudioFormat> formats;
    154     Vector<audio_format_t> halFormats;
    155     if (result == Result::OK) {
    156         halFormats = formatsFromString(halListValue.string(), AudioParameter::valueListSeparator);
    157         formats.resize(halFormats.size());
    158         for (size_t i = 0; i < halFormats.size(); ++i) {
    159             formats[i] = AudioFormat(halFormats[i]);
    160         }
    161     }
    162      _hidl_cb(formats);
    163     return Void();
    164 }
    165 
    166 Return<Result> Stream::setFormat(AudioFormat format)  {
    167     return setParam(AudioParameter::keyFormat, static_cast<int>(format));
    168 }
    169 
    170 Return<void> Stream::getAudioProperties(getAudioProperties_cb _hidl_cb)  {
    171     uint32_t halSampleRate = mStream->get_sample_rate(mStream);
    172     audio_channel_mask_t halMask = mStream->get_channels(mStream);
    173     audio_format_t halFormat = mStream->get_format(mStream);
    174     _hidl_cb(halSampleRate, AudioChannelMask(halMask), AudioFormat(halFormat));
    175     return Void();
    176 }
    177 
    178 Return<Result> Stream::addEffect(uint64_t effectId)  {
    179     effect_handle_t halEffect = EffectMap::getInstance().get(effectId);
    180     if (halEffect != NULL) {
    181         return analyzeStatus("add_audio_effect", mStream->add_audio_effect(mStream, halEffect));
    182     } else {
    183         ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId);
    184         return Result::INVALID_ARGUMENTS;
    185     }
    186 }
    187 
    188 Return<Result> Stream::removeEffect(uint64_t effectId)  {
    189     effect_handle_t halEffect = EffectMap::getInstance().get(effectId);
    190     if (halEffect != NULL) {
    191         return analyzeStatus(
    192                 "remove_audio_effect", mStream->remove_audio_effect(mStream, halEffect));
    193     } else {
    194         ALOGW("Invalid effect ID passed from client: %" PRIu64, effectId);
    195         return Result::INVALID_ARGUMENTS;
    196     }
    197 }
    198 
    199 Return<Result> Stream::standby()  {
    200     return analyzeStatus("standby", mStream->standby(mStream));
    201 }
    202 
    203 Return<AudioDevice> Stream::getDevice()  {
    204     int device;
    205     Result retval = getParam(AudioParameter::keyRouting, &device);
    206     return retval == Result::OK ? static_cast<AudioDevice>(device) : AudioDevice::NONE;
    207 }
    208 
    209 Return<Result> Stream::setDevice(const DeviceAddress& address)  {
    210     char* halDeviceAddress =
    211             audio_device_address_to_parameter(
    212                     static_cast<audio_devices_t>(address.device),
    213                     deviceAddressToHal(address).c_str());
    214     AudioParameter params((String8(halDeviceAddress)));
    215     free(halDeviceAddress);
    216     params.addInt(
    217             String8(AudioParameter::keyRouting), static_cast<audio_devices_t>(address.device));
    218     return setParams(params);
    219 }
    220 
    221 Return<Result> Stream::setConnectedState(const DeviceAddress& address, bool connected)  {
    222     return setParam(
    223             connected ? AudioParameter::keyStreamConnect : AudioParameter::keyStreamDisconnect,
    224             deviceAddressToHal(address).c_str());
    225 }
    226 
    227 Return<Result> Stream::setHwAvSync(uint32_t hwAvSync)  {
    228     return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync));
    229 }
    230 
    231 Return<void> Stream::getParameters(const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb)  {
    232     getParametersImpl(keys, _hidl_cb);
    233     return Void();
    234 }
    235 
    236 Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters)  {
    237     return setParametersImpl(parameters);
    238 }
    239 
    240 Return<void> Stream::debugDump(const hidl_handle& fd)  {
    241     if (fd.getNativeHandle() != nullptr && fd->numFds == 1) {
    242         analyzeStatus("dump", mStream->dump(mStream, fd->data[0]));
    243     }
    244     return Void();
    245 }
    246 
    247 Return<Result>  Stream::start() {
    248     return Result::NOT_SUPPORTED;
    249 }
    250 
    251 Return<Result>  Stream::stop() {
    252     return Result::NOT_SUPPORTED;
    253 }
    254 
    255 Return<void>  Stream::createMmapBuffer(int32_t minSizeFrames __unused,
    256                                        createMmapBuffer_cb _hidl_cb) {
    257     Result retval(Result::NOT_SUPPORTED);
    258     MmapBufferInfo info;
    259     _hidl_cb(retval, info);
    260     return Void();
    261 }
    262 
    263 Return<void>  Stream::getMmapPosition(getMmapPosition_cb _hidl_cb) {
    264     Result retval(Result::NOT_SUPPORTED);
    265     MmapPosition position;
    266     _hidl_cb(retval, position);
    267     return Void();
    268 }
    269 
    270 Return<Result> Stream::close()  {
    271     return Result::NOT_SUPPORTED;
    272 }
    273 
    274 } // namespace implementation
    275 }  // namespace V2_0
    276 }  // namespace audio
    277 }  // namespace hardware
    278 }  // namespace android
    279