Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da60340a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "aaudio: fix race condition in requestStart()"

parents 205266aa 9e9a95b3
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -86,10 +86,15 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode
            // 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 @@ void AudioStreamLegacy::processCallbackCommon(aaudio_callback_operation_t opcode
                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);
+0 −3
Original line number Diff line number Diff line
@@ -121,9 +121,6 @@ protected:

    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);
    }
+4 −2
Original line number Diff line number Diff line
@@ -244,11 +244,13 @@ aaudio_result_t AudioStreamRecord::requestStart()
        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;
@@ -258,11 +260,11 @@ aaudio_result_t AudioStreamRecord::requestStop() {
    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
+5 −3
Original line number Diff line number Diff line
@@ -271,11 +271,13 @@ aaudio_result_t AudioStreamTrack::requestStart() {
        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;
@@ -292,9 +294,9 @@ aaudio_result_t AudioStreamTrack::requestPause() {
              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);
@@ -323,13 +325,13 @@ aaudio_result_t AudioStreamTrack::requestStop() {
        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);;
}