1*ec779b8eSAndroid Build Coastguard Worker /* 2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*ec779b8eSAndroid Build Coastguard Worker * 4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*ec779b8eSAndroid Build Coastguard Worker * 8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*ec779b8eSAndroid Build Coastguard Worker * 10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License. 15*ec779b8eSAndroid Build Coastguard Worker */ 16*ec779b8eSAndroid Build Coastguard Worker 17*ec779b8eSAndroid Build Coastguard Worker #ifndef AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 18*ec779b8eSAndroid Build Coastguard Worker #define AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 19*ec779b8eSAndroid Build Coastguard Worker 20*ec779b8eSAndroid Build Coastguard Worker #include <assert.h> 21*ec779b8eSAndroid Build Coastguard Worker #include <mutex> 22*ec779b8eSAndroid Build Coastguard Worker 23*ec779b8eSAndroid Build Coastguard Worker #include <android-base/thread_annotations.h> 24*ec779b8eSAndroid Build Coastguard Worker #include <media/AidlConversion.h> 25*ec779b8eSAndroid Build Coastguard Worker #include <media/AudioClient.h> 26*ec779b8eSAndroid Build Coastguard Worker #include <utils/RefBase.h> 27*ec779b8eSAndroid Build Coastguard Worker 28*ec779b8eSAndroid Build Coastguard Worker #include "fifo/FifoBuffer.h" 29*ec779b8eSAndroid Build Coastguard Worker #include "binding/AudioEndpointParcelable.h" 30*ec779b8eSAndroid Build Coastguard Worker #include "binding/AAudioServiceMessage.h" 31*ec779b8eSAndroid Build Coastguard Worker #include "binding/AAudioStreamRequest.h" 32*ec779b8eSAndroid Build Coastguard Worker #include "core/AAudioStreamParameters.h" 33*ec779b8eSAndroid Build Coastguard Worker #include "utility/AAudioUtilities.h" 34*ec779b8eSAndroid Build Coastguard Worker #include "utility/AudioClock.h" 35*ec779b8eSAndroid Build Coastguard Worker 36*ec779b8eSAndroid Build Coastguard Worker #include "AAudioCommandQueue.h" 37*ec779b8eSAndroid Build Coastguard Worker #include "AAudioThread.h" 38*ec779b8eSAndroid Build Coastguard Worker #include "SharedRingBuffer.h" 39*ec779b8eSAndroid Build Coastguard Worker #include "TimestampScheduler.h" 40*ec779b8eSAndroid Build Coastguard Worker 41*ec779b8eSAndroid Build Coastguard Worker namespace android { 42*ec779b8eSAndroid Build Coastguard Worker class AAudioService; 43*ec779b8eSAndroid Build Coastguard Worker } 44*ec779b8eSAndroid Build Coastguard Worker 45*ec779b8eSAndroid Build Coastguard Worker namespace aaudio { 46*ec779b8eSAndroid Build Coastguard Worker 47*ec779b8eSAndroid Build Coastguard Worker class AAudioServiceEndpoint; 48*ec779b8eSAndroid Build Coastguard Worker 49*ec779b8eSAndroid Build Coastguard Worker // We expect the queue to only have a few commands. 50*ec779b8eSAndroid Build Coastguard Worker // This should be way more than we need. 51*ec779b8eSAndroid Build Coastguard Worker #define QUEUE_UP_CAPACITY_COMMANDS (128) 52*ec779b8eSAndroid Build Coastguard Worker 53*ec779b8eSAndroid Build Coastguard Worker /** 54*ec779b8eSAndroid Build Coastguard Worker * Each instance of AAudioServiceStreamBase corresponds to a client stream. 55*ec779b8eSAndroid Build Coastguard Worker * It uses a subclass of AAudioServiceEndpoint to communicate with the underlying device or port. 56*ec779b8eSAndroid Build Coastguard Worker */ 57*ec779b8eSAndroid Build Coastguard Worker class AAudioServiceStreamBase 58*ec779b8eSAndroid Build Coastguard Worker : public virtual android::RefBase 59*ec779b8eSAndroid Build Coastguard Worker , public AAudioStreamParameters 60*ec779b8eSAndroid Build Coastguard Worker , public Runnable { 61*ec779b8eSAndroid Build Coastguard Worker 62*ec779b8eSAndroid Build Coastguard Worker public: 63*ec779b8eSAndroid Build Coastguard Worker explicit AAudioServiceStreamBase(android::AAudioService &aAudioService); 64*ec779b8eSAndroid Build Coastguard Worker 65*ec779b8eSAndroid Build Coastguard Worker ~AAudioServiceStreamBase() override; 66*ec779b8eSAndroid Build Coastguard Worker 67*ec779b8eSAndroid Build Coastguard Worker enum { 68*ec779b8eSAndroid Build Coastguard Worker ILLEGAL_THREAD_ID = 0 69*ec779b8eSAndroid Build Coastguard Worker }; 70*ec779b8eSAndroid Build Coastguard Worker 71*ec779b8eSAndroid Build Coastguard Worker static std::string dumpHeader(); 72*ec779b8eSAndroid Build Coastguard Worker 73*ec779b8eSAndroid Build Coastguard Worker // does not include EOL 74*ec779b8eSAndroid Build Coastguard Worker virtual std::string dump() const; 75*ec779b8eSAndroid Build Coastguard Worker 76*ec779b8eSAndroid Build Coastguard Worker /** 77*ec779b8eSAndroid Build Coastguard Worker * Open the device. 78*ec779b8eSAndroid Build Coastguard Worker */ 79*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request) 80*ec779b8eSAndroid Build Coastguard Worker EXCLUDES(mUpMessageQueueLock); 81*ec779b8eSAndroid Build Coastguard Worker 82*ec779b8eSAndroid Build Coastguard Worker // We log the CLOSE from the close() method. We needed this separate method to log the OPEN 83*ec779b8eSAndroid Build Coastguard Worker // because we had to wait until we generated the handle. 84*ec779b8eSAndroid Build Coastguard Worker void logOpen(aaudio_handle_t streamHandle); 85*ec779b8eSAndroid Build Coastguard Worker 86*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t close() EXCLUDES(mLock); 87*ec779b8eSAndroid Build Coastguard Worker 88*ec779b8eSAndroid Build Coastguard Worker /** 89*ec779b8eSAndroid Build Coastguard Worker * Start the flow of audio data. 90*ec779b8eSAndroid Build Coastguard Worker * 91*ec779b8eSAndroid Build Coastguard Worker * This is not guaranteed to be synchronous but it currently is. 92*ec779b8eSAndroid Build Coastguard Worker * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete. 93*ec779b8eSAndroid Build Coastguard Worker */ 94*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t start() EXCLUDES(mLock); 95*ec779b8eSAndroid Build Coastguard Worker 96*ec779b8eSAndroid Build Coastguard Worker /** 97*ec779b8eSAndroid Build Coastguard Worker * Stop the flow of data so that start() can resume without loss of data. 98*ec779b8eSAndroid Build Coastguard Worker * 99*ec779b8eSAndroid Build Coastguard Worker * This is not guaranteed to be synchronous but it currently is. 100*ec779b8eSAndroid Build Coastguard Worker * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete. 101*ec779b8eSAndroid Build Coastguard Worker */ 102*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t pause() EXCLUDES(mLock); 103*ec779b8eSAndroid Build Coastguard Worker 104*ec779b8eSAndroid Build Coastguard Worker /** 105*ec779b8eSAndroid Build Coastguard Worker * Stop the flow of data after the currently queued data has finished playing. 106*ec779b8eSAndroid Build Coastguard Worker * 107*ec779b8eSAndroid Build Coastguard Worker * This is not guaranteed to be synchronous but it currently is. 108*ec779b8eSAndroid Build Coastguard Worker * An AAUDIO_SERVICE_EVENT_STOPPED will be sent to the client when complete. 109*ec779b8eSAndroid Build Coastguard Worker * 110*ec779b8eSAndroid Build Coastguard Worker */ 111*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t stop() EXCLUDES(mLock); 112*ec779b8eSAndroid Build Coastguard Worker 113*ec779b8eSAndroid Build Coastguard Worker /** 114*ec779b8eSAndroid Build Coastguard Worker * Discard any data held by the underlying HAL or Service. 115*ec779b8eSAndroid Build Coastguard Worker * 116*ec779b8eSAndroid Build Coastguard Worker * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete. 117*ec779b8eSAndroid Build Coastguard Worker */ 118*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t flush() EXCLUDES(mLock); 119*ec779b8eSAndroid Build Coastguard Worker 120*ec779b8eSAndroid Build Coastguard Worker /** 121*ec779b8eSAndroid Build Coastguard Worker * Exit standby mode. The MMAP buffer will be reallocated. 122*ec779b8eSAndroid Build Coastguard Worker */ 123*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t exitStandby(AudioEndpointParcelable *parcelable) EXCLUDES(mLock); 124*ec779b8eSAndroid Build Coastguard Worker startClient(const android::AudioClient & client,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)125*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t startClient(const android::AudioClient& client, 126*ec779b8eSAndroid Build Coastguard Worker const audio_attributes_t *attr __unused, 127*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t *clientHandle __unused) { 128*ec779b8eSAndroid Build Coastguard Worker ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); 129*ec779b8eSAndroid Build Coastguard Worker return AAUDIO_ERROR_UNAVAILABLE; 130*ec779b8eSAndroid Build Coastguard Worker } 131*ec779b8eSAndroid Build Coastguard Worker stopClient(audio_port_handle_t clientHandle __unused)132*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) { 133*ec779b8eSAndroid Build Coastguard Worker ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle); 134*ec779b8eSAndroid Build Coastguard Worker return AAUDIO_ERROR_UNAVAILABLE; 135*ec779b8eSAndroid Build Coastguard Worker } 136*ec779b8eSAndroid Build Coastguard Worker 137*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t registerAudioThread(pid_t clientThreadId, int priority) EXCLUDES(mLock); 138*ec779b8eSAndroid Build Coastguard Worker 139*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t unregisterAudioThread(pid_t clientThreadId) EXCLUDES(mLock); 140*ec779b8eSAndroid Build Coastguard Worker isRunning()141*ec779b8eSAndroid Build Coastguard Worker bool isRunning() const { 142*ec779b8eSAndroid Build Coastguard Worker return mState == AAUDIO_STREAM_STATE_STARTED; 143*ec779b8eSAndroid Build Coastguard Worker } 144*ec779b8eSAndroid Build Coastguard Worker 145*ec779b8eSAndroid Build Coastguard Worker /** 146*ec779b8eSAndroid Build Coastguard Worker * Fill in a parcelable description of stream. 147*ec779b8eSAndroid Build Coastguard Worker */ 148*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t getDescription(AudioEndpointParcelable &parcelable) EXCLUDES(mLock); 149*ec779b8eSAndroid Build Coastguard Worker setRegisteredThread(pid_t pid)150*ec779b8eSAndroid Build Coastguard Worker void setRegisteredThread(pid_t pid) { 151*ec779b8eSAndroid Build Coastguard Worker mRegisteredClientThread = pid; 152*ec779b8eSAndroid Build Coastguard Worker } 153*ec779b8eSAndroid Build Coastguard Worker getRegisteredThread()154*ec779b8eSAndroid Build Coastguard Worker pid_t getRegisteredThread() const { 155*ec779b8eSAndroid Build Coastguard Worker return mRegisteredClientThread; 156*ec779b8eSAndroid Build Coastguard Worker } 157*ec779b8eSAndroid Build Coastguard Worker getFramesPerBurst()158*ec779b8eSAndroid Build Coastguard Worker int32_t getFramesPerBurst() const { 159*ec779b8eSAndroid Build Coastguard Worker return mFramesPerBurst; 160*ec779b8eSAndroid Build Coastguard Worker } 161*ec779b8eSAndroid Build Coastguard Worker 162*ec779b8eSAndroid Build Coastguard Worker void run() override; // to implement Runnable 163*ec779b8eSAndroid Build Coastguard Worker 164*ec779b8eSAndroid Build Coastguard Worker void disconnect() EXCLUDES(mLock); 165*ec779b8eSAndroid Build Coastguard Worker getAudioClient()166*ec779b8eSAndroid Build Coastguard Worker const android::AudioClient &getAudioClient() { 167*ec779b8eSAndroid Build Coastguard Worker return mMmapClient; 168*ec779b8eSAndroid Build Coastguard Worker } 169*ec779b8eSAndroid Build Coastguard Worker getOwnerUserId()170*ec779b8eSAndroid Build Coastguard Worker uid_t getOwnerUserId() const { 171*ec779b8eSAndroid Build Coastguard Worker return VALUE_OR_FATAL(android::aidl2legacy_int32_t_uid_t( 172*ec779b8eSAndroid Build Coastguard Worker mMmapClient.attributionSource.uid)); 173*ec779b8eSAndroid Build Coastguard Worker } 174*ec779b8eSAndroid Build Coastguard Worker getOwnerProcessId()175*ec779b8eSAndroid Build Coastguard Worker pid_t getOwnerProcessId() const { 176*ec779b8eSAndroid Build Coastguard Worker return VALUE_OR_FATAL(android::aidl2legacy_int32_t_pid_t( 177*ec779b8eSAndroid Build Coastguard Worker mMmapClient.attributionSource.pid)); 178*ec779b8eSAndroid Build Coastguard Worker } 179*ec779b8eSAndroid Build Coastguard Worker getHandle()180*ec779b8eSAndroid Build Coastguard Worker aaudio_handle_t getHandle() const { 181*ec779b8eSAndroid Build Coastguard Worker return mHandle; 182*ec779b8eSAndroid Build Coastguard Worker } setHandle(aaudio_handle_t handle)183*ec779b8eSAndroid Build Coastguard Worker void setHandle(aaudio_handle_t handle) { 184*ec779b8eSAndroid Build Coastguard Worker mHandle = handle; 185*ec779b8eSAndroid Build Coastguard Worker } 186*ec779b8eSAndroid Build Coastguard Worker getPortHandle()187*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t getPortHandle() const { 188*ec779b8eSAndroid Build Coastguard Worker return mClientHandle; 189*ec779b8eSAndroid Build Coastguard Worker } 190*ec779b8eSAndroid Build Coastguard Worker getState()191*ec779b8eSAndroid Build Coastguard Worker aaudio_stream_state_t getState() const { 192*ec779b8eSAndroid Build Coastguard Worker return mState; 193*ec779b8eSAndroid Build Coastguard Worker } 194*ec779b8eSAndroid Build Coastguard Worker 195*ec779b8eSAndroid Build Coastguard Worker void onVolumeChanged(float volume); 196*ec779b8eSAndroid Build Coastguard Worker 197*ec779b8eSAndroid Build Coastguard Worker /** 198*ec779b8eSAndroid Build Coastguard Worker * Set false when the stream is started. 199*ec779b8eSAndroid Build Coastguard Worker * Set true when data is first read from the stream. 200*ec779b8eSAndroid Build Coastguard Worker * @param b 201*ec779b8eSAndroid Build Coastguard Worker */ setFlowing(bool b)202*ec779b8eSAndroid Build Coastguard Worker void setFlowing(bool b) { 203*ec779b8eSAndroid Build Coastguard Worker mFlowing = b; 204*ec779b8eSAndroid Build Coastguard Worker } 205*ec779b8eSAndroid Build Coastguard Worker isFlowing()206*ec779b8eSAndroid Build Coastguard Worker bool isFlowing() const { 207*ec779b8eSAndroid Build Coastguard Worker return mFlowing; 208*ec779b8eSAndroid Build Coastguard Worker } 209*ec779b8eSAndroid Build Coastguard Worker 210*ec779b8eSAndroid Build Coastguard Worker /** 211*ec779b8eSAndroid Build Coastguard Worker * Set false when the stream should not longer be processed. 212*ec779b8eSAndroid Build Coastguard Worker * This may be caused by a message queue overflow. 213*ec779b8eSAndroid Build Coastguard Worker * Set true when stream is started. 214*ec779b8eSAndroid Build Coastguard Worker * @param suspended 215*ec779b8eSAndroid Build Coastguard Worker */ setSuspended(bool suspended)216*ec779b8eSAndroid Build Coastguard Worker void setSuspended(bool suspended) { 217*ec779b8eSAndroid Build Coastguard Worker mSuspended = suspended; 218*ec779b8eSAndroid Build Coastguard Worker } 219*ec779b8eSAndroid Build Coastguard Worker isSuspended()220*ec779b8eSAndroid Build Coastguard Worker bool isSuspended() const { 221*ec779b8eSAndroid Build Coastguard Worker return mSuspended; 222*ec779b8eSAndroid Build Coastguard Worker } 223*ec779b8eSAndroid Build Coastguard Worker getTypeText()224*ec779b8eSAndroid Build Coastguard Worker virtual const char *getTypeText() const { return "Base"; } 225*ec779b8eSAndroid Build Coastguard Worker 226*ec779b8eSAndroid Build Coastguard Worker protected: 227*ec779b8eSAndroid Build Coastguard Worker 228*ec779b8eSAndroid Build Coastguard Worker /** 229*ec779b8eSAndroid Build Coastguard Worker * Open the device. 230*ec779b8eSAndroid Build Coastguard Worker */ 231*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t open(const aaudio::AAudioStreamRequest &request, 232*ec779b8eSAndroid Build Coastguard Worker aaudio_sharing_mode_t sharingMode); 233*ec779b8eSAndroid Build Coastguard Worker 234*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t start_l() REQUIRES(mLock); 235*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t close_l() REQUIRES(mLock); 236*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t pause_l() REQUIRES(mLock); 237*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t stop_l() REQUIRES(mLock); 238*ec779b8eSAndroid Build Coastguard Worker void disconnect_l() REQUIRES(mLock); 239*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t flush_l() REQUIRES(mLock); 240*ec779b8eSAndroid Build Coastguard Worker 241*ec779b8eSAndroid Build Coastguard Worker class RegisterAudioThreadParam : public AAudioCommandParam { 242*ec779b8eSAndroid Build Coastguard Worker public: RegisterAudioThreadParam(pid_t ownerPid,pid_t clientThreadId,int priority)243*ec779b8eSAndroid Build Coastguard Worker RegisterAudioThreadParam(pid_t ownerPid, pid_t clientThreadId, int priority) 244*ec779b8eSAndroid Build Coastguard Worker : AAudioCommandParam(), mOwnerPid(ownerPid), 245*ec779b8eSAndroid Build Coastguard Worker mClientThreadId(clientThreadId), mPriority(priority) { } 246*ec779b8eSAndroid Build Coastguard Worker ~RegisterAudioThreadParam() override = default; 247*ec779b8eSAndroid Build Coastguard Worker 248*ec779b8eSAndroid Build Coastguard Worker pid_t mOwnerPid; 249*ec779b8eSAndroid Build Coastguard Worker pid_t mClientThreadId; 250*ec779b8eSAndroid Build Coastguard Worker int mPriority; 251*ec779b8eSAndroid Build Coastguard Worker }; 252*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t registerAudioThread_l( 253*ec779b8eSAndroid Build Coastguard Worker pid_t ownerPid, pid_t clientThreadId, int priority) REQUIRES(mLock); 254*ec779b8eSAndroid Build Coastguard Worker 255*ec779b8eSAndroid Build Coastguard Worker class UnregisterAudioThreadParam : public AAudioCommandParam { 256*ec779b8eSAndroid Build Coastguard Worker public: UnregisterAudioThreadParam(pid_t clientThreadId)257*ec779b8eSAndroid Build Coastguard Worker explicit UnregisterAudioThreadParam(pid_t clientThreadId) 258*ec779b8eSAndroid Build Coastguard Worker : AAudioCommandParam(), mClientThreadId(clientThreadId) { } 259*ec779b8eSAndroid Build Coastguard Worker ~UnregisterAudioThreadParam() override = default; 260*ec779b8eSAndroid Build Coastguard Worker 261*ec779b8eSAndroid Build Coastguard Worker pid_t mClientThreadId; 262*ec779b8eSAndroid Build Coastguard Worker }; 263*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t unregisterAudioThread_l(pid_t clientThreadId) REQUIRES(mLock); 264*ec779b8eSAndroid Build Coastguard Worker 265*ec779b8eSAndroid Build Coastguard Worker class GetDescriptionParam : public AAudioCommandParam { 266*ec779b8eSAndroid Build Coastguard Worker public: GetDescriptionParam(AudioEndpointParcelable * parcelable)267*ec779b8eSAndroid Build Coastguard Worker explicit GetDescriptionParam(AudioEndpointParcelable* parcelable) 268*ec779b8eSAndroid Build Coastguard Worker : AAudioCommandParam(), mParcelable(parcelable) { } 269*ec779b8eSAndroid Build Coastguard Worker ~GetDescriptionParam() override = default; 270*ec779b8eSAndroid Build Coastguard Worker 271*ec779b8eSAndroid Build Coastguard Worker AudioEndpointParcelable* mParcelable; 272*ec779b8eSAndroid Build Coastguard Worker }; 273*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t getDescription_l(AudioEndpointParcelable* parcelable) 274*ec779b8eSAndroid Build Coastguard Worker REQUIRES(mLock) EXCLUDES(mUpMessageQueueLock); 275*ec779b8eSAndroid Build Coastguard Worker 276*ec779b8eSAndroid Build Coastguard Worker void setState(aaudio_stream_state_t state); 277*ec779b8eSAndroid Build Coastguard Worker 278*ec779b8eSAndroid Build Coastguard Worker /** 279*ec779b8eSAndroid Build Coastguard Worker * Device specific startup. 280*ec779b8eSAndroid Build Coastguard Worker * @return AAUDIO_OK or negative error. 281*ec779b8eSAndroid Build Coastguard Worker */ 282*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t startDevice_l() REQUIRES(mLock); 283*ec779b8eSAndroid Build Coastguard Worker 284*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command) 285*ec779b8eSAndroid Build Coastguard Worker EXCLUDES(mUpMessageQueueLock); 286*ec779b8eSAndroid Build Coastguard Worker 287*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t sendCurrentTimestamp_l() REQUIRES(mLock); 288*ec779b8eSAndroid Build Coastguard Worker 289*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t sendXRunCount(int32_t xRunCount); 290*ec779b8eSAndroid Build Coastguard Worker 291*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t sendStartClientCommand(const android::AudioClient& client, 292*ec779b8eSAndroid Build Coastguard Worker const audio_attributes_t *attr, 293*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t *clientHandle) EXCLUDES(mLock); 294*ec779b8eSAndroid Build Coastguard Worker 295*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t sendStopClientCommand(audio_port_handle_t clientHandle) EXCLUDES(mLock); 296*ec779b8eSAndroid Build Coastguard Worker 297*ec779b8eSAndroid Build Coastguard Worker /** 298*ec779b8eSAndroid Build Coastguard Worker * @param positionFrames 299*ec779b8eSAndroid Build Coastguard Worker * @param timeNanos 300*ec779b8eSAndroid Build Coastguard Worker * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error 301*ec779b8eSAndroid Build Coastguard Worker */ 302*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t getFreeRunningPosition_l( 303*ec779b8eSAndroid Build Coastguard Worker int64_t *positionFrames, int64_t *timeNanos) = 0; 304*ec779b8eSAndroid Build Coastguard Worker 305*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t getHardwareTimestamp_l(int64_t *positionFrames, int64_t *timeNanos) = 0; 306*ec779b8eSAndroid Build Coastguard Worker 307*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t getAudioDataDescription_l(AudioEndpointParcelable* parcelable) = 0; 308*ec779b8eSAndroid Build Coastguard Worker 309*ec779b8eSAndroid Build Coastguard Worker 310*ec779b8eSAndroid Build Coastguard Worker aaudio_stream_state_t mState = AAUDIO_STREAM_STATE_UNINITIALIZED; 311*ec779b8eSAndroid Build Coastguard Worker isDisconnected_l()312*ec779b8eSAndroid Build Coastguard Worker bool isDisconnected_l() const REQUIRES(mLock) { 313*ec779b8eSAndroid Build Coastguard Worker return mDisconnected; 314*ec779b8eSAndroid Build Coastguard Worker } setDisconnected_l(bool flag)315*ec779b8eSAndroid Build Coastguard Worker void setDisconnected_l(bool flag) REQUIRES(mLock) { 316*ec779b8eSAndroid Build Coastguard Worker mDisconnected = flag; 317*ec779b8eSAndroid Build Coastguard Worker } 318*ec779b8eSAndroid Build Coastguard Worker 319*ec779b8eSAndroid Build Coastguard Worker // If you implemented this method then please also override isStandbyImplemented(). standby_l()320*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t standby_l() REQUIRES(mLock) { 321*ec779b8eSAndroid Build Coastguard Worker return AAUDIO_ERROR_UNIMPLEMENTED; 322*ec779b8eSAndroid Build Coastguard Worker } isStandbyImplemented()323*ec779b8eSAndroid Build Coastguard Worker virtual bool isStandbyImplemented() { 324*ec779b8eSAndroid Build Coastguard Worker return false; 325*ec779b8eSAndroid Build Coastguard Worker } 326*ec779b8eSAndroid Build Coastguard Worker 327*ec779b8eSAndroid Build Coastguard Worker class ExitStandbyParam : public AAudioCommandParam { 328*ec779b8eSAndroid Build Coastguard Worker public: ExitStandbyParam(AudioEndpointParcelable * parcelable)329*ec779b8eSAndroid Build Coastguard Worker explicit ExitStandbyParam(AudioEndpointParcelable* parcelable) 330*ec779b8eSAndroid Build Coastguard Worker : AAudioCommandParam(), mParcelable(parcelable) { } 331*ec779b8eSAndroid Build Coastguard Worker ~ExitStandbyParam() override = default; 332*ec779b8eSAndroid Build Coastguard Worker 333*ec779b8eSAndroid Build Coastguard Worker AudioEndpointParcelable* mParcelable; 334*ec779b8eSAndroid Build Coastguard Worker }; exitStandby_l(AudioEndpointParcelable * parcelable __unused)335*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t exitStandby_l( 336*ec779b8eSAndroid Build Coastguard Worker AudioEndpointParcelable* parcelable __unused) REQUIRES(mLock) { 337*ec779b8eSAndroid Build Coastguard Worker return AAUDIO_ERROR_UNAVAILABLE; 338*ec779b8eSAndroid Build Coastguard Worker } isStandby_l()339*ec779b8eSAndroid Build Coastguard Worker bool isStandby_l() const REQUIRES(mLock) { 340*ec779b8eSAndroid Build Coastguard Worker return mStandby; 341*ec779b8eSAndroid Build Coastguard Worker } setStandby_l(bool standby)342*ec779b8eSAndroid Build Coastguard Worker void setStandby_l(bool standby) REQUIRES(mLock) { 343*ec779b8eSAndroid Build Coastguard Worker mStandby = standby; 344*ec779b8eSAndroid Build Coastguard Worker } 345*ec779b8eSAndroid Build Coastguard Worker isIdle_l()346*ec779b8eSAndroid Build Coastguard Worker bool isIdle_l() const REQUIRES(mLock) { 347*ec779b8eSAndroid Build Coastguard Worker return mState == AAUDIO_STREAM_STATE_OPEN || mState == AAUDIO_STREAM_STATE_PAUSED 348*ec779b8eSAndroid Build Coastguard Worker || mState == AAUDIO_STREAM_STATE_STOPPED; 349*ec779b8eSAndroid Build Coastguard Worker } 350*ec779b8eSAndroid Build Coastguard Worker nextDataReportTime_l()351*ec779b8eSAndroid Build Coastguard Worker virtual int64_t nextDataReportTime_l() REQUIRES(mLock) { 352*ec779b8eSAndroid Build Coastguard Worker return std::numeric_limits<int64_t>::max(); 353*ec779b8eSAndroid Build Coastguard Worker } reportData_l()354*ec779b8eSAndroid Build Coastguard Worker virtual void reportData_l() REQUIRES(mLock) { return; } 355*ec779b8eSAndroid Build Coastguard Worker 356*ec779b8eSAndroid Build Coastguard Worker class StartClientParam : public AAudioCommandParam { 357*ec779b8eSAndroid Build Coastguard Worker public: StartClientParam(const android::AudioClient & client,const audio_attributes_t * attr,audio_port_handle_t * clientHandle)358*ec779b8eSAndroid Build Coastguard Worker StartClientParam(const android::AudioClient& client, const audio_attributes_t* attr, 359*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t* clientHandle) 360*ec779b8eSAndroid Build Coastguard Worker : AAudioCommandParam(), mClient(client), mAttr(attr), mClientHandle(clientHandle) { 361*ec779b8eSAndroid Build Coastguard Worker } 362*ec779b8eSAndroid Build Coastguard Worker ~StartClientParam() override = default; 363*ec779b8eSAndroid Build Coastguard Worker 364*ec779b8eSAndroid Build Coastguard Worker android::AudioClient mClient; 365*ec779b8eSAndroid Build Coastguard Worker const audio_attributes_t* mAttr; 366*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t* mClientHandle; 367*ec779b8eSAndroid Build Coastguard Worker }; startClient_l(const android::AudioClient & client,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)368*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t startClient_l( 369*ec779b8eSAndroid Build Coastguard Worker const android::AudioClient& client, 370*ec779b8eSAndroid Build Coastguard Worker const audio_attributes_t *attr __unused, 371*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t *clientHandle __unused) REQUIRES(mLock) { 372*ec779b8eSAndroid Build Coastguard Worker ALOGD("AAudioServiceStreamBase::startClient_l(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client); 373*ec779b8eSAndroid Build Coastguard Worker return AAUDIO_ERROR_UNAVAILABLE; 374*ec779b8eSAndroid Build Coastguard Worker } 375*ec779b8eSAndroid Build Coastguard Worker 376*ec779b8eSAndroid Build Coastguard Worker class StopClientParam : public AAudioCommandParam { 377*ec779b8eSAndroid Build Coastguard Worker public: StopClientParam(audio_port_handle_t clientHandle)378*ec779b8eSAndroid Build Coastguard Worker explicit StopClientParam(audio_port_handle_t clientHandle) 379*ec779b8eSAndroid Build Coastguard Worker : AAudioCommandParam(), mClientHandle(clientHandle) { 380*ec779b8eSAndroid Build Coastguard Worker } 381*ec779b8eSAndroid Build Coastguard Worker ~StopClientParam() override = default; 382*ec779b8eSAndroid Build Coastguard Worker 383*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t mClientHandle; 384*ec779b8eSAndroid Build Coastguard Worker }; stopClient_l(audio_port_handle_t clientHandle)385*ec779b8eSAndroid Build Coastguard Worker virtual aaudio_result_t stopClient_l(audio_port_handle_t clientHandle) REQUIRES(mLock) { 386*ec779b8eSAndroid Build Coastguard Worker ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle); 387*ec779b8eSAndroid Build Coastguard Worker return AAUDIO_ERROR_UNAVAILABLE; 388*ec779b8eSAndroid Build Coastguard Worker } 389*ec779b8eSAndroid Build Coastguard Worker 390*ec779b8eSAndroid Build Coastguard Worker pid_t mRegisteredClientThread = ILLEGAL_THREAD_ID; 391*ec779b8eSAndroid Build Coastguard Worker 392*ec779b8eSAndroid Build Coastguard Worker std::mutex mUpMessageQueueLock; 393*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<SharedRingBuffer> mUpMessageQueue PT_GUARDED_BY(mUpMessageQueueLock); 394*ec779b8eSAndroid Build Coastguard Worker 395*ec779b8eSAndroid Build Coastguard Worker enum : int32_t { 396*ec779b8eSAndroid Build Coastguard Worker START, 397*ec779b8eSAndroid Build Coastguard Worker PAUSE, 398*ec779b8eSAndroid Build Coastguard Worker STOP, 399*ec779b8eSAndroid Build Coastguard Worker FLUSH, 400*ec779b8eSAndroid Build Coastguard Worker CLOSE, 401*ec779b8eSAndroid Build Coastguard Worker DISCONNECT, 402*ec779b8eSAndroid Build Coastguard Worker REGISTER_AUDIO_THREAD, 403*ec779b8eSAndroid Build Coastguard Worker UNREGISTER_AUDIO_THREAD, 404*ec779b8eSAndroid Build Coastguard Worker GET_DESCRIPTION, 405*ec779b8eSAndroid Build Coastguard Worker EXIT_STANDBY, 406*ec779b8eSAndroid Build Coastguard Worker START_CLIENT, 407*ec779b8eSAndroid Build Coastguard Worker STOP_CLIENT, 408*ec779b8eSAndroid Build Coastguard Worker }; 409*ec779b8eSAndroid Build Coastguard Worker AAudioThread mCommandThread; 410*ec779b8eSAndroid Build Coastguard Worker std::atomic_bool mThreadEnabled{false}; 411*ec779b8eSAndroid Build Coastguard Worker AAudioCommandQueue mCommandQueue; 412*ec779b8eSAndroid Build Coastguard Worker 413*ec779b8eSAndroid Build Coastguard Worker int32_t mFramesPerBurst = 0; 414*ec779b8eSAndroid Build Coastguard Worker android::AudioClient mMmapClient; // set in open, used in MMAP start() 415*ec779b8eSAndroid Build Coastguard Worker // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger. 416*ec779b8eSAndroid Build Coastguard Worker audio_port_handle_t mClientHandle = AUDIO_PORT_HANDLE_NONE; 417*ec779b8eSAndroid Build Coastguard Worker 418*ec779b8eSAndroid Build Coastguard Worker SimpleDoubleBuffer<Timestamp> mAtomicStreamTimestamp; 419*ec779b8eSAndroid Build Coastguard Worker 420*ec779b8eSAndroid Build Coastguard Worker android::AAudioService &mAudioService; 421*ec779b8eSAndroid Build Coastguard Worker 422*ec779b8eSAndroid Build Coastguard Worker // The mServiceEndpoint variable can be accessed by multiple threads. 423*ec779b8eSAndroid Build Coastguard Worker // So we access it by locally promoting a weak pointer to a smart pointer, 424*ec779b8eSAndroid Build Coastguard Worker // which is thread-safe. 425*ec779b8eSAndroid Build Coastguard Worker android::sp<AAudioServiceEndpoint> mServiceEndpoint; 426*ec779b8eSAndroid Build Coastguard Worker android::wp<AAudioServiceEndpoint> mServiceEndpointWeak; 427*ec779b8eSAndroid Build Coastguard Worker 428*ec779b8eSAndroid Build Coastguard Worker std::string mMetricsId; // set once during open() 429*ec779b8eSAndroid Build Coastguard Worker 430*ec779b8eSAndroid Build Coastguard Worker private: 431*ec779b8eSAndroid Build Coastguard Worker 432*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t stopTimestampThread(); 433*ec779b8eSAndroid Build Coastguard Worker 434*ec779b8eSAndroid Build Coastguard Worker /** 435*ec779b8eSAndroid Build Coastguard Worker * Send a message to the client with an int64_t data value. 436*ec779b8eSAndroid Build Coastguard Worker */ 437*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 438*ec779b8eSAndroid Build Coastguard Worker int64_t dataLong = 0); 439*ec779b8eSAndroid Build Coastguard Worker /** 440*ec779b8eSAndroid Build Coastguard Worker * Send a message to the client with a double data value. 441*ec779b8eSAndroid Build Coastguard Worker */ 442*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t sendServiceEvent(aaudio_service_event_t event, 443*ec779b8eSAndroid Build Coastguard Worker double dataDouble); 444*ec779b8eSAndroid Build Coastguard Worker 445*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t sendCommand(aaudio_command_opcode opCode, 446*ec779b8eSAndroid Build Coastguard Worker std::shared_ptr<AAudioCommandParam> param = nullptr, 447*ec779b8eSAndroid Build Coastguard Worker bool waitForReply = false, 448*ec779b8eSAndroid Build Coastguard Worker int64_t timeoutNanos = 0); 449*ec779b8eSAndroid Build Coastguard Worker 450*ec779b8eSAndroid Build Coastguard Worker void stopCommandThread(); 451*ec779b8eSAndroid Build Coastguard Worker 452*ec779b8eSAndroid Build Coastguard Worker aaudio_result_t closeAndClear(); 453*ec779b8eSAndroid Build Coastguard Worker 454*ec779b8eSAndroid Build Coastguard Worker /** 455*ec779b8eSAndroid Build Coastguard Worker * @return true if the queue is getting full. 456*ec779b8eSAndroid Build Coastguard Worker */ 457*ec779b8eSAndroid Build Coastguard Worker bool isUpMessageQueueBusy() EXCLUDES(mUpMessageQueueLock); 458*ec779b8eSAndroid Build Coastguard Worker 459*ec779b8eSAndroid Build Coastguard Worker aaudio_handle_t mHandle = -1; 460*ec779b8eSAndroid Build Coastguard Worker bool mFlowing = false; 461*ec779b8eSAndroid Build Coastguard Worker 462*ec779b8eSAndroid Build Coastguard Worker // This indicate that a running stream should not be processed because of an error, 463*ec779b8eSAndroid Build Coastguard Worker // for example a full message queue. 464*ec779b8eSAndroid Build Coastguard Worker std::atomic<bool> mSuspended{false}; 465*ec779b8eSAndroid Build Coastguard Worker GUARDED_BY(mLock)466*ec779b8eSAndroid Build Coastguard Worker bool mDisconnected GUARDED_BY(mLock) {false}; 467*ec779b8eSAndroid Build Coastguard Worker 468*ec779b8eSAndroid Build Coastguard Worker bool mStandby GUARDED_BY(mLock) = false; 469*ec779b8eSAndroid Build Coastguard Worker 470*ec779b8eSAndroid Build Coastguard Worker protected: 471*ec779b8eSAndroid Build Coastguard Worker // Locking order is important. 472*ec779b8eSAndroid Build Coastguard Worker // Acquire mLock before acquiring AAudioServiceEndpoint::mLockStreams 473*ec779b8eSAndroid Build Coastguard Worker // The lock will be held by the command thread. All operations needing the lock must run from 474*ec779b8eSAndroid Build Coastguard Worker // the command thread. 475*ec779b8eSAndroid Build Coastguard Worker std::mutex mLock; // Prevent start/stop/close etcetera from colliding 476*ec779b8eSAndroid Build Coastguard Worker }; 477*ec779b8eSAndroid Build Coastguard Worker 478*ec779b8eSAndroid Build Coastguard Worker } /* namespace aaudio */ 479*ec779b8eSAndroid Build Coastguard Worker 480*ec779b8eSAndroid Build Coastguard Worker #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H 481