Loading libs/binder/include/binder/SafeInterface.h +8 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,14 @@ public: return callParcel("writeParcelableVector", [&]() { return parcel->writeParcelableVector(v); }); } status_t read(const Parcel& parcel, std::vector<bool>* v) const { return callParcel("readBoolVector", [&]() { return parcel.readBoolVector(v); }); } status_t write(Parcel* parcel, const std::vector<bool>& v) const { return callParcel("writeBoolVector", [&]() { return parcel->writeBoolVector(v); }); } status_t read(const Parcel& parcel, float* f) const { return callParcel("readFloat", [&]() { return parcel.readFloat(f); }); } Loading libs/binder/tests/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -731,6 +731,9 @@ cc_test { "liblog", "libutils", ], static_libs: [ "libgmock", ], test_suites: [ "general-tests", "vts", Loading libs/binder/tests/binderSafeInterfaceTest.cpp +36 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,8 @@ #include <sys/eventfd.h> #include <sys/prctl.h> #include <gmock/gmock.h> using namespace std::chrono_literals; // NOLINT - google-build-using-namespace using android::binder::unique_fd; Loading Loading @@ -222,6 +224,7 @@ public: SetDeathToken = IBinder::FIRST_CALL_TRANSACTION, ReturnsNoMemory, LogicalNot, LogicalNotVector, ModifyEnum, IncrementFlattenable, IncrementLightFlattenable, Loading Loading @@ -249,6 +252,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 logicalNot(const std::vector<bool>& a, std::vector<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, Loading Loading @@ -288,7 +292,14 @@ public: } status_t logicalNot(bool a, bool* notA) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA); using Signature = status_t (ISafeInterfaceTest::*)(bool, bool*) const; return callRemote<Signature>(Tag::LogicalNot, a, notA); } status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>&, std::vector<bool>*) const; return callRemote<Signature>(Tag::LogicalNotVector, a, notA); } status_t modifyEnum(TestEnum a, TestEnum* b) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); Loading Loading @@ -406,6 +417,14 @@ public: *notA = !a; return NO_ERROR; } status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); notA->clear(); for (bool value : a) { notA->push_back(!value); } 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; Loading Loading @@ -513,7 +532,13 @@ public: return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory); } case ISafeInterfaceTest::Tag::LogicalNot: { return callLocal(data, reply, &ISafeInterfaceTest::logicalNot); using Signature = status_t (ISafeInterfaceTest::*)(bool a, bool* notA) const; return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot); } case ISafeInterfaceTest::Tag::LogicalNotVector: { using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>& a, std::vector<bool>* notA) const; return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot); } case ISafeInterfaceTest::Tag::ModifyEnum: { return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum); Loading Loading @@ -639,6 +664,15 @@ TEST_F(SafeInterfaceTest, TestLogicalNot) { ASSERT_EQ(!b, notB); } TEST_F(SafeInterfaceTest, TestLogicalNotVector) { const std::vector<bool> a = {true, false, true}; std::vector<bool> notA; status_t result = mSafeInterfaceTest->logicalNot(a, ¬A); ASSERT_EQ(NO_ERROR, result); std::vector<bool> expected = {false, true, false}; ASSERT_THAT(notA, testing::ContainerEq(expected)); } TEST_F(SafeInterfaceTest, TestModifyEnum) { const TestEnum a = TestEnum::INITIAL; TestEnum b = TestEnum::INVALID; Loading Loading
libs/binder/include/binder/SafeInterface.h +8 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,14 @@ public: return callParcel("writeParcelableVector", [&]() { return parcel->writeParcelableVector(v); }); } status_t read(const Parcel& parcel, std::vector<bool>* v) const { return callParcel("readBoolVector", [&]() { return parcel.readBoolVector(v); }); } status_t write(Parcel* parcel, const std::vector<bool>& v) const { return callParcel("writeBoolVector", [&]() { return parcel->writeBoolVector(v); }); } status_t read(const Parcel& parcel, float* f) const { return callParcel("readFloat", [&]() { return parcel.readFloat(f); }); } Loading
libs/binder/tests/Android.bp +3 −0 Original line number Diff line number Diff line Loading @@ -731,6 +731,9 @@ cc_test { "liblog", "libutils", ], static_libs: [ "libgmock", ], test_suites: [ "general-tests", "vts", Loading
libs/binder/tests/binderSafeInterfaceTest.cpp +36 −2 Original line number Diff line number Diff line Loading @@ -40,6 +40,8 @@ #include <sys/eventfd.h> #include <sys/prctl.h> #include <gmock/gmock.h> using namespace std::chrono_literals; // NOLINT - google-build-using-namespace using android::binder::unique_fd; Loading Loading @@ -222,6 +224,7 @@ public: SetDeathToken = IBinder::FIRST_CALL_TRANSACTION, ReturnsNoMemory, LogicalNot, LogicalNotVector, ModifyEnum, IncrementFlattenable, IncrementLightFlattenable, Loading Loading @@ -249,6 +252,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 logicalNot(const std::vector<bool>& a, std::vector<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, Loading Loading @@ -288,7 +292,14 @@ public: } status_t logicalNot(bool a, bool* notA) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); return callRemote<decltype(&ISafeInterfaceTest::logicalNot)>(Tag::LogicalNot, a, notA); using Signature = status_t (ISafeInterfaceTest::*)(bool, bool*) const; return callRemote<Signature>(Tag::LogicalNot, a, notA); } status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>&, std::vector<bool>*) const; return callRemote<Signature>(Tag::LogicalNotVector, a, notA); } status_t modifyEnum(TestEnum a, TestEnum* b) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); Loading Loading @@ -406,6 +417,14 @@ public: *notA = !a; return NO_ERROR; } status_t logicalNot(const std::vector<bool>& a, std::vector<bool>* notA) const override { ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__); notA->clear(); for (bool value : a) { notA->push_back(!value); } 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; Loading Loading @@ -513,7 +532,13 @@ public: return callLocal(data, reply, &ISafeInterfaceTest::returnsNoMemory); } case ISafeInterfaceTest::Tag::LogicalNot: { return callLocal(data, reply, &ISafeInterfaceTest::logicalNot); using Signature = status_t (ISafeInterfaceTest::*)(bool a, bool* notA) const; return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot); } case ISafeInterfaceTest::Tag::LogicalNotVector: { using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<bool>& a, std::vector<bool>* notA) const; return callLocal<Signature>(data, reply, &ISafeInterfaceTest::logicalNot); } case ISafeInterfaceTest::Tag::ModifyEnum: { return callLocal(data, reply, &ISafeInterfaceTest::modifyEnum); Loading Loading @@ -639,6 +664,15 @@ TEST_F(SafeInterfaceTest, TestLogicalNot) { ASSERT_EQ(!b, notB); } TEST_F(SafeInterfaceTest, TestLogicalNotVector) { const std::vector<bool> a = {true, false, true}; std::vector<bool> notA; status_t result = mSafeInterfaceTest->logicalNot(a, ¬A); ASSERT_EQ(NO_ERROR, result); std::vector<bool> expected = {false, true, false}; ASSERT_THAT(notA, testing::ContainerEq(expected)); } TEST_F(SafeInterfaceTest, TestModifyEnum) { const TestEnum a = TestEnum::INITIAL; TestEnum b = TestEnum::INVALID; Loading