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