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

Commit 797d8d64 authored by Android Merger's avatar Android Merger Committed by Gerrit Code Review
Browse files

Merge "Snap for 5240760 from accfc658 to...

Merge "Snap for 5240760 from accfc658 to pi-platform-release am: a31eb276" into pie-gsi
parents 4d85447e e68c2c68
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@ fifo_frames_t FifoControllerBase::getFullFramesAvailable() {

fifo_frames_t FifoControllerBase::getReadIndex() {
    // % works with non-power of two sizes
    return (fifo_frames_t) (getReadCounter() % mCapacity);
    return (fifo_frames_t) ((uint64_t)getReadCounter() % mCapacity);
}

void FifoControllerBase::advanceReadIndex(fifo_frames_t numFrames) {
@@ -51,7 +51,7 @@ fifo_frames_t FifoControllerBase::getEmptyFramesAvailable() {

fifo_frames_t FifoControllerBase::getWriteIndex() {
    // % works with non-power of two sizes
    return (fifo_frames_t) (getWriteCounter() % mCapacity);
    return (fifo_frames_t) ((uint64_t)getWriteCounter() % mCapacity);
}

void FifoControllerBase::advanceWriteIndex(fifo_frames_t numFrames) {
+189 −30
Original line number Diff line number Diff line
@@ -23,12 +23,12 @@
#include "fifo/FifoController.h"

using android::fifo_frames_t;
using android::fifo_counter_t;
using android::FifoController;
using android::FifoBuffer;
using android::WrappingBuffer;

//void foo() {
TEST(test_fifi_controller, fifo_indices) {
TEST(test_fifo_controller, fifo_indices) {
    // Values are arbitrary primes designed to trigger edge cases.
    constexpr int capacity = 83;
    constexpr int threshold = 47;
@@ -73,18 +73,59 @@ TEST(test_fifi_controller, fifo_indices) {
    ASSERT_EQ(threshold - advance2, fifoController.getEmptyFramesAvailable());
}

TEST(test_fifo_controller, fifo_wrap_around_zero) {
    constexpr int capacity = 7; // arbitrary prime
    constexpr int threshold = capacity;
    FifoController fifoController(capacity, threshold);
    ASSERT_EQ(capacity, fifoController.getCapacity());
    ASSERT_EQ(threshold, fifoController.getThreshold());

    fifoController.setReadCounter(-10); // a bit less than negative capacity
    for (int i = 0; i < 20; i++) {
        EXPECT_EQ(i - 10, fifoController.getReadCounter());
        EXPECT_GE(fifoController.getReadIndex(), 0);
        EXPECT_LT(fifoController.getReadIndex(), capacity);
        fifoController.advanceReadIndex(1);
    }

    fifoController.setWriteCounter(-10);
    for (int i = 0; i < 20; i++) {
        EXPECT_EQ(i - 10, fifoController.getWriteCounter());
        EXPECT_GE(fifoController.getWriteIndex(), 0);
        EXPECT_LT(fifoController.getWriteIndex(), capacity);
        fifoController.advanceWriteIndex(1);
    }
}


// TODO consider using a template for other data types.

// Create a big array and then use a region in the middle for the  unit tests.
// Then we can scan the rest of the array to see if it got clobbered.
static constexpr fifo_frames_t kBigArraySize = 1024;
static constexpr fifo_frames_t kFifoDataOffset = 128; // starting index of FIFO data
static constexpr int16_t       kSafeDataValue = 0x7654; // original value of BigArray

class TestFifoBuffer {
public:
    explicit TestFifoBuffer(fifo_frames_t capacity, fifo_frames_t threshold = 0)
        : mFifoBuffer(sizeof(int16_t), capacity) {
        : mFifoBuffer(sizeof(int16_t), capacity,
                      &mReadIndex,
                      &mWriteIndex,
                      &mVeryBigArray[kFifoDataOffset]) // address of start of FIFO data
    {

        // Assume a frame is one int16_t.
        // For reading and writing.
        mData = new int16_t[capacity];
        if (threshold <= 0) {
            threshold = capacity;
        }
        mFifoBuffer.setThreshold(threshold);
        mThreshold = threshold;

        for (fifo_frames_t i = 0; i < kBigArraySize; i++) {
            mVeryBigArray[i] = kSafeDataValue;
        }
    }

    void checkMisc() {
@@ -92,26 +133,70 @@ public:
        ASSERT_EQ(mThreshold, mFifoBuffer.getThreshold());
    }

    void verifyAddressInRange(void *p, void *valid, size_t numBytes) {
        uintptr_t p_int = (uintptr_t) p;
        uintptr_t valid_int = (uintptr_t) valid;
        EXPECT_GE(p_int, valid_int);
        EXPECT_LT(p_int, (valid_int + numBytes));
    }

    void verifyStorageIntegrity() {
        for (fifo_frames_t i = 0; i < kFifoDataOffset; i++) {
            EXPECT_EQ(mVeryBigArray[i], kSafeDataValue);
        }
        fifo_frames_t firstFrameAfter = kFifoDataOffset + mFifoBuffer.getBufferCapacityInFrames();
        for (fifo_frames_t i = firstFrameAfter; i < kBigArraySize; i++) {
            EXPECT_EQ(mVeryBigArray[i], kSafeDataValue);
        }
    }

    // Verify that the available frames in each part add up correctly.
    void checkWrappingBuffer() {
    void verifyWrappingBuffer() {
        WrappingBuffer wrappingBuffer;


        // Does the sum of the two parts match the available value returned?
        // For EmptyRoom
        fifo_frames_t framesAvailable =
                mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
        fifo_frames_t wrapAvailable = mFifoBuffer.getEmptyRoomAvailable(&wrappingBuffer);
        EXPECT_EQ(framesAvailable, wrapAvailable);
        fifo_frames_t bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
        EXPECT_EQ(framesAvailable, bothAvailable);

        // For FullData
        framesAvailable =
                mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
        wrapAvailable = mFifoBuffer.getFullDataAvailable(&wrappingBuffer);
        EXPECT_EQ(framesAvailable, wrapAvailable);
        bothAvailable = wrappingBuffer.numFrames[0] + wrappingBuffer.numFrames[1];
        EXPECT_EQ(framesAvailable, bothAvailable);

        // Are frame counts in legal range?
        fifo_frames_t capacity = mFifoBuffer.getBufferCapacityInFrames();
        EXPECT_GE(wrappingBuffer.numFrames[0], 0);
        EXPECT_LE(wrappingBuffer.numFrames[0], capacity);
        EXPECT_GE(wrappingBuffer.numFrames[1], 0);
        EXPECT_LE(wrappingBuffer.numFrames[1], capacity);

        // Are addresses within the FIFO data area?
        size_t validBytes = capacity * sizeof(int16_t);
        if (wrappingBuffer.numFrames[0]) {
            verifyAddressInRange(wrappingBuffer.data[0], mFifoStorage, validBytes);
            uint8_t *last = ((uint8_t *)wrappingBuffer.data[0])
                            + mFifoBuffer.convertFramesToBytes(wrappingBuffer.numFrames[0]) - 1;
            verifyAddressInRange(last, mFifoStorage, validBytes);
        }
        if (wrappingBuffer.numFrames[1]) {
            verifyAddressInRange(wrappingBuffer.data[1], mFifoStorage, validBytes);
            uint8_t *last = ((uint8_t *)wrappingBuffer.data[1])
                            + mFifoBuffer.convertFramesToBytes(wrappingBuffer.numFrames[1]) - 1;
            verifyAddressInRange(last, mFifoStorage, validBytes);
        }

    }

    // Write data but do not overflow.
    void writeData(fifo_frames_t numFrames) {
    void writeMultipleDataFrames(fifo_frames_t numFrames) {
        fifo_frames_t framesAvailable =
                mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
        fifo_frames_t framesToWrite = std::min(framesAvailable, numFrames);
@@ -122,8 +207,8 @@ public:
        ASSERT_EQ(framesToWrite, actual);
    }

    // Read data but do not underflow.
    void verifyData(fifo_frames_t numFrames) {
    // Read whatever data is available, Do not underflow.
    void verifyMultipleDataFrames(fifo_frames_t numFrames) {
        fifo_frames_t framesAvailable =
                mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
        fifo_frames_t framesToRead = std::min(framesAvailable, numFrames);
@@ -134,20 +219,35 @@ public:
        }
    }

    // Read specified number of frames
    void verifyRequestedData(fifo_frames_t numFrames) {
        fifo_frames_t framesAvailable =
                mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
        ASSERT_LE(numFrames, framesAvailable);
        fifo_frames_t framesToRead = std::min(framesAvailable, numFrames);
        fifo_frames_t actual = mFifoBuffer.read(mData, framesToRead);
        ASSERT_EQ(actual, numFrames);
        for (int i = 0; i < actual; i++) {
            ASSERT_EQ(mNextVerifyIndex++, mData[i]);
        }
    }

    // Wrap around the end of the buffer.
    void checkWrappingWriteRead() {
        constexpr int frames1 = 43;
        constexpr int frames2 = 15;

        writeData(frames1);
        checkWrappingBuffer();
        verifyData(frames1);
        checkWrappingBuffer();
        writeMultipleDataFrames(frames1);
        verifyWrappingBuffer();
        verifyRequestedData(frames1);
        verifyWrappingBuffer();

        writeMultipleDataFrames(frames2);
        verifyWrappingBuffer();
        verifyRequestedData(frames2);
        verifyWrappingBuffer();

        writeData(frames2);
        checkWrappingBuffer();
        verifyData(frames2);
        checkWrappingBuffer();
        verifyStorageIntegrity();
    }

    // Write and Read a specific amount of data.
@@ -156,10 +256,12 @@ public:
        // Wrap around with the smaller region in the second half.
        const int frames1 = capacity - 4;
        const int frames2 = 7; // arbitrary, small
        writeData(frames1);
        verifyData(frames1);
        writeData(frames2);
        verifyData(frames2);
        writeMultipleDataFrames(frames1);
        verifyRequestedData(frames1);
        writeMultipleDataFrames(frames2);
        verifyRequestedData(frames2);

        verifyStorageIntegrity();
    }

    // Write and Read a specific amount of data.
@@ -168,10 +270,12 @@ public:
        // Wrap around with the larger region in the second half.
        const int frames1 = capacity - 4;
        const int frames2 = capacity - 9; // arbitrary, large
        writeData(frames1);
        verifyData(frames1);
        writeData(frames2);
        verifyData(frames2);
        writeMultipleDataFrames(frames1);
        verifyRequestedData(frames1);
        writeMultipleDataFrames(frames2);
        verifyRequestedData(frames2);

        verifyStorageIntegrity();
    }

    // Randomly read or write up to the maximum amount of data.
@@ -180,30 +284,67 @@ public:
            fifo_frames_t framesEmpty =
                    mFifoBuffer.getFifoControllerBase()->getEmptyFramesAvailable();
            fifo_frames_t numFrames = (fifo_frames_t)(drand48() * framesEmpty);
            writeData(numFrames);
            writeMultipleDataFrames(numFrames);

            fifo_frames_t framesFull =
                    mFifoBuffer.getFifoControllerBase()->getFullFramesAvailable();
            numFrames = (fifo_frames_t)(drand48() * framesFull);
            verifyData(numFrames);
            verifyMultipleDataFrames(numFrames);
        }

        verifyStorageIntegrity();
    }

    // Write and Read a specific amount of data.
    void checkNegativeCounters() {
        fifo_counter_t counter = -9876;
        mFifoBuffer.setWriteCounter(counter);
        mFifoBuffer.setReadCounter(counter);
        checkWrappingWriteRead();
    }

    // Wrap over the boundary at 0x7FFFFFFFFFFFFFFF
    // Note that the behavior of a signed overflow is technically undefined.
    void checkHalfWrap() {
        fifo_counter_t counter = INT64_MAX - 10;
        mFifoBuffer.setWriteCounter(counter);
        mFifoBuffer.setReadCounter(counter);
        ASSERT_GT(mFifoBuffer.getWriteCounter(), 0);
        checkWrappingWriteRead();
        ASSERT_LT(mFifoBuffer.getWriteCounter(), 0); // did we wrap past INT64_MAX?
    }

    // Wrap over the boundary at 0xFFFFFFFFFFFFFFFF
    void checkFullWrap() {
        fifo_counter_t counter = -10;
        mFifoBuffer.setWriteCounter(counter);
        mFifoBuffer.setReadCounter(counter);
        ASSERT_LT(mFifoBuffer.getWriteCounter(), 0);
        writeMultipleDataFrames(20);
        ASSERT_GT(mFifoBuffer.getWriteCounter(), 0); // did we wrap past zero?
        verifyStorageIntegrity();
    }

    FifoBuffer     mFifoBuffer;
    int16_t       *mData;
    fifo_frames_t  mNextWriteIndex = 0;
    fifo_frames_t  mNextVerifyIndex = 0;
    fifo_frames_t  mThreshold;

    fifo_counter_t mReadIndex = 0;
    fifo_counter_t mWriteIndex = 0;
    int16_t        mVeryBigArray[kBigArraySize]; // Use the middle of this array for the FIFO.
    int16_t       *mFifoStorage = &mVeryBigArray[kFifoDataOffset]; // Start here for storage.
    int16_t        mData[kBigArraySize]{};
};

TEST(test_fifo_buffer, fifo_read_write) {
TEST(test_fifo_buffer, fifo_write_read) {
    constexpr int capacity = 51; // arbitrary
    TestFifoBuffer tester(capacity);
    tester.checkMisc();
    tester.checkWriteRead();
}

TEST(test_fifo_buffer, fifo_wrapping_read_write) {
TEST(test_fifo_buffer, fifo_wrapping_write_read) {
    constexpr int capacity = 59; // arbitrary, a little bigger this time
    TestFifoBuffer tester(capacity);
    tester.checkWrappingWriteRead();
@@ -227,3 +368,21 @@ TEST(test_fifo_buffer, fifo_random_threshold) {
    TestFifoBuffer tester(capacity, threshold);
    tester.checkRandomWriteRead();
}

TEST(test_fifo_buffer, fifo_negative_counters) {
    constexpr int capacity = 49; // arbitrary
    TestFifoBuffer tester(capacity);
    tester.checkNegativeCounters();
}

TEST(test_fifo_buffer, fifo_half_wrap) {
    constexpr int capacity = 57; // arbitrary
    TestFifoBuffer tester(capacity);
    tester.checkHalfWrap();
}

TEST(test_fifo_buffer, fifo_full_wrap) {
    constexpr int capacity = 57; // arbitrary
    TestFifoBuffer tester(capacity);
    tester.checkFullWrap();
}
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ void HalDeathHandler::serviceDied(uint64_t /*cookie*/, const wp<IBase>& /*who*/)
        handler.second();
    }
    ALOGE("HAL server crashed, audio server is restarting");
    exit(1);
    _exit(1);  // Avoid calling atexit handlers, as this code runs on a thread from RPC threadpool.
}

} // namespace android
+4 −0
Original line number Diff line number Diff line
@@ -3001,6 +3001,8 @@ sp<IEffect> AudioFlinger::createEffect(
    }

    {
        Mutex::Autolock _l(mLock);

        if (!EffectsFactoryHalInterface::isNullUuid(&pDesc->uuid)) {
            // if uuid is specified, request effect descriptor
            lStatus = mEffectsFactoryHal->getDescriptor(&pDesc->uuid, &desc);
@@ -3056,6 +3058,8 @@ sp<IEffect> AudioFlinger::createEffect(
                desc = d;
            }
        }
    }
    {

        // Do not allow auxiliary effects on a session different from 0 (output mix)
        if (sessionId != AUDIO_SESSION_OUTPUT_MIX &&