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 <media/AudioClient.h>
24 #include <utils/RefBase.h>
25 
26 #include "fifo/FifoBuffer.h"
27 #include "binding/IAAudioService.h"
28 #include "binding/AudioEndpointParcelable.h"
29 #include "binding/AAudioServiceMessage.h"
30 #include "utility/AAudioUtilities.h"
31 #include "utility/AudioClock.h"
32 
33 #include "SharedRingBuffer.h"
34 #include "AAudioThread.h"
35 
36 namespace android {
37     class AAudioService;
38 }
39 
40 namespace aaudio {
41 
42 class AAudioServiceEndpoint;
43 
44 // We expect the queue to only have a few commands.
45 // This should be way more than we need.
46 #define QUEUE_UP_CAPACITY_COMMANDS (128)
47 
48 /**
49  * Each instance of AAudioServiceStreamBase corresponds to a client stream.
50  * It uses a subclass of AAudioServiceEndpoint to communicate with the underlying device or port.
51  */
52 class AAudioServiceStreamBase
53     : public virtual android::RefBase
54     , public AAudioStreamParameters
55     , public Runnable  {
56 
57 public:
58     explicit AAudioServiceStreamBase(android::AAudioService &aAudioService);
59 
60     virtual ~AAudioServiceStreamBase();
61 
62     enum {
63         ILLEGAL_THREAD_ID = 0
64     };
65 
66     static std::string dumpHeader();
67 
68     // does not include EOL
69     virtual std::string dump() const;
70 
71     /**
72      * Open the device.
73      */
74     virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request) = 0;
75 
76     // We log the CLOSE from the close() method. We needed this separate method to log the OPEN
77     // because we had to wait until we generated the handle.
78     void logOpen(aaudio_handle_t streamHandle);
79 
80     aaudio_result_t close();
81 
82     /**
83      * Start the flow of audio data.
84      *
85      * This is not guaranteed to be synchronous but it currently is.
86      * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete.
87      */
88     aaudio_result_t start();
89 
90     /**
91      * Stop the flow of data so that start() can resume without loss of data.
92      *
93      * This is not guaranteed to be synchronous but it currently is.
94      * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete.
95     */
96     aaudio_result_t pause();
97 
98     /**
99      * Stop the flow of data after the currently queued data has finished playing.
100      *
101      * This is not guaranteed to be synchronous but it currently is.
102      * An AAUDIO_SERVICE_EVENT_STOPPED will be sent to the client when complete.
103      *
104      */
105     aaudio_result_t stop();
106 
107     /**
108      * Discard any data held by the underlying HAL or Service.
109      *
110      * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete.
111      */
112     aaudio_result_t flush();
113 
startClient(const android::AudioClient & client,const audio_attributes_t * attr __unused,audio_port_handle_t * clientHandle __unused)114     virtual aaudio_result_t startClient(const android::AudioClient& client,
115                                         const audio_attributes_t *attr __unused,
116                                         audio_port_handle_t *clientHandle __unused) {
117         ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client);
118         return AAUDIO_ERROR_UNAVAILABLE;
119     }
120 
stopClient(audio_port_handle_t clientHandle __unused)121     virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) {
122         ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle);
123         return AAUDIO_ERROR_UNAVAILABLE;
124     }
125 
126     aaudio_result_t registerAudioThread(pid_t clientThreadId, int priority);
127 
128     aaudio_result_t unregisterAudioThread(pid_t clientThreadId);
129 
isRunning()130     bool isRunning() const {
131         return mState == AAUDIO_STREAM_STATE_STARTED;
132     }
133 
134     /**
135      * Fill in a parcelable description of stream.
136      */
137     aaudio_result_t getDescription(AudioEndpointParcelable &parcelable);
138 
setRegisteredThread(pid_t pid)139     void setRegisteredThread(pid_t pid) {
140         mRegisteredClientThread = pid;
141     }
142 
getRegisteredThread()143     pid_t getRegisteredThread() const {
144         return mRegisteredClientThread;
145     }
146 
getFramesPerBurst()147     int32_t getFramesPerBurst() const {
148         return mFramesPerBurst;
149     }
150 
151     void run() override; // to implement Runnable
152 
153     void disconnect();
154 
getAudioClient()155     const android::AudioClient &getAudioClient() {
156         return mMmapClient;
157     }
158 
getOwnerUserId()159     uid_t getOwnerUserId() const {
160         return mMmapClient.clientUid;
161     }
162 
getOwnerProcessId()163     pid_t getOwnerProcessId() const {
164         return mMmapClient.clientPid;
165     }
166 
getHandle()167     aaudio_handle_t getHandle() const {
168         return mHandle;
169     }
setHandle(aaudio_handle_t handle)170     void setHandle(aaudio_handle_t handle) {
171         mHandle = handle;
172     }
173 
getPortHandle()174     audio_port_handle_t getPortHandle() const {
175         return mClientHandle;
176     }
177 
getState()178     aaudio_stream_state_t getState() const {
179         return mState;
180     }
181 
182     void onVolumeChanged(float volume);
183 
184     /**
185      * Set false when the stream is started.
186      * Set true when data is first read from the stream.
187      * @param b
188      */
setFlowing(bool b)189     void setFlowing(bool b) {
190         mFlowing = b;
191     }
192 
isFlowing()193     bool isFlowing() const {
194         return mFlowing;
195     }
196 
197     /**
198      * Set false when the stream should not longer be processed.
199      * This may be caused by a message queue overflow.
200      * Set true when stream is started.
201      * @param suspended
202      */
setSuspended(bool suspended)203     void setSuspended(bool suspended) {
204         mSuspended = suspended;
205     }
206 
isSuspended()207     bool isSuspended() const {
208         return mSuspended;
209     }
210 
211     /**
212      * Atomically increment the number of active references to the stream by AAudioService.
213      *
214      * This is called under a global lock in AAudioStreamTracker.
215      *
216      * @return value after the increment
217      */
218     int32_t incrementServiceReferenceCount_l();
219 
220     /**
221      * Atomically decrement the number of active references to the stream by AAudioService.
222      * This should only be called after incrementServiceReferenceCount_l().
223      *
224      * This is called under a global lock in AAudioStreamTracker.
225      *
226      * @return value after the decrement
227      */
228     int32_t decrementServiceReferenceCount_l();
229 
isCloseNeeded()230     bool isCloseNeeded() const {
231         return mCloseNeeded.load();
232     }
233 
234     /**
235      * Mark this stream as needing to be closed.
236      * Once marked for closing, it cannot be unmarked.
237      */
markCloseNeeded()238     void markCloseNeeded() {
239         mCloseNeeded.store(true);
240     }
241 
getTypeText()242     virtual const char *getTypeText() const { return "Base"; }
243 
244 protected:
245 
246     /**
247      * Open the device.
248      */
249     aaudio_result_t open(const aaudio::AAudioStreamRequest &request,
250                          aaudio_sharing_mode_t sharingMode);
251 
252     // These must be called under mLock
253     virtual aaudio_result_t close_l();
254     virtual aaudio_result_t pause_l();
255     virtual aaudio_result_t stop_l();
256     void disconnect_l();
257 
258     void setState(aaudio_stream_state_t state);
259 
260     /**
261      * Device specific startup.
262      * @return AAUDIO_OK or negative error.
263      */
264     virtual aaudio_result_t startDevice();
265 
266     aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command);
267 
268     aaudio_result_t sendCurrentTimestamp();
269 
270     aaudio_result_t sendXRunCount(int32_t xRunCount);
271 
272     /**
273      * @param positionFrames
274      * @param timeNanos
275      * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error
276      */
277     virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
278 
279     virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0;
280 
281     virtual aaudio_result_t getAudioDataDescription(AudioEndpointParcelable &parcelable) = 0;
282 
283     aaudio_stream_state_t   mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
284 
285     pid_t                   mRegisteredClientThread = ILLEGAL_THREAD_ID;
286 
287     SharedRingBuffer*       mUpMessageQueue;
288     std::mutex              mUpMessageQueueLock;
289 
290     AAudioThread            mTimestampThread;
291     // This is used by one thread to tell another thread to exit. So it must be atomic.
292     std::atomic<bool>       mThreadEnabled{false};
293 
294     int32_t                 mFramesPerBurst = 0;
295     android::AudioClient    mMmapClient; // set in open, used in MMAP start()
296     // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger.
297     audio_port_handle_t     mClientHandle = AUDIO_PORT_HANDLE_NONE;
298 
299     SimpleDoubleBuffer<Timestamp>  mAtomicStreamTimestamp;
300 
301     android::AAudioService &mAudioService;
302 
303     // The mServiceEndpoint variable can be accessed by multiple threads.
304     // So we access it by locally promoting a weak pointer to a smart pointer,
305     // which is thread-safe.
306     android::sp<AAudioServiceEndpoint> mServiceEndpoint;
307     android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
308 
309     std::string mMetricsId;  // set once during open()
310 
311 private:
312 
313     aaudio_result_t stopTimestampThread();
314 
315     /**
316      * Send a message to the client with an int64_t data value.
317      */
318     aaudio_result_t sendServiceEvent(aaudio_service_event_t event,
319                                      int64_t dataLong = 0);
320     /**
321      * Send a message to the client with a double data value.
322      */
323     aaudio_result_t sendServiceEvent(aaudio_service_event_t event,
324                                      double dataDouble);
325 
326     /**
327      * @return true if the queue is getting full.
328      */
329     bool isUpMessageQueueBusy();
330 
331     aaudio_handle_t         mHandle = -1;
332     bool                    mFlowing = false;
333 
334     // This is modified under a global lock in AAudioStreamTracker.
335     int32_t                 mCallingCount = 0;
336 
337     // This indicates that a stream that is being referenced by a binder call needs to closed.
338     std::atomic<bool>       mCloseNeeded{false};
339 
340     // This indicate that a running stream should not be processed because of an error,
341     // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded.
342     std::atomic<bool>       mSuspended{false};
343 
344     // Locking order is important.
345     // Always acquire mLock before acquiring AAudioServiceEndpoint::mLockStreams
346     std::mutex              mLock; // Prevent start/stop/close etcetera from colliding
347 };
348 
349 } /* namespace aaudio */
350 
351 #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H
352