libbinder: Add vector<Parcelable> to SafeInterface

Adds support fo sending and receiving std::vector<Parcelable>
parameters (such as the vector of OccupancyTracker::Segments in
IGraphicBufferConsumer::getOccupancyHistory) as part of a SafeInterface.

Test: New test in binderSafeInterfaceTest
Change-Id: Ifb7d2cece79ee9fd52791f61d2488e6a490805f3
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index 4d9cacb..6a16e24 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -127,6 +127,24 @@
     int32_t value = 0;
 };
 
+class TestParcelable : public Parcelable {
+public:
+    TestParcelable() = default;
+    explicit TestParcelable(int32_t value) : mValue(value) {}
+    TestParcelable(const TestParcelable& other) : TestParcelable(other.mValue) {}
+    TestParcelable(TestParcelable&& other) : TestParcelable(other.mValue) {}
+
+    // Parcelable interface
+    status_t writeToParcel(Parcel* parcel) const override { return parcel->writeInt32(mValue); }
+    status_t readFromParcel(const Parcel* parcel) override { return parcel->readInt32(&mValue); }
+
+    int32_t getValue() const { return mValue; }
+    void setValue(int32_t value) { mValue = value; }
+
+private:
+    int32_t mValue = 0;
+};
+
 class ExitOnDeath : public IBinder::DeathRecipient {
 public:
     ~ExitOnDeath() override = default;
@@ -204,6 +222,7 @@
         IncrementLightRefBaseFlattenable,
         IncrementNativeHandle,
         IncrementNoCopyNoMove,
+        IncrementParcelableVector,
         ToUpper,
         CallMeBack,
         IncrementInt32,
@@ -231,6 +250,8 @@
                                sp<TestLightRefBaseFlattenable>* aPlusOne) const = 0;
     virtual status_t increment(const sp<NativeHandle>& a, sp<NativeHandle>* aPlusOne) const = 0;
     virtual status_t increment(const NoCopyNoMove& a, NoCopyNoMove* aPlusOne) const = 0;
+    virtual status_t increment(const std::vector<TestParcelable>& a,
+                               std::vector<TestParcelable>* aPlusOne) const = 0;
     virtual status_t toUpper(const String8& str, String8* upperStr) const = 0;
     // As mentioned above, sp<IBinder> is already tested by setDeathToken
     virtual void callMeBack(const sp<ICallback>& callback, int32_t a) const = 0;
@@ -296,6 +317,13 @@
                                                            NoCopyNoMove* aPlusOne) const;
         return callRemote<Signature>(Tag::IncrementNoCopyNoMove, a, aPlusOne);
     }
+    status_t increment(const std::vector<TestParcelable>& a,
+                       std::vector<TestParcelable>* aPlusOne) const override {
+        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
+        using Signature = status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
+                                                           std::vector<TestParcelable>*);
+        return callRemote<Signature>(Tag::IncrementParcelableVector, a, aPlusOne);
+    }
     status_t toUpper(const String8& str, String8* upperStr) const override {
         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
         return callRemote<decltype(&ISafeInterfaceTest::toUpper)>(Tag::ToUpper, str, upperStr);
@@ -407,6 +435,15 @@
         aPlusOne->setValue(a.getValue() + 1);
         return NO_ERROR;
     }
+    status_t increment(const std::vector<TestParcelable>& a,
+                       std::vector<TestParcelable>* aPlusOne) const override {
+        ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
+        aPlusOne->resize(a.size());
+        for (size_t i = 0; i < a.size(); ++i) {
+            (*aPlusOne)[i].setValue(a[i].getValue() + 1);
+        }
+        return NO_ERROR;
+    }
     status_t toUpper(const String8& str, String8* upperStr) const override {
         ALOG(LOG_INFO, getLogTag(), "%s", __PRETTY_FUNCTION__);
         *upperStr = str;
@@ -490,6 +527,12 @@
                                                                    NoCopyNoMove* aPlusOne) const;
                 return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
             }
+            case ISafeInterfaceTest::Tag::IncrementParcelableVector: {
+                using Signature =
+                        status_t (ISafeInterfaceTest::*)(const std::vector<TestParcelable>&,
+                                                         std::vector<TestParcelable>*) const;
+                return callLocal<Signature>(data, reply, &ISafeInterfaceTest::increment);
+            }
             case ISafeInterfaceTest::Tag::ToUpper: {
                 return callLocal(data, reply, &ISafeInterfaceTest::toUpper);
             }
@@ -680,6 +723,16 @@
     ASSERT_EQ(a.getValue() + 1, aPlusOne.getValue());
 }
 
+TEST_F(SafeInterfaceTest, TestIncremementParcelableVector) {
+    const std::vector<TestParcelable> a{TestParcelable{1}, TestParcelable{2}};
+    std::vector<TestParcelable> aPlusOne;
+    status_t result = mSafeInterfaceTest->increment(a, &aPlusOne);
+    ASSERT_EQ(a.size(), aPlusOne.size());
+    for (size_t i = 0; i < a.size(); ++i) {
+        ASSERT_EQ(a[i].getValue() + 1, aPlusOne[i].getValue());
+    }
+}
+
 TEST_F(SafeInterfaceTest, TestToUpper) {
     const String8 str{"Hello, world!"};
     String8 upperStr;