• 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 <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     /**
73      * Open the device.
74      */
75     virtual aaudio_result_t open(const aaudio::AAudioStreamRequest &request) = 0;
76 
77     virtual aaudio_result_t close();
78 
79     /**
80      * Start the flow of audio data.
81      *
82      * This is not guaranteed to be synchronous but it currently is.
83      * An AAUDIO_SERVICE_EVENT_STARTED will be sent to the client when complete.
84      */
85     virtual aaudio_result_t start();
86 
87     /**
88      * Stop the flow of data so that start() can resume without loss of data.
89      *
90      * This is not guaranteed to be synchronous but it currently is.
91      * An AAUDIO_SERVICE_EVENT_PAUSED will be sent to the client when complete.
92     */
93     virtual aaudio_result_t pause();
94 
95     /**
96      * Stop the flow of data after the currently queued data has finished playing.
97      *
98      * This is not guaranteed to be synchronous but it currently is.
99      * An AAUDIO_SERVICE_EVENT_STOPPED will be sent to the client when complete.
100      *
101      */
102     virtual aaudio_result_t stop();
103 
104     aaudio_result_t stopTimestampThread();
105 
106     /**
107      * Discard any data held by the underlying HAL or Service.
108      *
109      * An AAUDIO_SERVICE_EVENT_FLUSHED will be sent to the client when complete.
110      */
111     virtual aaudio_result_t flush();
112 
113 
startClient(const android::AudioClient & client __unused,audio_port_handle_t * clientHandle __unused)114     virtual aaudio_result_t startClient(const android::AudioClient& client __unused,
115                                         audio_port_handle_t *clientHandle __unused) {
116         ALOGD("AAudioServiceStreamBase::startClient(%p, ...) AAUDIO_ERROR_UNAVAILABLE", &client);
117         return AAUDIO_ERROR_UNAVAILABLE;
118     }
119 
stopClient(audio_port_handle_t clientHandle __unused)120     virtual aaudio_result_t stopClient(audio_port_handle_t clientHandle __unused) {
121         ALOGD("AAudioServiceStreamBase::stopClient(%d) AAUDIO_ERROR_UNAVAILABLE", clientHandle);
122         return AAUDIO_ERROR_UNAVAILABLE;
123     }
124 
isRunning()125     bool isRunning() const {
126         return mState == AAUDIO_STREAM_STATE_STARTED;
127     }
128 
129     // -------------------------------------------------------------------
130 
131     /**
132      * Send a message to the client with an int64_t data value.
133      */
134     aaudio_result_t sendServiceEvent(aaudio_service_event_t event,
135                                      int64_t dataLong = 0);
136     /**
137      * Send a message to the client with an double data value.
138      */
139     aaudio_result_t sendServiceEvent(aaudio_service_event_t event,
140                                      double  dataDouble);
141 
142     /**
143      * Fill in a parcelable description of stream.
144      */
145     aaudio_result_t getDescription(AudioEndpointParcelable &parcelable);
146 
147 
setRegisteredThread(pid_t pid)148     void setRegisteredThread(pid_t pid) {
149         mRegisteredClientThread = pid;
150     }
151 
getRegisteredThread()152     pid_t getRegisteredThread() const {
153         return mRegisteredClientThread;
154     }
155 
getFramesPerBurst()156     int32_t getFramesPerBurst() const {
157         return mFramesPerBurst;
158     }
159 
160     void run() override; // to implement Runnable
161 
162     void disconnect();
163 
getAudioClient()164     const android::AudioClient &getAudioClient() {
165         return mMmapClient;
166     }
167 
getOwnerUserId()168     uid_t getOwnerUserId() const {
169         return mMmapClient.clientUid;
170     }
171 
getOwnerProcessId()172     pid_t getOwnerProcessId() const {
173         return mMmapClient.clientPid;
174     }
175 
getHandle()176     aaudio_handle_t getHandle() const {
177         return mHandle;
178     }
setHandle(aaudio_handle_t handle)179     void setHandle(aaudio_handle_t handle) {
180         mHandle = handle;
181     }
182 
getPortHandle()183     audio_port_handle_t getPortHandle() const {
184         return mClientHandle;
185     }
186 
getState()187     aaudio_stream_state_t getState() const {
188         return mState;
189     }
190 
191     void onVolumeChanged(float volume);
192 
193     /**
194      * Set false when the stream is started.
195      * Set true when data is first read from the stream.
196      * @param b
197      */
setFlowing(bool b)198     void setFlowing(bool b) {
199         mFlowing = b;
200     }
201 
isFlowing()202     bool isFlowing() const {
203         return mFlowing;
204     }
205 
206     /**
207      * Set false when the stream should not longer be processed.
208      * This may be caused by a message queue overflow.
209      * Set true when stream is started.
210      * @param suspended
211      */
setSuspended(bool suspended)212     void setSuspended(bool suspended) {
213         mSuspended = suspended;
214     }
215 
isSuspended()216     bool isSuspended() const {
217         return mSuspended;
218     }
219 
220     /**
221      * Atomically increment the number of active references to the stream by AAudioService.
222      *
223      * This is called under a global lock in AAudioStreamTracker.
224      *
225      * @return value after the increment
226      */
227     int32_t incrementServiceReferenceCount_l();
228 
229     /**
230      * Atomically decrement the number of active references to the stream by AAudioService.
231      * This should only be called after incrementServiceReferenceCount_l().
232      *
233      * This is called under a global lock in AAudioStreamTracker.
234      *
235      * @return value after the decrement
236      */
237     int32_t decrementServiceReferenceCount_l();
238 
isCloseNeeded()239     bool isCloseNeeded() const {
240         return mCloseNeeded.load();
241     }
242 
243     /**
244      * Mark this stream as needing to be closed.
245      * Once marked for closing, it cannot be unmarked.
246      */
markCloseNeeded()247     void markCloseNeeded() {
248         mCloseNeeded.store(true);
249     }
250 
getTypeText()251     virtual const char *getTypeText() const { return "Base"; }
252 
253 protected:
254 
255     /**
256      * Open the device.
257      */
258     aaudio_result_t open(const aaudio::AAudioStreamRequest &request,
259                          aaudio_sharing_mode_t sharingMode);
260 
setState(aaudio_stream_state_t state)261     void setState(aaudio_stream_state_t state) {
262         mState = state;
263     }
264 
265     /**
266      * Device specific startup.
267      * @return AAUDIO_OK or negative error.
268      */
269     virtual aaudio_result_t startDevice();
270 
271     aaudio_result_t writeUpMessageQueue(AAudioServiceMessage *command);
272 
273     aaudio_result_t sendCurrentTimestamp();
274 
275     aaudio_result_t sendXRunCount(int32_t xRunCount);
276 
277     /**
278      * @param positionFrames
279      * @param timeNanos
280      * @return AAUDIO_OK or AAUDIO_ERROR_UNAVAILABLE or other negative error
281      */
282     virtual aaudio_result_t getFreeRunningPosition(int64_t *positionFrames, int64_t *timeNanos) = 0;
283 
284     virtual aaudio_result_t getHardwareTimestamp(int64_t *positionFrames, int64_t *timeNanos) = 0;
285 
286     virtual aaudio_result_t getAudioDataDescription(AudioEndpointParcelable &parcelable) = 0;
287 
288     aaudio_stream_state_t   mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
289 
290     pid_t                   mRegisteredClientThread = ILLEGAL_THREAD_ID;
291 
292     SharedRingBuffer*       mUpMessageQueue;
293     std::mutex              mUpMessageQueueLock;
294 
295     AAudioThread            mTimestampThread;
296     // This is used by one thread to tell another thread to exit. So it must be atomic.
297     std::atomic<bool>       mThreadEnabled{false};
298 
299     int32_t                 mFramesPerBurst = 0;
300     android::AudioClient    mMmapClient; // set in open, used in MMAP start()
301     // TODO rename mClientHandle to mPortHandle to be more consistent with AudioFlinger.
302     audio_port_handle_t     mClientHandle = AUDIO_PORT_HANDLE_NONE;
303 
304     SimpleDoubleBuffer<Timestamp>  mAtomicStreamTimestamp;
305 
306     android::AAudioService &mAudioService;
307 
308     // The mServiceEndpoint variable can be accessed by multiple threads.
309     // So we access it by locally promoting a weak pointer to a smart pointer,
310     // which is thread-safe.
311     android::sp<AAudioServiceEndpoint> mServiceEndpoint;
312     android::wp<AAudioServiceEndpoint> mServiceEndpointWeak;
313 
314 private:
315 
316     /**
317      * @return true if the queue is getting full.
318      */
319     bool isUpMessageQueueBusy();
320 
321     aaudio_handle_t         mHandle = -1;
322     bool                    mFlowing = false;
323 
324     // This is modified under a global lock in AAudioStreamTracker.
325     int32_t                 mCallingCount = 0;
326 
327     // This indicates that a stream that is being referenced by a binder call needs to closed.
328     std::atomic<bool>       mCloseNeeded{false};
329 
330     // This indicate that a running stream should not be processed because of an error,
331     // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded.
332     std::atomic<bool>       mSuspended{false};
333 };
334 
335 } /* namespace aaudio */
336 
337 #endif //AAUDIO_AAUDIO_SERVICE_STREAM_BASE_H
338