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

Commit df614ae8 authored by Dan Stoza's avatar Dan Stoza
Browse files

libbinder: Support Flattenable in SafeInterface

Adds support for sending and receiving Flattenable parameters as part
of a SafeInterface.

Test: New test in binderSafeInterfaceTest
Change-Id: I5c84d6f27ac1f8c7ad37210e836f390e02b92959
parent 78b28608
Loading
Loading
Loading
Loading
+10 −0
Original line number Original line Diff line number Diff line
@@ -45,6 +45,16 @@ public:
        return callParcel("writeBool", [&]() { return parcel->writeBool(b); });
        return callParcel("writeBool", [&]() { return parcel->writeBool(b); });
    }
    }
    template <typename T>
    template <typename T>
    typename std::enable_if<std::is_base_of<Flattenable<T>, T>::value, status_t>::type read(
            const Parcel& parcel, T* t) const {
        return callParcel("read(Flattenable)", [&]() { return parcel.read(*t); });
    }
    template <typename T>
    typename std::enable_if<std::is_base_of<Flattenable<T>, T>::value, status_t>::type write(
            Parcel* parcel, const T& t) const {
        return callParcel("write(Flattenable)", [&]() { return parcel->write(t); });
    }
    template <typename T>
    typename std::enable_if<std::is_base_of<LightFlattenable<T>, T>::value, status_t>::type read(
    typename std::enable_if<std::is_base_of<LightFlattenable<T>, T>::value, status_t>::type read(
            const Parcel& parcel, T* t) const {
            const Parcel& parcel, T* t) const {
        return callParcel("read(LightFlattenable)", [&]() { return parcel.read(*t); });
        return callParcel("read(LightFlattenable)", [&]() { return parcel.read(*t); });
+45 −0
Original line number Original line Diff line number Diff line
@@ -65,6 +65,25 @@ private:
    uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
    uint8_t mPadding[4] = {}; // Avoids a warning from -Wpadded
};
};


struct TestFlattenable : Flattenable<TestFlattenable> {
    TestFlattenable() = default;
    explicit TestFlattenable(int32_t v) : value(v) {}

    // Flattenable protocol
    size_t getFlattenedSize() const { return sizeof(value); }
    size_t getFdCount() const { return 0; }
    status_t flatten(void*& buffer, size_t& size, int*& /*fds*/, size_t& /*count*/) const {
        FlattenableUtils::write(buffer, size, value);
        return NO_ERROR;
    }
    status_t unflatten(void const*& buffer, size_t& size, int const*& /*fds*/, size_t& /*count*/) {
        FlattenableUtils::read(buffer, size, value);
        return NO_ERROR;
    }

    int32_t value = 0;
};

struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
struct TestLightFlattenable : LightFlattenablePod<TestLightFlattenable> {
    TestLightFlattenable() = default;
    TestLightFlattenable() = default;
    explicit TestLightFlattenable(int32_t v) : value(v) {}
    explicit TestLightFlattenable(int32_t v) : value(v) {}
@@ -142,6 +161,7 @@ public:
        SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
        SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
        ReturnsNoMemory,
        ReturnsNoMemory,
        LogicalNot,
        LogicalNot,
        IncrementFlattenable,
        IncrementLightFlattenable,
        IncrementLightFlattenable,
        IncrementNoCopyNoMove,
        IncrementNoCopyNoMove,
        ToUpper,
        ToUpper,
@@ -161,6 +181,7 @@ public:


    // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
    // These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
    virtual status_t logicalNot(bool a, bool* notA) const = 0;
    virtual status_t logicalNot(bool a, bool* notA) const = 0;
    virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0;
    virtual status_t increment(const TestLightFlattenable& a,
    virtual status_t increment(const TestLightFlattenable& a,
                               TestLightFlattenable* aPlusOne) const = 0;
                               TestLightFlattenable* aPlusOne) const = 0;
    virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
    virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
@@ -192,6 +213,12 @@ public:
        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
        return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
        return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA);
    }
    }
    status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
        using Signature =
                status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const;
        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
        return callRemote<Signature>(Tag::IncrementFlattenable, a, aPlusOne);
    }
    status_t increment(const TestLightFlattenable& a,
    status_t increment(const TestLightFlattenable& a,
                       TestLightFlattenable* aPlusOne) const override {
                       TestLightFlattenable* aPlusOne) const override {
        using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
        using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
@@ -263,6 +290,11 @@ public:
        *notA = !a;
        *notA = !a;
        return NO_ERROR;
        return NO_ERROR;
    }
    }
    status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override {
        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
        aPlusOne->value = a.value + 1;
        return NO_ERROR;
    }
    status_t increment(const TestLightFlattenable& a,
    status_t increment(const TestLightFlattenable& a,
                       TestLightFlattenable* aPlusOne) const override {
                       TestLightFlattenable* aPlusOne) const override {
        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
@@ -317,6 +349,11 @@ public:
            case ISafeInterfaceTest::Tag::LogicalNot: {
            case ISafeInterfaceTest::Tag::LogicalNot: {
                return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
                return callLocal(data, reply, &ISafeInterfaceTest::logicalNot);
            }
            }
            case ISafeInterfaceTest::Tag::IncrementFlattenable: {
                using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a,
                                                                   TestFlattenable* aPlusOne) const;
                return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
            }
            case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
            case ISafeInterfaceTest::Tag::IncrementLightFlattenable: {
                using Signature =
                using Signature =
                        status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
                        status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
@@ -428,6 +465,14 @@ TEST_F(SafeInterfaceTest, TestLogicalNot) {
    ASSERT_EQ(!b, notB);
    ASSERT_EQ(!b, notB);
}
}


TEST_F(SafeInterfaceTest, TestIncrementFlattenable) {
    const TestFlattenable a{1};
    TestFlattenable aPlusOne{0};
    status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
    ASSERT_EQ(NO_ERROR, result);
    ASSERT_EQ(a.value + 1, aPlusOne.value);
}

TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
TEST_F(SafeInterfaceTest, TestIncrementLightFlattenable) {
    const TestLightFlattenable a{1};
    const TestLightFlattenable a{1};
    TestLightFlattenable aPlusOne{0};
    TestLightFlattenable aPlusOne{0};