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

Commit 112278a6 authored by Xin Li's avatar Xin Li Committed by Gerrit Code Review
Browse files

Merge "Merge Android 12 QPR 3"

parents 55d91e6a aea43810
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ namespace android {

// for audio_track_cblk_t::mState, to match TrackBase.h
static inline constexpr int CBLK_STATE_IDLE = 0;
static inline constexpr int CBLK_STATE_ACTIVE = 6;
static inline constexpr int CBLK_STATE_PAUSING = 7;

/**
+3 −0
Original line number Diff line number Diff line
@@ -928,6 +928,9 @@ void CCodecConfig::initializeStandardParams() {
    add(ConfigMapper(KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
        .limitTo(D::AUDIO & (D::CONFIG | D::PARAM | D::READ)));

    add(ConfigMapper(KEY_MAX_OUTPUT_CHANNEL_COUNT, C2_PARAMKEY_MAX_CHANNEL_COUNT, "value")
        .limitTo(D::AUDIO & (D::CONFIG | D::PARAM | D::READ)));

    add(ConfigMapper(KEY_AAC_SBR_MODE, C2_PARAMKEY_AAC_SBR_MODE, "value")
        .limitTo(D::AUDIO & D::ENCODER & (D::CONFIG | D::PARAM | D::READ))
        .withMapper([](C2Value v) -> C2Value {
+2 −1
Original line number Diff line number Diff line
@@ -352,7 +352,8 @@ AAUDIO_API aaudio_result_t AAudioStream_waitForStateChange(AAudioStream* stream,
{

    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
    return audioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds);
    android::sp<AudioStream> spAudioStream(audioStream);
    return spAudioStream->waitForStateChange(inputState, nextState, timeoutNanoseconds);
}

// ============================================================
+54 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@

#include <gtest/gtest.h>
#include <unistd.h>
#include <thread>

// Callback function that does nothing.
aaudio_data_callback_result_t NoopDataCallbackProc(
@@ -51,6 +52,7 @@ aaudio_data_callback_result_t NoopDataCallbackProc(
}

constexpr int64_t NANOS_PER_MILLISECOND = 1000 * 1000;
constexpr int64_t MICROS_PER_MILLISECOND = 1000;

void checkReleaseThenClose(aaudio_performance_mode_t perfMode,
        aaudio_sharing_mode_t sharingMode,
@@ -762,6 +764,58 @@ TEST(test_various, aaudio_callback_once_lowlat) {
    checkCallbackOnce(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
}

void waitForStateChangeToClosingorClosed(AAudioStream **stream, std::atomic<bool>* isReady)
{
    *isReady = true;
    aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
    EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(*stream,
                                                         AAUDIO_STREAM_STATE_OPEN, &state,
                                                         10000 * NANOS_PER_MILLISECOND));
    if ((state != AAUDIO_STREAM_STATE_CLOSING) && (state != AAUDIO_STREAM_STATE_CLOSED)){
        FAIL() << "ERROR - State not closing or closed. Current state: " <<
                AAudio_convertStreamStateToText(state);
    }
}

void testWaitForStateChangeClose(aaudio_performance_mode_t perfMode) {
    AAudioStreamBuilder *aaudioBuilder = nullptr;
    AAudioStream *aaudioStream = nullptr;

    ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
    AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, perfMode);
    ASSERT_EQ(AAUDIO_OK, AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream));

    // Verify Open State
    aaudio_stream_state_t state = AAUDIO_STREAM_STATE_UNKNOWN;
    EXPECT_EQ(AAUDIO_OK, AAudioStream_waitForStateChange(aaudioStream,
                                                         AAUDIO_STREAM_STATE_UNKNOWN, &state,
                                                         1000 * NANOS_PER_MILLISECOND));
    EXPECT_EQ(AAUDIO_STREAM_STATE_OPEN, state);

    std::atomic<bool> isWaitThreadReady{false};

    // Spawn a new thread to wait for the state change
    std::thread waitThread (waitForStateChangeToClosingorClosed, &aaudioStream,
                            &isWaitThreadReady);

    // Wait for worker thread to be ready
    while (!isWaitThreadReady) {
        usleep(MICROS_PER_MILLISECOND);
    }
    // Sleep an additional millisecond to make sure waitForAudioThread is called
    usleep(MICROS_PER_MILLISECOND);
    EXPECT_EQ(AAUDIO_OK, AAudioStream_close(aaudioStream));
    waitThread.join();
}

TEST(test_various, wait_for_state_change_close_none) {
    testWaitForStateChangeClose(AAUDIO_PERFORMANCE_MODE_NONE);
}

TEST(test_various, wait_for_state_change_close_lowlat) {
    testWaitForStateChangeClose(AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
}

// ************************************************************
struct WakeUpCallbackData {
    void wakeOther() {
+20 −3
Original line number Diff line number Diff line
@@ -975,8 +975,16 @@ bool AudioTrack::pauseAndWait(const std::chrono::milliseconds& timeout)
{
    using namespace std::chrono_literals;

    // We use atomic access here for state variables - these are used as hints
    // to ensure we have ramped down audio.
    const int priorState = mProxy->getState();
    const uint32_t priorPosition = mProxy->getPosition().unsignedValue();

    pause();

    // Only if we were previously active, do we wait to ramp down the audio.
    if (priorState != CBLK_STATE_ACTIVE) return true;

    AutoMutex lock(mLock);
    // offload and direct tracks do not wait because pause volume ramp is handled by hardware.
    if (isOffloadedOrDirect_l()) return true;
@@ -984,16 +992,25 @@ bool AudioTrack::pauseAndWait(const std::chrono::milliseconds& timeout)
    // Wait for the track state to be anything besides pausing.
    // This ensures that the volume has ramped down.
    constexpr auto SLEEP_INTERVAL_MS = 10ms;
    constexpr auto POSITION_TIMEOUT_MS = 40ms; // don't wait longer than this for position change.
    auto begin = std::chrono::steady_clock::now();
    while (true) {
        // wait for state to change
        // Wait for state and position to change.
        // After pause() the server state should be PAUSING, but that may immediately
        // convert to PAUSED by prepareTracks before data is read into the mixer.
        // Hence we check that the state is not PAUSING and that the server position
        // has advanced to be a more reliable estimate that the volume ramp has completed.
        const int state = mProxy->getState();
        const uint32_t position = mProxy->getPosition().unsignedValue();

        mLock.unlock(); // only local variables accessed until lock.
        auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(
                std::chrono::steady_clock::now() - begin);
        if (state != CBLK_STATE_PAUSING) {
            ALOGV("%s: success state:%d after %lld ms", __func__, state, elapsed.count());
        if (state != CBLK_STATE_PAUSING &&
                (elapsed >= POSITION_TIMEOUT_MS || position != priorPosition)) {
            ALOGV("%s: success state:%d, position:%u after %lld ms"
                    " (prior state:%d  prior position:%u)",
                    __func__, state, position, elapsed.count(), priorState, priorPosition);
            return true;
        }
        std::chrono::milliseconds remaining = timeout - elapsed;
Loading