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
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index ac2f4d5..d1f63a7 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -65,6 +65,25 @@
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> {
TestLightFlattenable() = default;
explicit TestLightFlattenable(int32_t v) : value(v) {}
@@ -142,6 +161,7 @@
SetDeathToken = IBinder::FIRST_CALL_TRANSACTION,
ReturnsNoMemory,
LogicalNot,
+ IncrementFlattenable,
IncrementLightFlattenable,
IncrementNoCopyNoMove,
ToUpper,
@@ -161,6 +181,7 @@
// These are ordered according to their corresponding methods in SafeInterface::ParcelHandler
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,
TestLightFlattenable* aPlusOne) const = 0;
virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
@@ -192,6 +213,12 @@
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
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,
TestLightFlattenable* aPlusOne) const override {
using Signature = status_t (ISafeInterfaceTest::*)(const TestLightFlattenable&,
@@ -263,6 +290,11 @@
*notA = !a;
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,
TestLightFlattenable* aPlusOne) const override {
ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
@@ -317,6 +349,11 @@
case ISafeInterfaceTest::Tag::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: {
using Signature =
status_t (ISafeInterfaceTest::*)(const TestLightFlattenable& a,
@@ -428,6 +465,14 @@
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) {
const TestLightFlattenable a{1};
TestLightFlattenable aPlusOne{0};