diff options
author | 2017-03-28 17:02:05 -0700 | |
---|---|---|
committer | 2017-04-04 16:11:55 -0700 | |
commit | df614ae850b0b277030f94fd32062d45e723f91b (patch) | |
tree | 679adb8d86166f9e12f45ae614670d75add1ab5c | |
parent | 78b286087b99c60b614c300b8b76f6f6dc8d54f7 (diff) |
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
-rw-r--r-- | libs/binder/include/binder/SafeInterface.h | 10 | ||||
-rw-r--r-- | libs/binder/tests/binderSafeInterfaceTest.cpp | 45 |
2 files changed, 55 insertions, 0 deletions
diff --git a/libs/binder/include/binder/SafeInterface.h b/libs/binder/include/binder/SafeInterface.h index 0e723c59ee..44c1352984 100644 --- a/libs/binder/include/binder/SafeInterface.h +++ b/libs/binder/include/binder/SafeInterface.h @@ -45,6 +45,16 @@ public: return callParcel("writeBool", [&]() { return parcel->writeBool(b); }); } 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( const Parcel& parcel, T* t) const { return callParcel("read(LightFlattenable)", [&]() { return parcel.read(*t); }); diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp index ac2f4d5a59..d1f63a728b 100644 --- a/libs/binder/tests/binderSafeInterfaceTest.cpp +++ b/libs/binder/tests/binderSafeInterfaceTest.cpp @@ -65,6 +65,25 @@ private: 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 @@ public: SetDeathToken = IBinder::FIRST_CALL_TRANSACTION, ReturnsNoMemory, LogicalNot, + IncrementFlattenable, IncrementLightFlattenable, IncrementNoCopyNoMove, ToUpper, @@ -161,6 +181,7 @@ public: // 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 @@ public: 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 @@ public: *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 @@ public: 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 @@ TEST_F(SafeInterfaceTest, TestLogicalNot) { 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}; |