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

Commit aea43810 authored by Xin Li's avatar Xin Li
Browse files

Merge Android 12 QPR 3

Bug: 236045730
Merged-In: Iaa97a03bc18f72e3dfb4cc6600cbec8f2cc876e1
Change-Id: I5bc201841262ae3a409a4bb03aade310687681db
parents e2f4f1ce 2bdebb91
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