StreamOut.impl.h revision 10548295023bee99108e418499aff09fe578211e
110548295023bee99108e418499aff09fe578211eMikhail Naganov/*
210548295023bee99108e418499aff09fe578211eMikhail Naganov * Copyright (C) 2016 The Android Open Source Project
310548295023bee99108e418499aff09fe578211eMikhail Naganov *
410548295023bee99108e418499aff09fe578211eMikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License");
510548295023bee99108e418499aff09fe578211eMikhail Naganov * you may not use this file except in compliance with the License.
610548295023bee99108e418499aff09fe578211eMikhail Naganov * You may obtain a copy of the License at
710548295023bee99108e418499aff09fe578211eMikhail Naganov *
810548295023bee99108e418499aff09fe578211eMikhail Naganov *      http://www.apache.org/licenses/LICENSE-2.0
910548295023bee99108e418499aff09fe578211eMikhail Naganov *
1010548295023bee99108e418499aff09fe578211eMikhail Naganov * Unless required by applicable law or agreed to in writing, software
1110548295023bee99108e418499aff09fe578211eMikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS,
1210548295023bee99108e418499aff09fe578211eMikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310548295023bee99108e418499aff09fe578211eMikhail Naganov * See the License for the specific language governing permissions and
1410548295023bee99108e418499aff09fe578211eMikhail Naganov * limitations under the License.
1510548295023bee99108e418499aff09fe578211eMikhail Naganov */
1610548295023bee99108e418499aff09fe578211eMikhail Naganov
1710548295023bee99108e418499aff09fe578211eMikhail Naganov#define LOG_TAG "StreamOutHAL"
1810548295023bee99108e418499aff09fe578211eMikhail Naganov
1910548295023bee99108e418499aff09fe578211eMikhail Naganov#include <hardware/audio.h>
2010548295023bee99108e418499aff09fe578211eMikhail Naganov#include <utils/Log.h>
2110548295023bee99108e418499aff09fe578211eMikhail Naganov
2210548295023bee99108e418499aff09fe578211eMikhail Naganov#include "StreamOut.h"
2310548295023bee99108e418499aff09fe578211eMikhail Naganov
2410548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace android {
2510548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace hardware {
2610548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace audio {
2710548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace V2_0 {
2810548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace implementation {
2910548295023bee99108e418499aff09fe578211eMikhail Naganov
3010548295023bee99108e418499aff09fe578211eMikhail NaganovStreamOut::StreamOut(audio_hw_device_t* device, audio_stream_out_t* stream)
3110548295023bee99108e418499aff09fe578211eMikhail Naganov        : mDevice(device), mStream(stream), mStreamCommon(new Stream(&stream->common)) {
3210548295023bee99108e418499aff09fe578211eMikhail Naganov}
3310548295023bee99108e418499aff09fe578211eMikhail Naganov
3410548295023bee99108e418499aff09fe578211eMikhail NaganovStreamOut::~StreamOut() {
3510548295023bee99108e418499aff09fe578211eMikhail Naganov    mCallback.clear();
3610548295023bee99108e418499aff09fe578211eMikhail Naganov    mDevice->close_output_stream(mDevice, mStream);
3710548295023bee99108e418499aff09fe578211eMikhail Naganov    mStream = nullptr;
3810548295023bee99108e418499aff09fe578211eMikhail Naganov    mDevice = nullptr;
3910548295023bee99108e418499aff09fe578211eMikhail Naganov}
4010548295023bee99108e418499aff09fe578211eMikhail Naganov
4110548295023bee99108e418499aff09fe578211eMikhail Naganov// Methods from ::android::hardware::audio::V2_0::IStream follow.
4210548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<uint64_t> StreamOut::getFrameSize()  {
4310548295023bee99108e418499aff09fe578211eMikhail Naganov    return audio_stream_out_frame_size(mStream);
4410548295023bee99108e418499aff09fe578211eMikhail Naganov}
4510548295023bee99108e418499aff09fe578211eMikhail Naganov
4610548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<uint64_t> StreamOut::getFrameCount()  {
4710548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getFrameCount();
4810548295023bee99108e418499aff09fe578211eMikhail Naganov}
4910548295023bee99108e418499aff09fe578211eMikhail Naganov
5010548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<uint64_t> StreamOut::getBufferSize()  {
5110548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getBufferSize();
5210548295023bee99108e418499aff09fe578211eMikhail Naganov}
5310548295023bee99108e418499aff09fe578211eMikhail Naganov
5410548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<uint32_t> StreamOut::getSampleRate()  {
5510548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getSampleRate();
5610548295023bee99108e418499aff09fe578211eMikhail Naganov}
5710548295023bee99108e418499aff09fe578211eMikhail Naganov
5810548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb)  {
5910548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getSupportedSampleRates(_hidl_cb);
6010548295023bee99108e418499aff09fe578211eMikhail Naganov}
6110548295023bee99108e418499aff09fe578211eMikhail Naganov
6210548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setSampleRate(uint32_t sampleRateHz)  {
6310548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->setSampleRate(sampleRateHz);
6410548295023bee99108e418499aff09fe578211eMikhail Naganov}
6510548295023bee99108e418499aff09fe578211eMikhail Naganov
6610548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<AudioChannelMask> StreamOut::getChannelMask()  {
6710548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getChannelMask();
6810548295023bee99108e418499aff09fe578211eMikhail Naganov}
6910548295023bee99108e418499aff09fe578211eMikhail Naganov
7010548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb)  {
7110548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getSupportedChannelMasks(_hidl_cb);
7210548295023bee99108e418499aff09fe578211eMikhail Naganov}
7310548295023bee99108e418499aff09fe578211eMikhail Naganov
7410548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setChannelMask(AudioChannelMask mask)  {
7510548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->setChannelMask(mask);
7610548295023bee99108e418499aff09fe578211eMikhail Naganov}
7710548295023bee99108e418499aff09fe578211eMikhail Naganov
7810548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<AudioFormat> StreamOut::getFormat()  {
7910548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getFormat();
8010548295023bee99108e418499aff09fe578211eMikhail Naganov}
8110548295023bee99108e418499aff09fe578211eMikhail Naganov
8210548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getSupportedFormats(getSupportedFormats_cb _hidl_cb)  {
8310548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getSupportedFormats(_hidl_cb);
8410548295023bee99108e418499aff09fe578211eMikhail Naganov}
8510548295023bee99108e418499aff09fe578211eMikhail Naganov
8610548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setFormat(AudioFormat format)  {
8710548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->setFormat(format);
8810548295023bee99108e418499aff09fe578211eMikhail Naganov}
8910548295023bee99108e418499aff09fe578211eMikhail Naganov
9010548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getAudioProperties(getAudioProperties_cb _hidl_cb)  {
9110548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getAudioProperties(_hidl_cb);
9210548295023bee99108e418499aff09fe578211eMikhail Naganov}
9310548295023bee99108e418499aff09fe578211eMikhail Naganov
9410548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::addEffect(uint64_t effectId)  {
9510548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->addEffect(effectId);
9610548295023bee99108e418499aff09fe578211eMikhail Naganov}
9710548295023bee99108e418499aff09fe578211eMikhail Naganov
9810548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::removeEffect(uint64_t effectId)  {
9910548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->removeEffect(effectId);
10010548295023bee99108e418499aff09fe578211eMikhail Naganov}
10110548295023bee99108e418499aff09fe578211eMikhail Naganov
10210548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::standby()  {
10310548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->standby();
10410548295023bee99108e418499aff09fe578211eMikhail Naganov}
10510548295023bee99108e418499aff09fe578211eMikhail Naganov
10610548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<AudioDevice> StreamOut::getDevice()  {
10710548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getDevice();
10810548295023bee99108e418499aff09fe578211eMikhail Naganov}
10910548295023bee99108e418499aff09fe578211eMikhail Naganov
11010548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setDevice(const DeviceAddress& address)  {
11110548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->setDevice(address);
11210548295023bee99108e418499aff09fe578211eMikhail Naganov}
11310548295023bee99108e418499aff09fe578211eMikhail Naganov
11410548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setConnectedState(const DeviceAddress& address, bool connected)  {
11510548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->setConnectedState(address, connected);
11610548295023bee99108e418499aff09fe578211eMikhail Naganov}
11710548295023bee99108e418499aff09fe578211eMikhail Naganov
11810548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setHwAvSync(uint32_t hwAvSync)  {
11910548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->setHwAvSync(hwAvSync);
12010548295023bee99108e418499aff09fe578211eMikhail Naganov}
12110548295023bee99108e418499aff09fe578211eMikhail Naganov
12210548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getParameters(
12310548295023bee99108e418499aff09fe578211eMikhail Naganov        const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb)  {
12410548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->getParameters(keys, _hidl_cb);
12510548295023bee99108e418499aff09fe578211eMikhail Naganov}
12610548295023bee99108e418499aff09fe578211eMikhail Naganov
12710548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setParameters(const hidl_vec<ParameterValue>& parameters)  {
12810548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->setParameters(parameters);
12910548295023bee99108e418499aff09fe578211eMikhail Naganov}
13010548295023bee99108e418499aff09fe578211eMikhail Naganov
13110548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::debugDump(const native_handle_t* fd)  {
13210548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->debugDump(fd);
13310548295023bee99108e418499aff09fe578211eMikhail Naganov}
13410548295023bee99108e418499aff09fe578211eMikhail Naganov
13510548295023bee99108e418499aff09fe578211eMikhail Naganov
13610548295023bee99108e418499aff09fe578211eMikhail Naganov// Methods from ::android::hardware::audio::V2_0::IStreamOut follow.
13710548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<uint32_t> StreamOut::getLatency()  {
13810548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStream->get_latency(mStream);
13910548295023bee99108e418499aff09fe578211eMikhail Naganov}
14010548295023bee99108e418499aff09fe578211eMikhail Naganov
14110548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setVolume(float left, float right)  {
14210548295023bee99108e418499aff09fe578211eMikhail Naganov    Result retval(Result::NOT_SUPPORTED);
14310548295023bee99108e418499aff09fe578211eMikhail Naganov    if (mStream->set_volume != NULL) {
14410548295023bee99108e418499aff09fe578211eMikhail Naganov        retval = mStreamCommon->analyzeStatus(
14510548295023bee99108e418499aff09fe578211eMikhail Naganov                "set_volume", mStream->set_volume(mStream, left, right));
14610548295023bee99108e418499aff09fe578211eMikhail Naganov    }
14710548295023bee99108e418499aff09fe578211eMikhail Naganov    return retval;
14810548295023bee99108e418499aff09fe578211eMikhail Naganov}
14910548295023bee99108e418499aff09fe578211eMikhail Naganov
15010548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::write(const hidl_vec<uint8_t>& data, write_cb _hidl_cb)  {
15110548295023bee99108e418499aff09fe578211eMikhail Naganov    // TODO(mnaganov): Replace with FMQ version.
15210548295023bee99108e418499aff09fe578211eMikhail Naganov    Result retval(Result::OK);
15310548295023bee99108e418499aff09fe578211eMikhail Naganov    uint64_t written = 0;
15410548295023bee99108e418499aff09fe578211eMikhail Naganov    ssize_t writeResult = mStream->write(mStream, &data[0], data.size());
15510548295023bee99108e418499aff09fe578211eMikhail Naganov    if (writeResult >= 0) {
15610548295023bee99108e418499aff09fe578211eMikhail Naganov        written = writeResult;
15710548295023bee99108e418499aff09fe578211eMikhail Naganov    } else {
15810548295023bee99108e418499aff09fe578211eMikhail Naganov        retval = mStreamCommon->analyzeStatus("write", writeResult);
15910548295023bee99108e418499aff09fe578211eMikhail Naganov        written = 0;
16010548295023bee99108e418499aff09fe578211eMikhail Naganov    }
16110548295023bee99108e418499aff09fe578211eMikhail Naganov    _hidl_cb(retval, written);
16210548295023bee99108e418499aff09fe578211eMikhail Naganov    return Void();
16310548295023bee99108e418499aff09fe578211eMikhail Naganov}
16410548295023bee99108e418499aff09fe578211eMikhail Naganov
16510548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getRenderPosition(getRenderPosition_cb _hidl_cb)  {
16610548295023bee99108e418499aff09fe578211eMikhail Naganov    uint32_t halDspFrames;
16710548295023bee99108e418499aff09fe578211eMikhail Naganov    Result retval = mStreamCommon->analyzeStatus(
16810548295023bee99108e418499aff09fe578211eMikhail Naganov            "get_render_position", mStream->get_render_position(mStream, &halDspFrames));
16910548295023bee99108e418499aff09fe578211eMikhail Naganov    _hidl_cb(retval, halDspFrames);
17010548295023bee99108e418499aff09fe578211eMikhail Naganov    return Void();
17110548295023bee99108e418499aff09fe578211eMikhail Naganov}
17210548295023bee99108e418499aff09fe578211eMikhail Naganov
17310548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getNextWriteTimestamp(getNextWriteTimestamp_cb _hidl_cb)  {
17410548295023bee99108e418499aff09fe578211eMikhail Naganov    Result retval(Result::NOT_SUPPORTED);
17510548295023bee99108e418499aff09fe578211eMikhail Naganov    int64_t timestampUs = 0;
17610548295023bee99108e418499aff09fe578211eMikhail Naganov    if (mStream->get_next_write_timestamp != NULL) {
17710548295023bee99108e418499aff09fe578211eMikhail Naganov        retval = mStreamCommon->analyzeStatus(
17810548295023bee99108e418499aff09fe578211eMikhail Naganov                "get_next_write_timestamp",
17910548295023bee99108e418499aff09fe578211eMikhail Naganov                mStream->get_next_write_timestamp(mStream, &timestampUs));
18010548295023bee99108e418499aff09fe578211eMikhail Naganov    }
18110548295023bee99108e418499aff09fe578211eMikhail Naganov    _hidl_cb(retval, timestampUs);
18210548295023bee99108e418499aff09fe578211eMikhail Naganov    return Void();
18310548295023bee99108e418499aff09fe578211eMikhail Naganov}
18410548295023bee99108e418499aff09fe578211eMikhail Naganov
18510548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::setCallback(const sp<IStreamOutCallback>& callback)  {
18610548295023bee99108e418499aff09fe578211eMikhail Naganov    if (mStream->set_callback == NULL) return Result::NOT_SUPPORTED;
18710548295023bee99108e418499aff09fe578211eMikhail Naganov    int result = mStream->set_callback(mStream, StreamOut::asyncCallback, this);
18810548295023bee99108e418499aff09fe578211eMikhail Naganov    if (result == 0) {
18910548295023bee99108e418499aff09fe578211eMikhail Naganov        mCallback = callback;
19010548295023bee99108e418499aff09fe578211eMikhail Naganov    }
19110548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStreamCommon->analyzeStatus("set_callback", result);
19210548295023bee99108e418499aff09fe578211eMikhail Naganov}
19310548295023bee99108e418499aff09fe578211eMikhail Naganov
19410548295023bee99108e418499aff09fe578211eMikhail Naganov// static
19510548295023bee99108e418499aff09fe578211eMikhail Naganovint StreamOut::asyncCallback(stream_callback_event_t event, void*, void *cookie) {
19610548295023bee99108e418499aff09fe578211eMikhail Naganov    wp<StreamOut> weakSelf(reinterpret_cast<StreamOut*>(cookie));
19710548295023bee99108e418499aff09fe578211eMikhail Naganov    sp<StreamOut> self = weakSelf.promote();
19810548295023bee99108e418499aff09fe578211eMikhail Naganov    if (self == 0) return 0;
19910548295023bee99108e418499aff09fe578211eMikhail Naganov    sp<IStreamOutCallback> callback = self->mCallback.promote();
20010548295023bee99108e418499aff09fe578211eMikhail Naganov    if (callback == 0) return 0;
20110548295023bee99108e418499aff09fe578211eMikhail Naganov    ALOGV("asyncCallback() event %d", event);
20210548295023bee99108e418499aff09fe578211eMikhail Naganov    switch (event) {
20310548295023bee99108e418499aff09fe578211eMikhail Naganov        case STREAM_CBK_EVENT_WRITE_READY:
20410548295023bee99108e418499aff09fe578211eMikhail Naganov            callback->onWriteReady();
20510548295023bee99108e418499aff09fe578211eMikhail Naganov            break;
20610548295023bee99108e418499aff09fe578211eMikhail Naganov        case STREAM_CBK_EVENT_DRAIN_READY:
20710548295023bee99108e418499aff09fe578211eMikhail Naganov            callback->onDrainReady();
20810548295023bee99108e418499aff09fe578211eMikhail Naganov            break;
20910548295023bee99108e418499aff09fe578211eMikhail Naganov        case STREAM_CBK_EVENT_ERROR:
21010548295023bee99108e418499aff09fe578211eMikhail Naganov            callback->onError();
21110548295023bee99108e418499aff09fe578211eMikhail Naganov            break;
21210548295023bee99108e418499aff09fe578211eMikhail Naganov        default:
21310548295023bee99108e418499aff09fe578211eMikhail Naganov            ALOGW("asyncCallback() unknown event %d", event);
21410548295023bee99108e418499aff09fe578211eMikhail Naganov            break;
21510548295023bee99108e418499aff09fe578211eMikhail Naganov    }
21610548295023bee99108e418499aff09fe578211eMikhail Naganov    return 0;
21710548295023bee99108e418499aff09fe578211eMikhail Naganov}
21810548295023bee99108e418499aff09fe578211eMikhail Naganov
21910548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::supportsPauseAndResume(supportsPauseAndResume_cb _hidl_cb)  {
22010548295023bee99108e418499aff09fe578211eMikhail Naganov    _hidl_cb(mStream->pause != NULL, mStream->resume != NULL);
22110548295023bee99108e418499aff09fe578211eMikhail Naganov    return Void();
22210548295023bee99108e418499aff09fe578211eMikhail Naganov}
22310548295023bee99108e418499aff09fe578211eMikhail Naganov
22410548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::pause()  {
22510548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStream->pause != NULL ?
22610548295023bee99108e418499aff09fe578211eMikhail Naganov            mStreamCommon->analyzeStatus("pause", mStream->pause(mStream)) :
22710548295023bee99108e418499aff09fe578211eMikhail Naganov            Result::NOT_SUPPORTED;
22810548295023bee99108e418499aff09fe578211eMikhail Naganov}
22910548295023bee99108e418499aff09fe578211eMikhail Naganov
23010548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::resume()  {
23110548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStream->resume != NULL ?
23210548295023bee99108e418499aff09fe578211eMikhail Naganov            mStreamCommon->analyzeStatus("resume", mStream->resume(mStream)) :
23310548295023bee99108e418499aff09fe578211eMikhail Naganov            Result::NOT_SUPPORTED;
23410548295023bee99108e418499aff09fe578211eMikhail Naganov}
23510548295023bee99108e418499aff09fe578211eMikhail Naganov
23610548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<bool> StreamOut::supportsDrain()  {
23710548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStream->drain != NULL;
23810548295023bee99108e418499aff09fe578211eMikhail Naganov}
23910548295023bee99108e418499aff09fe578211eMikhail Naganov
24010548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::drain(AudioDrain type)  {
24110548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStream->drain != NULL ?
24210548295023bee99108e418499aff09fe578211eMikhail Naganov            mStreamCommon->analyzeStatus(
24310548295023bee99108e418499aff09fe578211eMikhail Naganov                    "drain", mStream->drain(mStream, static_cast<audio_drain_type_t>(type))) :
24410548295023bee99108e418499aff09fe578211eMikhail Naganov            Result::NOT_SUPPORTED;
24510548295023bee99108e418499aff09fe578211eMikhail Naganov}
24610548295023bee99108e418499aff09fe578211eMikhail Naganov
24710548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<Result> StreamOut::flush()  {
24810548295023bee99108e418499aff09fe578211eMikhail Naganov    return mStream->flush != NULL ?
24910548295023bee99108e418499aff09fe578211eMikhail Naganov            mStreamCommon->analyzeStatus("flush", mStream->flush(mStream)) :
25010548295023bee99108e418499aff09fe578211eMikhail Naganov            Result::NOT_SUPPORTED;
25110548295023bee99108e418499aff09fe578211eMikhail Naganov}
25210548295023bee99108e418499aff09fe578211eMikhail Naganov
25310548295023bee99108e418499aff09fe578211eMikhail NaganovReturn<void> StreamOut::getPresentationPosition(getPresentationPosition_cb _hidl_cb)  {
25410548295023bee99108e418499aff09fe578211eMikhail Naganov    Result retval(Result::NOT_SUPPORTED);
25510548295023bee99108e418499aff09fe578211eMikhail Naganov    uint64_t frames = 0;
25610548295023bee99108e418499aff09fe578211eMikhail Naganov    TimeSpec timeStamp = { 0, 0 };
25710548295023bee99108e418499aff09fe578211eMikhail Naganov    if (mStream->get_presentation_position != NULL) {
25810548295023bee99108e418499aff09fe578211eMikhail Naganov        struct timespec halTimeStamp;
25910548295023bee99108e418499aff09fe578211eMikhail Naganov        retval = mStreamCommon->analyzeStatus(
26010548295023bee99108e418499aff09fe578211eMikhail Naganov                "get_presentation_position",
26110548295023bee99108e418499aff09fe578211eMikhail Naganov                mStream->get_presentation_position(mStream, &frames, &halTimeStamp));
26210548295023bee99108e418499aff09fe578211eMikhail Naganov        if (retval == Result::OK) {
26310548295023bee99108e418499aff09fe578211eMikhail Naganov            timeStamp.tvSec = halTimeStamp.tv_sec;
26410548295023bee99108e418499aff09fe578211eMikhail Naganov            timeStamp.tvNSec = halTimeStamp.tv_nsec;
26510548295023bee99108e418499aff09fe578211eMikhail Naganov        }
26610548295023bee99108e418499aff09fe578211eMikhail Naganov    }
26710548295023bee99108e418499aff09fe578211eMikhail Naganov    _hidl_cb(retval, frames, timeStamp);
26810548295023bee99108e418499aff09fe578211eMikhail Naganov    return Void();
26910548295023bee99108e418499aff09fe578211eMikhail Naganov}
27010548295023bee99108e418499aff09fe578211eMikhail Naganov
27110548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace implementation
27210548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace V2_0
27310548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace audio
27410548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace hardware
27510548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace android
276