aaudio: call stop() from the callback
Stop the stream when the callback returns AAUDIO_CALLBACK_RESULT_STOP.
Refactor start/pause/stop code to allow different paths for
stop from the app or from the callback.
Fix error handling in joinThread().
Simplify code path through PlayerBase.
Bug: 120932593
Bug: 121158739
Test: test_return_stop
Test: test_return_stop -i
Test: test_return_stop -n
Test: test_return_stop -i -n
Test: atest CtsNativeMediaAAudioTestCases
Change-Id: I85134211348b26077693d9a71bf1331dad60da38
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index a6b9f5d..2edab58 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -78,8 +78,9 @@
void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode, void *info) {
aaudio_data_callback_result_t callbackResult;
- // This illegal size can be used to tell AudioFlinger to stop calling us.
- // This takes advantage of AudioFlinger killing the stream.
+ // This illegal size can be used to tell AudioRecord or AudioTrack to stop calling us.
+ // This takes advantage of them killing the stream when they see a size out of range.
+ // That is an undocumented behavior.
// TODO add to API in AudioRecord and AudioTrack
const size_t SIZE_STOP_CALLBACKS = SIZE_MAX;
@@ -95,7 +96,7 @@
ALOGW("processCallbackCommon() data, stream disconnected");
audioBuffer->size = SIZE_STOP_CALLBACKS;
} else if (!mCallbackEnabled.load()) {
- ALOGW("processCallbackCommon() stopping because callback disabled");
+ ALOGW("processCallbackCommon() no data because callback disabled");
audioBuffer->size = SIZE_STOP_CALLBACKS;
} else {
if (audioBuffer->frameCount == 0) {
@@ -115,10 +116,16 @@
}
if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
audioBuffer->size = audioBuffer->frameCount * getBytesPerDeviceFrame();
- } else { // STOP or invalid result
- ALOGW("%s() callback requested stop, fake an error", __func__);
- audioBuffer->size = SIZE_STOP_CALLBACKS;
- // Disable the callback just in case AudioFlinger keeps trying to call us.
+ } else {
+ if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
+ ALOGD("%s() callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+ } else {
+ ALOGW("%s() callback returned invalid result = %d",
+ __func__, callbackResult);
+ }
+ audioBuffer->size = 0;
+ systemStopFromCallback();
+ // Disable the callback just in case the system keeps trying to call us.
mCallbackEnabled.store(false);
}