diff options
| author | 2017-04-07 15:00:18 -0700 | |
|---|---|---|
| committer | 2017-04-10 14:35:41 -0700 | |
| commit | 81ea3efb75a6427c946221f95dcf9c388b27a977 (patch) | |
| tree | 52f97ee1433992ef737689930a76ce09ac11a0c5 | |
| parent | 6dd325b9396c9946ced9d01665152a44167a8fa2 (diff) | |
libbinder: Support enums in SafeInterface
Adds support for sending and receiving enum values (as their underlying
types) as part of a SafeInterface.
Test: New test in binderSafeInterfaceTest
Change-Id: I9c3b6b7e7728d8c95514928354136be84bfd7875
| -rw-r--r-- | libs/binder/include/binder/SafeInterface.h | 13 | ||||
| -rw-r--r-- | libs/binder/tests/binderSafeInterfaceTest.cpp | 28 |
2 files changed, 41 insertions, 0 deletions
diff --git a/libs/binder/include/binder/SafeInterface.h b/libs/binder/include/binder/SafeInterface.h index 52037049c8..f931304b95 100644 --- a/libs/binder/include/binder/SafeInterface.h +++ b/libs/binder/include/binder/SafeInterface.h @@ -44,6 +44,19 @@ public: status_t write(Parcel* parcel, bool b) const { return callParcel("writeBool", [&]() { return parcel->writeBool(b); }); } + template <typename E> + typename std::enable_if<std::is_enum<E>::value, status_t>::type read(const Parcel& parcel, + E* e) const { + typename std::underlying_type<E>::type u{}; + status_t result = read(parcel, &u); + *e = static_cast<E>(u); + return result; + } + template <typename E> + typename std::enable_if<std::is_enum<E>::value, status_t>::type write(Parcel* parcel, + E e) const { + return write(parcel, static_cast<typename std::underlying_type<E>::type>(e)); + } 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 { diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp index 70f49000f1..ccb023d2ce 100644 --- a/libs/binder/tests/binderSafeInterfaceTest.cpp +++ b/libs/binder/tests/binderSafeInterfaceTest.cpp @@ -37,6 +37,12 @@ using namespace std::chrono_literals; // NOLINT - google-build-using-namespace namespace android { namespace tests { +enum class TestEnum : uint32_t { + INVALID = 0, + INITIAL = 1, + FINAL = 2, +}; + // This class serves two purposes: // 1) It ensures that the implementation doesn't require copying or moving the data (for // efficiency purposes) @@ -187,6 +193,7 @@ public: SetDeathToken = IBinder::FIRST_CALL_TRANSACTION, ReturnsNoMemory, LogicalNot, + ModifyEnum, IncrementFlattenable, IncrementLightFlattenable, IncrementLightRefBaseFlattenable, @@ -210,6 +217,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 modifyEnum(TestEnum a, TestEnum* b) const = 0; virtual status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const = 0; virtual status_t increment(const TestLightFlattenable& a, TestLightFlattenable* aPlusOne) const = 0; @@ -246,6 +254,10 @@ public: ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA); } + status_t modifyEnum(TestEnum a, TestEnum* b) const override { + ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); + return callRemote<decltype(&ISafeInterfaceTest::modifyEnum)>(Tag::ModifyEnum, a, b); + } status_t increment(const TestFlattenable& a, TestFlattenable* aPlusOne) const override { using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable&, TestFlattenable*) const; @@ -339,6 +351,11 @@ public: *notA = !a; return NO_ERROR; } + status_t modifyEnum(TestEnum a, TestEnum* b) const override { + ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); + *b = (a == TestEnum::INITIAL) ? TestEnum::FINAL : TestEnum::INVALID; + 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; @@ -414,6 +431,9 @@ public: case ISafeInterfaceTest::Tag::LogicalNot: { return callLocal(data, reply, &ISafeInterfaceTest::logicalNot); } + case ISafeInterfaceTest::Tag::ModifyEnum: { + return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum); + } case ISafeInterfaceTest::Tag::IncrementFlattenable: { using Signature = status_t (ISafeInterfaceTest::*)(const TestFlattenable& a, TestFlattenable* aPlusOne) const; @@ -544,6 +564,14 @@ TEST_F(SafeInterfaceTest, TestLogicalNot) { ASSERT_EQ(!b, notB); } +TEST_F(SafeInterfaceTest, TestModifyEnum) { + const TestEnum a = TestEnum::INITIAL; + TestEnum b = TestEnum::INVALID; + status_t result = mSafeInterfaceTest->modifyEnum(a, &b); + ASSERT_EQ(NO_ERROR, result); + ASSERT_EQ(TestEnum::FINAL, b); +} + TEST_F(SafeInterfaceTest, TestIncrementFlattenable) { const TestFlattenable a{1}; TestFlattenable aPlusOne{0}; |