1 /*
2  * Copyright 2015 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 #define LOG_TAG "AAudioStream"
18 //#define LOG_NDEBUG 0
19 #include <utils/Log.h>
20 
21 #include <atomic>
22 #include <stdint.h>
23 #include <aaudio/AAudio.h>
24 
25 #include "AudioStreamBuilder.h"
26 #include "AudioStream.h"
27 #include "AudioClock.h"
28 #include "AudioGlobal.h"
29 
30 namespace aaudio {
31 
32 
33 // Sequential number assigned to streams solely for debugging purposes.
AAudio_getNextStreamId()34 static aaudio_stream_id_t AAudio_getNextStreamId() {
35     static std::atomic <aaudio_stream_id_t> nextStreamId{1};
36     return nextStreamId++;
37 }
38 
AudioStream()39 AudioStream::AudioStream()
40         : mPlayerBase(new MyPlayerBase(this))
41         , mStreamId(AAudio_getNextStreamId())
42         {
43     // mThread is a pthread_t of unknown size so we need memset.
44     memset(&mThread, 0, sizeof(mThread));
45     setPeriodNanoseconds(0);
46 }
47 
~AudioStream()48 AudioStream::~AudioStream() {
49     // If the stream is deleted when OPEN or in use then audio resources will leak.
50     // This would indicate an internal error. So we want to find this ASAP.
51     LOG_ALWAYS_FATAL_IF(!(getState() == AAUDIO_STREAM_STATE_CLOSED
52                           || getState() == AAUDIO_STREAM_STATE_UNINITIALIZED
53                           || getState() == AAUDIO_STREAM_STATE_DISCONNECTED),
54                         "~AudioStream() - still in use, state = %s",
55                         AudioGlobal_convertStreamStateToText(getState()));
56 
57     mPlayerBase->clearParentReference(); // remove reference to this AudioStream
58 }
59 
open(const AudioStreamBuilder & builder)60 aaudio_result_t AudioStream::open(const AudioStreamBuilder& builder)
61 {
62     // Call here as well because the AAudioService will call this without calling build().
63     aaudio_result_t result = builder.validate();
64     if (result != AAUDIO_OK) {
65         return result;
66     }
67 
68     // Copy parameters from the Builder because the Builder may be deleted after this call.
69     // TODO AudioStream should be a subclass of AudioStreamParameters
70     mSamplesPerFrame = builder.getSamplesPerFrame();
71     mSampleRate = builder.getSampleRate();
72     mDeviceId = builder.getDeviceId();
73     mFormat = builder.getFormat();
74     mSharingMode = builder.getSharingMode();
75     mSharingModeMatchRequired = builder.isSharingModeMatchRequired();
76     mPerformanceMode = builder.getPerformanceMode();
77 
78     mUsage = builder.getUsage();
79     if (mUsage == AAUDIO_UNSPECIFIED) {
80         mUsage = AAUDIO_USAGE_MEDIA;
81     }
82     mContentType = builder.getContentType();
83     if (mContentType == AAUDIO_UNSPECIFIED) {
84         mContentType = AAUDIO_CONTENT_TYPE_MUSIC;
85     }
86     mInputPreset = builder.getInputPreset();
87     if (mInputPreset == AAUDIO_UNSPECIFIED) {
88         mInputPreset = AAUDIO_INPUT_PRESET_VOICE_RECOGNITION;
89     }
90     mAllowedCapturePolicy = builder.getAllowedCapturePolicy();
91     if (mAllowedCapturePolicy == AAUDIO_UNSPECIFIED) {
92         mAllowedCapturePolicy = AAUDIO_ALLOW_CAPTURE_BY_ALL;
93     }
94 
95     // callbacks
96     mFramesPerDataCallback = builder.getFramesPerDataCallback();
97     mDataCallbackProc = builder.getDataCallbackProc();
98     mErrorCallbackProc = builder.getErrorCallbackProc();
99     mDataCallbackUserData = builder.getDataCallbackUserData();
100     mErrorCallbackUserData = builder.getErrorCallbackUserData();
101 
102     return AAUDIO_OK;
103 }
104 
systemStart()105 aaudio_result_t AudioStream::systemStart() {
106     std::lock_guard<std::mutex> lock(mStreamLock);
107 
108     if (collidesWithCallback()) {
109         ALOGE("%s cannot be called from a callback!", __func__);
110         return AAUDIO_ERROR_INVALID_STATE;
111     }
112 
113     aaudio_result_t result = requestStart();
114     if (result == AAUDIO_OK) {
115         // We only call this for logging in "dumpsys audio". So ignore return code.
116         (void) mPlayerBase->start();
117     }
118     return result;
119 }
120 
systemPause()121 aaudio_result_t AudioStream::systemPause() {
122     std::lock_guard<std::mutex> lock(mStreamLock);
123 
124     if (!isPauseSupported()) {
125         return AAUDIO_ERROR_UNIMPLEMENTED;
126     }
127 
128     if (collidesWithCallback()) {
129         ALOGE("%s cannot be called from a callback!", __func__);
130         return AAUDIO_ERROR_INVALID_STATE;
131     }
132 
133     switch (getState()) {
134         // Proceed with pausing.
135         case AAUDIO_STREAM_STATE_STARTING:
136         case AAUDIO_STREAM_STATE_STARTED:
137         case AAUDIO_STREAM_STATE_DISCONNECTED:
138             break;
139 
140             // Transition from one inactive state to another.
141         case AAUDIO_STREAM_STATE_OPEN:
142         case AAUDIO_STREAM_STATE_STOPPED:
143         case AAUDIO_STREAM_STATE_FLUSHED:
144             setState(AAUDIO_STREAM_STATE_PAUSED);
145             return AAUDIO_OK;
146 
147             // Redundant?
148         case AAUDIO_STREAM_STATE_PAUSING:
149         case AAUDIO_STREAM_STATE_PAUSED:
150             return AAUDIO_OK;
151 
152             // Don't interfere with transitional states or when closed.
153         case AAUDIO_STREAM_STATE_STOPPING:
154         case AAUDIO_STREAM_STATE_FLUSHING:
155         case AAUDIO_STREAM_STATE_CLOSING:
156         case AAUDIO_STREAM_STATE_CLOSED:
157         default:
158             ALOGW("safePause() stream not running, state = %s",
159                   AudioGlobal_convertStreamStateToText(getState()));
160             return AAUDIO_ERROR_INVALID_STATE;
161     }
162 
163     aaudio_result_t result = requestPause();
164     if (result == AAUDIO_OK) {
165         // We only call this for logging in "dumpsys audio". So ignore return code.
166         (void) mPlayerBase->pause();
167     }
168     return result;
169 }
170 
safeFlush()171 aaudio_result_t AudioStream::safeFlush() {
172     if (!isFlushSupported()) {
173         ALOGE("flush not supported for this stream");
174         return AAUDIO_ERROR_UNIMPLEMENTED;
175     }
176 
177     std::lock_guard<std::mutex> lock(mStreamLock);
178     if (collidesWithCallback()) {
179         ALOGE("stream cannot be flushed from a callback!");
180         return AAUDIO_ERROR_INVALID_STATE;
181     }
182 
183     aaudio_result_t result = AAudio_isFlushAllowed(getState());
184     if (result != AAUDIO_OK) {
185         return result;
186     }
187 
188     return requestFlush();
189 }
190 
systemStopFromCallback()191 aaudio_result_t AudioStream::systemStopFromCallback() {
192     std::lock_guard<std::mutex> lock(mStreamLock);
193     aaudio_result_t result = safeStop();
194     if (result == AAUDIO_OK) {
195         // We only call this for logging in "dumpsys audio". So ignore return code.
196         (void) mPlayerBase->stop();
197     }
198     return result;
199 }
200 
systemStopFromApp()201 aaudio_result_t AudioStream::systemStopFromApp() {
202     std::lock_guard<std::mutex> lock(mStreamLock);
203     if (collidesWithCallback()) {
204         ALOGE("stream cannot be stopped by calling from a callback!");
205         return AAUDIO_ERROR_INVALID_STATE;
206     }
207     aaudio_result_t result = safeStop();
208     if (result == AAUDIO_OK) {
209         // We only call this for logging in "dumpsys audio". So ignore return code.
210         (void) mPlayerBase->stop();
211     }
212     return result;
213 }
214 
215 // This must be called under mStreamLock.
safeStop()216 aaudio_result_t AudioStream::safeStop() {
217 
218     switch (getState()) {
219         // Proceed with stopping.
220         case AAUDIO_STREAM_STATE_STARTING:
221         case AAUDIO_STREAM_STATE_STARTED:
222         case AAUDIO_STREAM_STATE_DISCONNECTED:
223             break;
224 
225         // Transition from one inactive state to another.
226         case AAUDIO_STREAM_STATE_OPEN:
227         case AAUDIO_STREAM_STATE_PAUSED:
228         case AAUDIO_STREAM_STATE_FLUSHED:
229             setState(AAUDIO_STREAM_STATE_STOPPED);
230             return AAUDIO_OK;
231 
232         // Redundant?
233         case AAUDIO_STREAM_STATE_STOPPING:
234         case AAUDIO_STREAM_STATE_STOPPED:
235             return AAUDIO_OK;
236 
237         // Don't interfere with transitional states or when closed.
238         case AAUDIO_STREAM_STATE_PAUSING:
239         case AAUDIO_STREAM_STATE_FLUSHING:
240         case AAUDIO_STREAM_STATE_CLOSING:
241         case AAUDIO_STREAM_STATE_CLOSED:
242         default:
243             ALOGW("%s() stream not running, state = %s", __func__,
244                   AudioGlobal_convertStreamStateToText(getState()));
245             return AAUDIO_ERROR_INVALID_STATE;
246     }
247 
248     return requestStop();
249 }
250 
safeClose()251 aaudio_result_t AudioStream::safeClose() {
252     // This get temporarily unlocked in the close when joining callback threads.
253     std::lock_guard<std::mutex> lock(mStreamLock);
254     if (collidesWithCallback()) {
255         ALOGE("%s cannot be called from a callback!", __func__);
256         return AAUDIO_ERROR_INVALID_STATE;
257     }
258     return close();
259 }
260 
setState(aaudio_stream_state_t state)261 void AudioStream::setState(aaudio_stream_state_t state) {
262     ALOGV("%s(%d) from %d to %d", __func__, getId(), mState, state);
263     // CLOSED is a final state
264     if (mState == AAUDIO_STREAM_STATE_CLOSED) {
265         ALOGE("%s(%d) tried to set to %d but already CLOSED", __func__, getId(), state);
266 
267     // Once DISCONNECTED, we can only move to CLOSED state.
268     } else if (mState == AAUDIO_STREAM_STATE_DISCONNECTED
269                && state != AAUDIO_STREAM_STATE_CLOSED) {
270         ALOGE("%s(%d) tried to set to %d but already DISCONNECTED", __func__, getId(), state);
271 
272     } else {
273         mState = state;
274     }
275 }
276 
waitForStateChange(aaudio_stream_state_t currentState,aaudio_stream_state_t * nextState,int64_t timeoutNanoseconds)277 aaudio_result_t AudioStream::waitForStateChange(aaudio_stream_state_t currentState,
278                                                 aaudio_stream_state_t *nextState,
279                                                 int64_t timeoutNanoseconds)
280 {
281     aaudio_result_t result = updateStateMachine();
282     if (result != AAUDIO_OK) {
283         return result;
284     }
285 
286     int64_t durationNanos = 20 * AAUDIO_NANOS_PER_MILLISECOND; // arbitrary
287     aaudio_stream_state_t state = getState();
288     while (state == currentState && timeoutNanoseconds > 0) {
289         if (durationNanos > timeoutNanoseconds) {
290             durationNanos = timeoutNanoseconds;
291         }
292         AudioClock::sleepForNanos(durationNanos);
293         timeoutNanoseconds -= durationNanos;
294 
295         aaudio_result_t result = updateStateMachine();
296         if (result != AAUDIO_OK) {
297             return result;
298         }
299 
300         state = getState();
301     }
302     if (nextState != nullptr) {
303         *nextState = state;
304     }
305     return (state == currentState) ? AAUDIO_ERROR_TIMEOUT : AAUDIO_OK;
306 }
307 
308 // This registers the callback thread with the server before
309 // passing control to the app. This gives the server an opportunity to boost
310 // the thread's performance characteristics.
wrapUserThread()311 void* AudioStream::wrapUserThread() {
312     void* procResult = nullptr;
313     mThreadRegistrationResult = registerThread();
314     if (mThreadRegistrationResult == AAUDIO_OK) {
315         // Run callback loop. This may take a very long time.
316         procResult = mThreadProc(mThreadArg);
317         mThreadRegistrationResult = unregisterThread();
318     }
319     return procResult;
320 }
321 
322 // This is the entry point for the new thread created by createThread().
323 // It converts the 'C' function call to a C++ method call.
AudioStream_internalThreadProc(void * threadArg)324 static void* AudioStream_internalThreadProc(void* threadArg) {
325     AudioStream *audioStream = (AudioStream *) threadArg;
326     return audioStream->wrapUserThread();
327 }
328 
329 // This is not exposed in the API.
330 // But it is still used internally to implement callbacks for MMAP mode.
createThread(int64_t periodNanoseconds,aaudio_audio_thread_proc_t threadProc,void * threadArg)331 aaudio_result_t AudioStream::createThread(int64_t periodNanoseconds,
332                                      aaudio_audio_thread_proc_t threadProc,
333                                      void* threadArg)
334 {
335     if (mHasThread) {
336         ALOGE("createThread() - mHasThread already true");
337         return AAUDIO_ERROR_INVALID_STATE;
338     }
339     if (threadProc == nullptr) {
340         return AAUDIO_ERROR_NULL;
341     }
342     // Pass input parameters to the background thread.
343     mThreadProc = threadProc;
344     mThreadArg = threadArg;
345     setPeriodNanoseconds(periodNanoseconds);
346     int err = pthread_create(&mThread, nullptr, AudioStream_internalThreadProc, this);
347     if (err != 0) {
348         android::status_t status = -errno;
349         ALOGE("createThread() - pthread_create() failed, %d", status);
350         return AAudioConvert_androidToAAudioResult(status);
351     } else {
352         // TODO Use AAudioThread or maybe AndroidThread
353         // Name the thread with an increasing index, "AAudio_#", for debugging.
354         static std::atomic<uint32_t> nextThreadIndex{1};
355         char name[16]; // max length for a pthread_name
356         uint32_t index = nextThreadIndex++;
357         // Wrap the index so that we do not hit the 16 char limit
358         // and to avoid hard-to-read large numbers.
359         index = index % 100000;  // arbitrary
360         snprintf(name, sizeof(name), "AAudio_%u", index);
361         err = pthread_setname_np(mThread, name);
362         ALOGW_IF((err != 0), "Could not set name of AAudio thread. err = %d", err);
363 
364         mHasThread = true;
365         return AAUDIO_OK;
366     }
367 }
368 
369 // This must be called under mStreamLock.
joinThread(void ** returnArg,int64_t timeoutNanoseconds __unused)370 aaudio_result_t AudioStream::joinThread(void** returnArg, int64_t timeoutNanoseconds __unused)
371 {
372     if (!mHasThread) {
373         ALOGE("joinThread() - but has no thread");
374         return AAUDIO_ERROR_INVALID_STATE;
375     }
376     aaudio_result_t result = AAUDIO_OK;
377     // If the callback is stopping the stream because the app passed back STOP
378     // then we don't need to join(). The thread is already about to exit.
379     if (pthread_self() != mThread) {
380         // Called from an app thread. Not the callback.
381         // Unlock because the callback may be trying to stop the stream but is blocked.
382         mStreamLock.unlock();
383 #if 0
384         // TODO implement equivalent of pthread_timedjoin_np()
385         struct timespec abstime;
386         int err = pthread_timedjoin_np(mThread, returnArg, &abstime);
387 #else
388         int err = pthread_join(mThread, returnArg);
389 #endif
390         mStreamLock.lock();
391         if (err) {
392             ALOGE("%s() pthread_join() returns err = %d", __func__, err);
393             result = AAudioConvert_androidToAAudioResult(-err);
394         }
395     }
396     // This must be set false so that the callback thread can be created
397     // when the stream is restarted.
398     mHasThread = false;
399     return (result != AAUDIO_OK) ? result : mThreadRegistrationResult;
400 }
401 
maybeCallDataCallback(void * audioData,int32_t numFrames)402 aaudio_data_callback_result_t AudioStream::maybeCallDataCallback(void *audioData,
403                                                                  int32_t numFrames) {
404     aaudio_data_callback_result_t result = AAUDIO_CALLBACK_RESULT_STOP;
405     AAudioStream_dataCallback dataCallback = getDataCallbackProc();
406     if (dataCallback != nullptr) {
407         // Store thread ID of caller to detect stop() and close() calls from callback.
408         pid_t expected = CALLBACK_THREAD_NONE;
409         if (mDataCallbackThread.compare_exchange_strong(expected, gettid())) {
410             result = (*dataCallback)(
411                     (AAudioStream *) this,
412                     getDataCallbackUserData(),
413                     audioData,
414                     numFrames);
415             mDataCallbackThread.store(CALLBACK_THREAD_NONE);
416         } else {
417             ALOGW("%s() data callback already running!", __func__);
418         }
419     }
420     return result;
421 }
422 
maybeCallErrorCallback(aaudio_result_t result)423 void AudioStream::maybeCallErrorCallback(aaudio_result_t result) {
424     AAudioStream_errorCallback errorCallback = getErrorCallbackProc();
425     if (errorCallback != nullptr) {
426         // Store thread ID of caller to detect stop() and close() calls from callback.
427         pid_t expected = CALLBACK_THREAD_NONE;
428         if (mErrorCallbackThread.compare_exchange_strong(expected, gettid())) {
429             (*errorCallback)(
430                     (AAudioStream *) this,
431                     getErrorCallbackUserData(),
432                     result);
433             mErrorCallbackThread.store(CALLBACK_THREAD_NONE);
434         } else {
435             ALOGW("%s() error callback already running!", __func__);
436         }
437     }
438 }
439 
440 // Is this running on the same thread as a callback?
441 // Note: This cannot be implemented using a thread_local because that would
442 // require using a thread_local variable that is shared between streams.
443 // So a thread_local variable would prevent stopping or closing stream A from
444 // a callback on stream B, which is currently legal and not so terrible.
collidesWithCallback() const445 bool AudioStream::collidesWithCallback() const {
446     pid_t thisThread = gettid();
447     // Compare the current thread ID with the thread ID of the callback
448     // threads to see it they match. If so then this code is being
449     // called from one of the stream callback functions.
450     return ((mErrorCallbackThread.load() == thisThread)
451             || (mDataCallbackThread.load() == thisThread));
452 }
453 
454 #if AAUDIO_USE_VOLUME_SHAPER
applyVolumeShaper(const android::media::VolumeShaper::Configuration & configuration __unused,const android::media::VolumeShaper::Operation & operation __unused)455 android::media::VolumeShaper::Status AudioStream::applyVolumeShaper(
456         const android::media::VolumeShaper::Configuration& configuration __unused,
457         const android::media::VolumeShaper::Operation& operation __unused) {
458     ALOGW("applyVolumeShaper() is not supported");
459     return android::media::VolumeShaper::Status::ok();
460 }
461 #endif
462 
setDuckAndMuteVolume(float duckAndMuteVolume)463 void AudioStream::setDuckAndMuteVolume(float duckAndMuteVolume) {
464     ALOGD("%s() to %f", __func__, duckAndMuteVolume);
465     mDuckAndMuteVolume = duckAndMuteVolume;
466     doSetVolume(); // apply this change
467 }
468 
MyPlayerBase(AudioStream * parent)469 AudioStream::MyPlayerBase::MyPlayerBase(AudioStream *parent) : mParent(parent) {
470 }
471 
~MyPlayerBase()472 AudioStream::MyPlayerBase::~MyPlayerBase() {
473 }
474 
registerWithAudioManager()475 void AudioStream::MyPlayerBase::registerWithAudioManager() {
476     if (!mRegistered) {
477         init(android::PLAYER_TYPE_AAUDIO, AAudioConvert_usageToInternal(mParent->getUsage()));
478         mRegistered = true;
479     }
480 }
481 
unregisterWithAudioManager()482 void AudioStream::MyPlayerBase::unregisterWithAudioManager() {
483     if (mRegistered) {
484         baseDestroy();
485         mRegistered = false;
486     }
487 }
488 
destroy()489 void AudioStream::MyPlayerBase::destroy() {
490     unregisterWithAudioManager();
491 }
492 
493 }  // namespace aaudio
494