AAudioServiceStreamShared.cpp revision 71f35bb687476694882a617ba4a810a0bb56fe23
1c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/*
2c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Copyright (C) 2017 The Android Open Source Project
3c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *
4c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Licensed under the Apache License, Version 2.0 (the "License");
5c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * you may not use this file except in compliance with the License.
6c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * You may obtain a copy of the License at
7c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *
8c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *      http://www.apache.org/licenses/LICENSE-2.0
9c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *
10c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Unless required by applicable law or agreed to in writing, software
11c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * distributed under the License is distributed on an "AS IS" BASIS,
12c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * See the License for the specific language governing permissions and
14c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * limitations under the License.
15c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */
16c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
17c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#define LOG_TAG "AAudioService"
18c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk//#define LOG_NDEBUG 0
19c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <utils/Log.h>
20c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
21c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <mutex>
22c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
23c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <aaudio/AAudio.h>
24c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
25c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/IAAudioService.h"
26c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
27c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/AAudioServiceMessage.h"
28c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioServiceStreamBase.h"
29c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioServiceStreamShared.h"
30c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioEndpointManager.h"
31c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioService.h"
32c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "AAudioServiceEndpoint.h"
33c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
34c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing namespace android;
35c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing namespace aaudio;
36c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
37c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#define MIN_BURSTS_PER_BUFFER   2
38c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#define MAX_BURSTS_PER_BUFFER   32
39c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
40c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil BurkAAudioServiceStreamShared::AAudioServiceStreamShared(AAudioService &audioService)
41c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    : mAudioService(audioService)
42c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    {
43c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
44c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
45c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil BurkAAudioServiceStreamShared::~AAudioServiceStreamShared() {
46c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    close();
47c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
48c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
49c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::open(const aaudio::AAudioStreamRequest &request,
50c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                     aaudio::AAudioStreamConfiguration &configurationOutput)  {
51c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
52c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t result = AAudioServiceStreamBase::open(request, configurationOutput);
53c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (result != AAUDIO_OK) {
54c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        ALOGE("AAudioServiceStreamBase open returned %d", result);
55c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return result;
56c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
57c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
58c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
59c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t deviceId = configurationInput.getDeviceId();
60c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_direction_t direction = request.getDirection();
61c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
62c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    ALOGD("AAudioServiceStreamShared::open(), direction = %d", direction);
63c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
6471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    mServiceEndpoint = mEndpointManager.openEndpoint(mAudioService, deviceId, direction);
65c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    ALOGD("AAudioServiceStreamShared::open(), mServiceEndPoint = %p", mServiceEndpoint);
66c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (mServiceEndpoint == nullptr) {
67c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return AAUDIO_ERROR_UNAVAILABLE;
68c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
69c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
70c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Is the request compatible with the shared endpoint?
71c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mAudioFormat = configurationInput.getAudioFormat();
72c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (mAudioFormat == AAUDIO_FORMAT_UNSPECIFIED) {
73c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mAudioFormat = AAUDIO_FORMAT_PCM_FLOAT;
74c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    } else if (mAudioFormat != AAUDIO_FORMAT_PCM_FLOAT) {
7571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        ALOGE("AAudioServiceStreamShared::open(), mAudioFormat = %d, need FLOAT", mAudioFormat);
76c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return AAUDIO_ERROR_INVALID_FORMAT;
77c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
78c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
79c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mSampleRate = configurationInput.getSampleRate();
80c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (mSampleRate == AAUDIO_FORMAT_UNSPECIFIED) {
81c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mSampleRate = mServiceEndpoint->getSampleRate();
82c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    } else if (mSampleRate != mServiceEndpoint->getSampleRate()) {
8371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        ALOGE("AAudioServiceStreamShared::open(), mAudioFormat = %d, need %d",
8471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk              mSampleRate, mServiceEndpoint->getSampleRate());
85c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return AAUDIO_ERROR_INVALID_RATE;
86c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
87c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
88c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mSamplesPerFrame = configurationInput.getSamplesPerFrame();
89c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (mSamplesPerFrame == AAUDIO_FORMAT_UNSPECIFIED) {
90c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mSamplesPerFrame = mServiceEndpoint->getSamplesPerFrame();
91c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    } else if (mSamplesPerFrame != mServiceEndpoint->getSamplesPerFrame()) {
9271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        ALOGE("AAudioServiceStreamShared::open(), mSamplesPerFrame = %d, need %d",
9371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk              mSamplesPerFrame, mServiceEndpoint->getSamplesPerFrame());
94c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return AAUDIO_ERROR_OUT_OF_RANGE;
95c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
96c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
97c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Determine this stream's shared memory buffer capacity.
98c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mFramesPerBurst = mServiceEndpoint->getFramesPerBurst();
99c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t minCapacityFrames = configurationInput.getBufferCapacity();
10071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    int32_t numBursts = MAX_BURSTS_PER_BUFFER;
10171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (minCapacityFrames != AAUDIO_UNSPECIFIED) {
10271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        numBursts = (minCapacityFrames + mFramesPerBurst - 1) / mFramesPerBurst;
10371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        if (numBursts < MIN_BURSTS_PER_BUFFER) {
10471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            numBursts = MIN_BURSTS_PER_BUFFER;
10571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        } else if (numBursts > MAX_BURSTS_PER_BUFFER) {
10671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk            numBursts = MAX_BURSTS_PER_BUFFER;
10771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        }
108c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
109c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mCapacityInFrames = numBursts * mFramesPerBurst;
110c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    ALOGD("AAudioServiceStreamShared::open(), mCapacityInFrames = %d", mCapacityInFrames);
111c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
112c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Create audio data shared memory buffer for client.
113c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mAudioDataQueue = new SharedRingBuffer();
114c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mAudioDataQueue->allocate(calculateBytesPerFrame(), mCapacityInFrames);
115c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
116c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Fill in configuration for client.
117c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    configurationOutput.setSampleRate(mSampleRate);
118c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    configurationOutput.setSamplesPerFrame(mSamplesPerFrame);
119c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    configurationOutput.setAudioFormat(mAudioFormat);
120c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    configurationOutput.setDeviceId(deviceId);
121c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
122c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mServiceEndpoint->registerStream(this);
123c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
124c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return AAUDIO_OK;
125c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
126c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
127c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/**
128c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Start the flow of audio data.
129c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *
130c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete.
131c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */
132c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::start()  {
13371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    AAudioServiceEndpoint *endpoint = mServiceEndpoint;
13471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (endpoint == nullptr) {
13571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        return AAUDIO_ERROR_INVALID_STATE;
13671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
137c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Add this stream to the mixer.
13871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    aaudio_result_t result = endpoint->startStream(this);
139c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (result != AAUDIO_OK) {
140c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        ALOGE("AAudioServiceStreamShared::start() mServiceEndpoint returned %d", result);
141c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        processError();
142c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    } else {
143c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        result = AAudioServiceStreamBase::start();
144c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
145c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return AAUDIO_OK;
146c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
147c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
148c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/**
149c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Stop the flow of data so that start() can resume without loss of data.
150c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *
151c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete.
152c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk*/
153c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::pause()  {
15471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    AAudioServiceEndpoint *endpoint = mServiceEndpoint;
15571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (endpoint == nullptr) {
15671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        return AAUDIO_ERROR_INVALID_STATE;
15771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
15871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    // Add this stream to the mixer.
15971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    aaudio_result_t result = endpoint->stopStream(this);
16071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (result != AAUDIO_OK) {
16171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        ALOGE("AAudioServiceStreamShared::pause() mServiceEndpoint returned %d", result);
16271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        processError();
16371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
16471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    return AAudioServiceStreamBase::pause();
16571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk}
16671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
16771f35bb687476694882a617ba4a810a0bb56fe23Phil Burkaaudio_result_t AAudioServiceStreamShared::stop()  {
16871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    AAudioServiceEndpoint *endpoint = mServiceEndpoint;
16971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (endpoint == nullptr) {
17071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        return AAUDIO_ERROR_INVALID_STATE;
17171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
172c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Add this stream to the mixer.
17371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    aaudio_result_t result = endpoint->stopStream(this);
174c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (result != AAUDIO_OK) {
175c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        ALOGE("AAudioServiceStreamShared::stop() mServiceEndpoint returned %d", result);
176c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        processError();
177c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
17871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    return AAudioServiceStreamBase::stop();
179c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
180c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
181c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/**
182c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *  Discard any data held by the underlying HAL or Service.
183c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk *
184c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete.
185c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */
186c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::flush()  {
187c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // TODO make sure we are paused
18871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    // TODO actually flush the data
18971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    return AAudioServiceStreamBase::flush() ;
190c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
191c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
192c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::close()  {
193c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    pause();
194c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // TODO wait for pause() to synchronize
19571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    AAudioServiceEndpoint *endpoint = mServiceEndpoint;
19671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (endpoint != nullptr) {
19771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        endpoint->unregisterStream(this);
19871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
19971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        AAudioEndpointManager &mEndpointManager = AAudioEndpointManager::getInstance();
20071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        mEndpointManager.closeEndpoint(endpoint);
20171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        mServiceEndpoint = nullptr;
20271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
203c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return AAudioServiceStreamBase::close();
204c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
205c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
206c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/**
207c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Get an immutable description of the data queue created by this service.
208c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */
209c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::getDownDataDescription(AudioEndpointParcelable &parcelable)
210c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk{
211c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Gather information on the data queue.
212c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mAudioDataQueue->fillParcelable(parcelable,
213c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                    parcelable.mDownDataQueueParcelable);
214c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    parcelable.mDownDataQueueParcelable.setFramesPerBurst(getFramesPerBurst());
215c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return AAUDIO_OK;
216c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
217c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
218c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkvoid AAudioServiceStreamShared::onStop() {
219c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
220c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
221c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkvoid AAudioServiceStreamShared::onDisconnect() {
222c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mServiceEndpoint->close();
223c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mServiceEndpoint = nullptr;
224c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
225c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
22671f35bb687476694882a617ba4a810a0bb56fe23Phil Burkvoid AAudioServiceStreamShared::markTransferTime(int64_t nanoseconds) {
22771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    mMarkedPosition = mAudioDataQueue->getFifoBuffer()->getReadCounter();
22871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    mMarkedTime = nanoseconds;
22971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk}
230c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
231c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamShared::getFreeRunningPosition(int64_t *positionFrames,
232c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                                                int64_t *timeNanos) {
23371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    // TODO get these two numbers as an atomic pair
23471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    *positionFrames = mMarkedPosition;
23571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    *timeNanos = mMarkedTime;
236c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return AAUDIO_OK;
237c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
238