aaudio: fix race condition in requestStart()

Set callback enable flag before starting AudioTrack callback.

Bug: 72115512
Test: Repeat:  adb shell write_sine_callback -pn -s4
Test: 20 times and make sure framesWritten is advancing.
Change-Id: I670fde46da0dccf8a6d03478fe2aa8b7ad596a3b
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
index c5dfb7c..3352b33 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.cpp
@@ -86,10 +86,15 @@
             // AudioRecord::Buffer
             // TODO define our own AudioBuffer and pass it from the subclasses.
             AudioTrack::Buffer *audioBuffer = static_cast<AudioTrack::Buffer *>(info);
-            if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED || !mCallbackEnabled.load()) {
+            if (getState() == AAUDIO_STREAM_STATE_DISCONNECTED) {
+                ALOGW("processCallbackCommon() data, stream disconnected");
+                audioBuffer->size = SIZE_STOP_CALLBACKS;
+            } else if (!mCallbackEnabled.load()) {
+                ALOGW("processCallbackCommon() stopping because callback disabled");
                 audioBuffer->size = SIZE_STOP_CALLBACKS;
             } else {
                 if (audioBuffer->frameCount == 0) {
+                    ALOGW("processCallbackCommon() data, frameCount is zero");
                     return;
                 }
 
@@ -106,7 +111,7 @@
                 if (callbackResult == AAUDIO_CALLBACK_RESULT_CONTINUE) {
                     audioBuffer->size = audioBuffer->frameCount * getBytesPerFrame();
                 } else { // STOP or invalid result
-                    ALOGW("%s() stop stream by faking an error", __func__);
+                    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.
                     mCallbackEnabled.store(false);
diff --git a/media/libaaudio/src/legacy/AudioStreamLegacy.h b/media/libaaudio/src/legacy/AudioStreamLegacy.h
index 6a506b3..494edbc 100644
--- a/media/libaaudio/src/legacy/AudioStreamLegacy.h
+++ b/media/libaaudio/src/legacy/AudioStreamLegacy.h
@@ -121,9 +121,6 @@
 
     void forceDisconnect(bool errorCallbackEnabled = true);
 
-    void onStart() { mCallbackEnabled.store(true); }
-    void onStop() { mCallbackEnabled.store(false); }
-
     int64_t incrementFramesWritten(int32_t frames) {
         return mFramesWritten.increment(frames);
     }
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 5f4ab9b..2bdb057 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -234,11 +234,13 @@
         return AAudioConvert_androidToAAudioResult(err);
     }
 
+    // Enable callback before starting AudioTrack to avoid shutting
+    // down because of a race condition.
+    mCallbackEnabled.store(true);
     err = mAudioRecord->start();
     if (err != OK) {
         return AAudioConvert_androidToAAudioResult(err);
     } else {
-        onStart();
         setState(AAUDIO_STREAM_STATE_STARTING);
     }
     return AAUDIO_OK;
@@ -248,11 +250,11 @@
     if (mAudioRecord.get() == nullptr) {
         return AAUDIO_ERROR_INVALID_STATE;
     }
-    onStop();
     setState(AAUDIO_STREAM_STATE_STOPPING);
     incrementFramesWritten(getFramesRead() - getFramesWritten()); // TODO review
     mTimestampPosition.set(getFramesRead());
     mAudioRecord->stop();
+    mCallbackEnabled.store(false);
     mFramesRead.reset32();
     mTimestampPosition.reset32();
     // Pass false to prevent errorCallback from being called after disconnect
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 17a8d52..db07925 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -259,11 +259,13 @@
         return AAudioConvert_androidToAAudioResult(err);
     }
 
+    // Enable callback before starting AudioTrack to avoid shutting
+    // down because of a race condition.
+    mCallbackEnabled.store(true);
     err = mAudioTrack->start();
     if (err != OK) {
         return AAudioConvert_androidToAAudioResult(err);
     } else {
-        onStart();
         setState(AAUDIO_STREAM_STATE_STARTING);
     }
     return AAUDIO_OK;
@@ -280,9 +282,9 @@
               AAudio_convertStreamStateToText(getState()));
         return AAUDIO_ERROR_INVALID_STATE;
     }
-    onStop();
     setState(AAUDIO_STREAM_STATE_PAUSING);
     mAudioTrack->pause();
+    mCallbackEnabled.store(false);
     status_t err = mAudioTrack->getPosition(&mPositionWhenPausing);
     if (err != OK) {
         return AAudioConvert_androidToAAudioResult(err);
@@ -311,13 +313,13 @@
         ALOGE("requestStop() no AudioTrack");
         return AAUDIO_ERROR_INVALID_STATE;
     }
-    onStop();
     setState(AAUDIO_STREAM_STATE_STOPPING);
     incrementFramesRead(getFramesWritten() - getFramesRead()); // TODO review
     mTimestampPosition.set(getFramesWritten());
     mFramesWritten.reset32();
     mTimestampPosition.reset32();
     mAudioTrack->stop();
+    mCallbackEnabled.store(false);
     return checkForDisconnectRequest(false);;
 }