xref: /aosp_15_r20/frameworks/av/services/oboeservice/AAudioServiceStreamBase.h (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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