Home | History | Annotate | Download | only in default
      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 
     39 Stream::Stream(audio_stream_t* stream) : mStream(stream) {}
     40 
     41 Stream::~Stream() {
     42     mStream = nullptr;
     43 }
     44 
     45 // static
     46 Result Stream::analyzeStatus(const char* funcName, int status) {
     47     return util::analyzeStatus("stream", funcName, status);
     48 }
     49 
     50 // static
     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 
     56 char* Stream::halGetParameters(const char* keys) {
     57     return mStream->get_parameters(mStream, keys);
     58 }
     59 
     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.
     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 
     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 
     78 Return<uint64_t> Stream::getBufferSize() {
     79     return mStream->get_buffer_size(mStream);
     80 }
     81 
     82 Return<uint32_t> Stream::getSampleRate() {
     83     return mStream->get_sample_rate(mStream);
     84 }
     85 
     86 #if MAJOR_VERSION == 2
     87 Return<void> Stream::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) {
     88     return getSupportedSampleRates(getFormat(), _hidl_cb);
     89 }
     90 Return<void> Stream::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) {
     91     return getSupportedChannelMasks(getFormat(), _hidl_cb);
     92 }
     93 #endif
     94 
     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 
    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 
    151 Return<Result> Stream::setSampleRate(uint32_t sampleRateHz) {
    152     return setParam(AudioParameter::keySamplingRate, static_cast<int>(sampleRateHz));
    153 }
    154 
    155 Return<AudioChannelBitfield> Stream::getChannelMask() {
    156     return AudioChannelBitfield(mStream->get_channels(mStream));
    157 }
    158 
    159 Return<Result> Stream::setChannelMask(AudioChannelBitfield mask) {
    160     return setParam(AudioParameter::keyChannels, static_cast<int>(mask));
    161 }
    162 
    163 Return<AudioFormat> Stream::getFormat() {
    164     return AudioFormat(mStream->get_format(mStream));
    165 }
    166 
    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 
    183 Return<Result> Stream::setFormat(AudioFormat format) {
    184     return setParam(AudioParameter::keyFormat, static_cast<int>(format));
    185 }
    186 
    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 
    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 
    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 
    216 Return<Result> Stream::standby() {
    217     return analyzeStatus("standby", mStream->standby(mStream));
    218 }
    219 
    220 Return<Result> Stream::setHwAvSync(uint32_t hwAvSync) {
    221     return setParam(AudioParameter::keyStreamHwAvSync, static_cast<int>(hwAvSync));
    222 }
    223 
    224 #if MAJOR_VERSION == 2
    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 
    231 Return<Result> Stream::setDevice(const DeviceAddress& address) {
    232     return setParam(AudioParameter::keyRouting, address);
    233 }
    234 
    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 
    240 Return<Result> Stream::setParameters(const hidl_vec<ParameterValue>& parameters) {
    241     return setParametersImpl({} /* context */, parameters);
    242 }
    243 
    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
    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 
    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 }
    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 
    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 
    287 Return<Result> Stream::start() {
    288     return Result::NOT_SUPPORTED;
    289 }
    290 
    291 Return<Result> Stream::stop() {
    292     return Result::NOT_SUPPORTED;
    293 }
    294 
    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 
    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 
    310 Return<Result> Stream::close() {
    311     return Result::NOT_SUPPORTED;
    312 }
    313 
    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
    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