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}