12355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk/*
22355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Copyright (C) 2016 The Android Open Source Project
32355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *
42355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Licensed under the Apache License, Version 2.0 (the "License");
52355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * you may not use this file except in compliance with the License.
62355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * You may obtain a copy of the License at
72355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *
82355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *      http://www.apache.org/licenses/LICENSE-2.0
92355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk *
102355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * Unless required by applicable law or agreed to in writing, software
112355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * distributed under the License is distributed on an "AS IS" BASIS,
122355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * See the License for the specific language governing permissions and
142355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk * limitations under the License.
152355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk */
162355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
175ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#define LOG_TAG "AAudioService"
182355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk//#define LOG_NDEBUG 0
192355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk#include <utils/Log.h>
202355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
21c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include <mutex>
22c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
23c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/IAAudioService.h"
24c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "binding/AAudioServiceMessage.h"
25c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "utility/AudioClock.h"
26c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
275ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk#include "AAudioServiceStreamBase.h"
28c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk#include "TimestampScheduler.h"
292355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
30c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing namespace android;  // TODO just import names needed
31c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkusing namespace aaudio;   // TODO just import names needed
322355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
332355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk/**
34c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Base class for streams in the service.
35c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * @return
362355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk */
372355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
385ed503c7a66c90f93759c90237a9b432dbd93f9fPhil BurkAAudioServiceStreamBase::AAudioServiceStreamBase()
392355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk        : mUpMessageQueue(nullptr)
40c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        , mAAudioThread() {
412355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk}
422355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
435ed503c7a66c90f93759c90237a9b432dbd93f9fPhil BurkAAudioServiceStreamBase::~AAudioServiceStreamBase() {
44c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    close();
45c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
46c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
47c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::open(const aaudio::AAudioStreamRequest &request,
48c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                     aaudio::AAudioStreamConfiguration &configurationOutput) {
49c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    std::lock_guard<std::mutex> lock(mLockUpMessageQueue);
50c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (mUpMessageQueue != nullptr) {
51c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return AAUDIO_ERROR_INVALID_STATE;
52c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    } else {
53c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        mUpMessageQueue = new SharedRingBuffer();
54c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return mUpMessageQueue->allocate(sizeof(AAudioServiceMessage), QUEUE_UP_CAPACITY_COMMANDS);
55c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
56c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
57c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
58c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::close() {
59c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    std::lock_guard<std::mutex> lock(mLockUpMessageQueue);
602355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    delete mUpMessageQueue;
61c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mUpMessageQueue = nullptr;
62942bdc0aebc88dc8b12c0e7742ec0003bbb8b80fPhil Burk
63c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return AAUDIO_OK;
642355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk}
652355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
66c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::start() {
67c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    sendServiceEvent(AAUDIO_SERVICE_EVENT_STARTED);
68c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mState = AAUDIO_STREAM_STATE_STARTED;
69c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mThreadEnabled.store(true);
70c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return mAAudioThread.start(this);
71c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
72c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
73c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::pause() {
74dec33abe3739b2116ef6fbac36f7ca5d26f9d190Phil Burk
75c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    sendCurrentTimestamp();
76c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mThreadEnabled.store(false);
77c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t result = mAAudioThread.stop();
78c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (result != AAUDIO_OK) {
79c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        processError();
80c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return result;
81c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
82c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    sendServiceEvent(AAUDIO_SERVICE_EVENT_PAUSED);
83c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mState = AAUDIO_STREAM_STATE_PAUSED;
84c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return result;
85c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
86c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
8771f35bb687476694882a617ba4a810a0bb56fe23Phil Burkaaudio_result_t AAudioServiceStreamBase::stop() {
8871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    // TODO wait for data to be played out
8971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    sendCurrentTimestamp();
9071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    mThreadEnabled.store(false);
9171f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    aaudio_result_t result = mAAudioThread.stop();
9271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (result != AAUDIO_OK) {
9371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        processError();
9471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        return result;
9571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
9671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    sendServiceEvent(AAUDIO_SERVICE_EVENT_STOPPED);
9771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    mState = AAUDIO_STREAM_STATE_STOPPED;
9871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    return result;
9971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk}
10071f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
10171f35bb687476694882a617ba4a810a0bb56fe23Phil Burkaaudio_result_t AAudioServiceStreamBase::flush() {
10271f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    sendServiceEvent(AAUDIO_SERVICE_EVENT_FLUSHED);
10371f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    mState = AAUDIO_STREAM_STATE_FLUSHED;
10471f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    return AAUDIO_OK;
10571f35bb687476694882a617ba4a810a0bb56fe23Phil Burk}
10671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk
107cf5f6d2825d9a8430a291042ca9c6f68e5b666d0Phil Burk// implement Runnable, periodically send timestamps to client
108c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkvoid AAudioServiceStreamBase::run() {
10971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    ALOGD("AAudioServiceStreamBase::run() entering ----------------");
110c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    TimestampScheduler timestampScheduler;
111c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    timestampScheduler.setBurstPeriod(mFramesPerBurst, mSampleRate);
112c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    timestampScheduler.start(AudioClock::getNanoseconds());
113c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int64_t nextTime = timestampScheduler.nextAbsoluteTime();
114c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    while(mThreadEnabled.load()) {
115c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        if (AudioClock::getNanoseconds() >= nextTime) {
116c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            aaudio_result_t result = sendCurrentTimestamp();
117c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            if (result != AAUDIO_OK) {
118c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                break;
119c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            }
120c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            nextTime = timestampScheduler.nextAbsoluteTime();
121c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        } else  {
122c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            // Sleep until it is time to send the next timestamp.
123c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk            AudioClock::sleepUntilNanoTime(nextTime);
124c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        }
125c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
12671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    ALOGD("AAudioServiceStreamBase::run() exiting ----------------");
127c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
128c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
129c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkvoid AAudioServiceStreamBase::processError() {
130c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    sendServiceEvent(AAUDIO_SERVICE_EVENT_DISCONNECTED);
131c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
132c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
133c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::sendServiceEvent(aaudio_service_event_t event,
134c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                               double  dataDouble,
135c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                               int64_t dataLong) {
1365ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    AAudioServiceMessage command;
1375ed503c7a66c90f93759c90237a9b432dbd93f9fPhil Burk    command.what = AAudioServiceMessage::code::EVENT;
1382355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk    command.event.event = event;
139c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    command.event.dataDouble = dataDouble;
140c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    command.event.dataLong = dataLong;
141c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return writeUpMessageQueue(&command);
142c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
143c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
144c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::writeUpMessageQueue(AAudioServiceMessage *command) {
145c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    std::lock_guard<std::mutex> lock(mLockUpMessageQueue);
14671f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    if (mUpMessageQueue == nullptr) {
14771f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        ALOGE("writeUpMessageQueue(): mUpMessageQueue null! - stream not open");
14871f35bb687476694882a617ba4a810a0bb56fe23Phil Burk        return AAUDIO_ERROR_NULL;
14971f35bb687476694882a617ba4a810a0bb56fe23Phil Burk    }
150c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
151c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (count != 1) {
152c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        ALOGE("writeUpMessageQueue(): Queue full. Did client die?");
153c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return AAUDIO_ERROR_WOULD_BLOCK;
154c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    } else {
155c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        return AAUDIO_OK;
156c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
157c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}
158c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk
159c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::sendCurrentTimestamp() {
160c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    AAudioServiceMessage command;
161c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    aaudio_result_t result = getFreeRunningPosition(&command.timestamp.position,
162c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                                    &command.timestamp.timestamp);
163c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    if (result == AAUDIO_OK) {
16487c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    //    ALOGD("sendCurrentTimestamp(): position = %lld, nanos = %lld",
16587c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    //          (long long) command.timestamp.position,
16687c9f646a94259d7c321c3b3d5947fa1778f5ac2Phil Burk    //          (long long) command.timestamp.timestamp);
167c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        command.what = AAudioServiceMessage::code::TIMESTAMP;
168c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk        result = writeUpMessageQueue(&command);
169c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    }
170c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return result;
1712355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk}
1722355edbcacfcb6e852a8707d893aaca788d42fdcPhil Burk
173c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk/**
174c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * Get an immutable description of the in-memory queues
175c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk * used to communicate with the underlying HAL or Service.
176c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk */
177c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burkaaudio_result_t AAudioServiceStreamBase::getDescription(AudioEndpointParcelable &parcelable) {
178c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    // Gather information on the message queue.
179c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    mUpMessageQueue->fillParcelable(parcelable,
180c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk                                    parcelable.mUpMessageQueueParcelable);
181c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk    return getDownDataDescription(parcelable);
182c0c70e3c7dd10bc2c0caffcab1f3f5fb406b35fbPhil Burk}