libbinder: Status writeOverParcel

For errors written to the parcel late.

Bug: 211823183
Test: aidl_integration_test
Change-Id: I036a016e143408bf1c3cb4f67f622c7e0dac91bf
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index a44c578..83b97d0 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -211,6 +211,12 @@
     return status;
 }
 
+status_t Status::writeOverParcel(Parcel* parcel) const {
+    parcel->setDataSize(0);
+    parcel->setDataPosition(0);
+    return writeToParcel(parcel);
+}
+
 void Status::setException(int32_t ex, const String8& message) {
     mException = ex;
     mErrorCode = ex == EX_TRANSACTION_FAILED ? FAILED_TRANSACTION : NO_ERROR;
diff --git a/libs/binder/include/binder/Status.h b/libs/binder/include/binder/Status.h
index aaafa36..af34695 100644
--- a/libs/binder/include/binder/Status.h
+++ b/libs/binder/include/binder/Status.h
@@ -117,6 +117,10 @@
     status_t readFromParcel(const Parcel& parcel);
     status_t writeToParcel(Parcel* parcel) const;
 
+    // Convenience API to replace a Parcel with a status value, w/o requiring
+    // calling multiple APIs (makes generated code smaller).
+    status_t writeOverParcel(Parcel* parcel) const;
+
     // Set one of the pre-defined exception types defined above.
     void setException(int32_t ex, const String8& message);
     // Set a service specific exception with error code.
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 5e5c495..2ce00b2 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -98,6 +98,7 @@
     srcs: [
         "binderParcelUnitTest.cpp",
         "binderBinderUnitTest.cpp",
+        "binderStatusUnitTest.cpp",
     ],
     shared_libs: [
         "libbinder",
diff --git a/libs/binder/tests/binderStatusUnitTest.cpp b/libs/binder/tests/binderStatusUnitTest.cpp
new file mode 100644
index 0000000..a32ec5c
--- /dev/null
+++ b/libs/binder/tests/binderStatusUnitTest.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/Parcel.h>
+#include <binder/Status.h>
+#include <gtest/gtest.h>
+
+using android::Parcel;
+using android::binder::Status;
+
+TEST(Status, WriteOverParcel) {
+    Status status = Status::fromExceptionCode(Status::EX_NULL_POINTER);
+
+    Parcel indirect;
+    indirect.writeInt32(64);
+    status.writeOverParcel(&indirect);
+
+    Parcel direct;
+    status.writeToParcel(&direct);
+
+    EXPECT_EQ(0, indirect.compareData(direct));
+}