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

Commit acb9c3da authored by Pawan Wagh's avatar Pawan Wagh Committed by Automerger Merge Worker
Browse files

Merge changes If163fe2a,Ib736cc16 am: 9e350221 am: a1618f31

parents 6c63b3c5 a1618f31
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -15,6 +15,24 @@
 */

interface IBinderRecordReplayTest {
    void setByte(byte input);
    byte getByte();

    void setChar(char input);
    char getChar();

    void setBoolean(boolean input);
    boolean getBoolean();

    void setInt(int input);
    int getInt();

    void setFloat(float input);
    float getFloat();

    void setLong(long input);
    long getLong();

    void setDouble(double input);
    double getDouble();
}
+111 −52
Original line number Diff line number Diff line
@@ -33,47 +33,67 @@ using android::binder::debug::RecordedTransaction;

const String16 kServerName = String16("binderRecordReplay");

#define GENERATE_GETTER_SETTER(name, T) \
    Status set##name(T input) {         \
        m##name = input;                \
        return Status::ok();            \
    }                                   \
                                        \
    Status get##name(T* output) {       \
        *output = m##name;              \
        return Status::ok();            \
    }                                   \
    T m##name

class MyRecordReplay : public BnBinderRecordReplayTest {
public:
    Status setInt(int input) {
        mInt = input;
        return Status::ok();
    }
    Status getInt(int* output) {
        *output = mInt;
        return Status::ok();
    }

private:
    int mInt = 0;
    GENERATE_GETTER_SETTER(Boolean, bool);
    GENERATE_GETTER_SETTER(Byte, int8_t);
    GENERATE_GETTER_SETTER(Int, int);
    GENERATE_GETTER_SETTER(Char, char16_t);
    GENERATE_GETTER_SETTER(Long, int64_t);
    GENERATE_GETTER_SETTER(Float, float);
    GENERATE_GETTER_SETTER(Double, double);
};

TEST(BinderClearBuf, RecordReplayRepeatInt) {
class BinderClearBuf : public ::testing::Test {
public:
    void SetUp() override {
        // get the remote service
    sp<IBinder> binder = defaultServiceManager()->getService(kServerName);
    ASSERT_NE(nullptr, binder);
    sp<IBinderRecordReplayTest> iface = interface_cast<IBinderRecordReplayTest>(binder);
    sp<BpBinder> bpBinder = binder->remoteBinder();
    ASSERT_NE(nullptr, bpBinder);

    base::unique_fd fd(
            open("/data/local/tmp/binderRecordReplayTest.rec", O_RDWR | O_CREAT | O_CLOEXEC, 0666));
        mBinder = defaultServiceManager()->getService(kServerName);
        ASSERT_NE(nullptr, mBinder);
        mInterface = interface_cast<IBinderRecordReplayTest>(mBinder);
        mBpBinder = mBinder->remoteBinder();
        ASSERT_NE(nullptr, mBpBinder);
    }

    template <typename T>
    void recordReplay(Status (IBinderRecordReplayTest::*set)(T), T recordedValue,
                      Status (IBinderRecordReplayTest::*get)(T*), T changedValue) {
        base::unique_fd fd(open("/data/local/tmp/binderRecordReplayTest.rec",
                                O_RDWR | O_CREAT | O_CLOEXEC, 0666));
        ASSERT_TRUE(fd.ok());

        // record a transaction
    bpBinder->startRecordingBinder(fd);
    EXPECT_TRUE(iface->setInt(3).isOk());
    bpBinder->stopRecordingBinder();
        mBpBinder->startRecordingBinder(fd);
        auto status = (*mInterface.*set)(recordedValue);
        EXPECT_TRUE(status.isOk());
        mBpBinder->stopRecordingBinder();

        // test transaction does the thing we expect it to do
    int output;
    EXPECT_TRUE(iface->getInt(&output).isOk());
    EXPECT_EQ(output, 3);
        T output;
        status = (*mInterface.*get)(&output);
        EXPECT_TRUE(status.isOk());
        EXPECT_EQ(output, recordedValue);

        // write over the existing state
    EXPECT_TRUE(iface->setInt(5).isOk());
    EXPECT_TRUE(iface->getInt(&output).isOk());
    EXPECT_EQ(output, 5);
        status = (*mInterface.*set)(changedValue);
        EXPECT_TRUE(status.isOk());

        status = (*mInterface.*get)(&output);
        EXPECT_TRUE(status.isOk());

        EXPECT_EQ(output, changedValue);

        // replay transaction
        ASSERT_EQ(0, lseek(fd.get(), 0, SEEK_SET));
@@ -83,16 +103,55 @@ TEST(BinderClearBuf, RecordReplayRepeatInt) {
        // TODO: move logic to replay RecordedTransaction into RecordedTransaction
        Parcel data;
        data.setData(transaction->getDataParcel().data(), transaction->getDataParcel().dataSize());
    status_t status = binder->remoteBinder()->transact(transaction->getCode(), data, nullptr,
        auto result = mBinder->remoteBinder()->transact(transaction->getCode(), data, nullptr,
                                                        transaction->getFlags());

        // make sure recording does the thing we expect it to do
    EXPECT_EQ(OK, status);
    EXPECT_TRUE(iface->getInt(&output).isOk());
    EXPECT_EQ(output, 3);
        EXPECT_EQ(OK, result);

        status = (*mInterface.*get)(&output);
        EXPECT_TRUE(status.isOk());
        EXPECT_EQ(output, recordedValue);
    }

private:
    sp<IBinder> mBinder;
    sp<BpBinder> mBpBinder;
    sp<IBinderRecordReplayTest> mInterface;
};

TEST_F(BinderClearBuf, RecordReplayRepeatByte) {
    recordReplay(&IBinderRecordReplayTest::setByte, int8_t{122}, &IBinderRecordReplayTest::getByte,
                 int8_t{90});
}

TEST_F(BinderClearBuf, RecordReplayRepeatBoolean) {
    recordReplay(&IBinderRecordReplayTest::setBoolean, true, &IBinderRecordReplayTest::getBoolean,
                 false);
}

TEST_F(BinderClearBuf, RecordReplayRepeatChar) {
    recordReplay(&IBinderRecordReplayTest::setChar, char16_t{'G'},
                 &IBinderRecordReplayTest::getChar, char16_t{'K'});
}

TEST_F(BinderClearBuf, RecordReplayRepeatInt) {
    recordReplay(&IBinderRecordReplayTest::setInt, 3, &IBinderRecordReplayTest::getInt, 5);
}

TEST_F(BinderClearBuf, RecordReplayRepeatFloat) {
    recordReplay(&IBinderRecordReplayTest::setFloat, 1.1f, &IBinderRecordReplayTest::getFloat,
                 22.0f);
}

TEST_F(BinderClearBuf, RecordReplayRepeatLong) {
    recordReplay(&IBinderRecordReplayTest::setLong, int64_t{1LL << 55},
                 &IBinderRecordReplayTest::getLong, int64_t{1LL << 12});
}

    // TODO: we should also make sure we can convert the recording to a fuzzer
    // corpus entry, and we will be able to replay it in the same way
TEST_F(BinderClearBuf, RecordReplayRepeatDouble) {
    recordReplay(&IBinderRecordReplayTest::setDouble, 0.00, &IBinderRecordReplayTest::getDouble,
                 1.11);
}

int main(int argc, char** argv) {