CPP: added enforceNoDataAvail()

After deserialization of parameters during an AIDL call and before
calling the implementation,  check that there's no bytes left to read on
the parcel.

More details can be found at go/safer-parcel.

Bug: 208509444
Test: aidl_integration_test
Change-Id: Ic7bda3d3773b348c957981d4447f987bebccfa57
diff --git a/Android.bp b/Android.bp
index c272347..a6e9b63 100644
--- a/Android.bp
+++ b/Android.bp
@@ -312,6 +312,7 @@
 filegroup {
     name: "libaidl-integration-cpp-java-test-files",
     srcs: [
+        "tests/android/aidl/tests/BadParcelable.aidl",
         "tests/android/aidl/tests/ICppJavaTests.aidl",
         "tests/android/aidl/tests/SimpleParcelable.aidl",
     ],
@@ -358,6 +359,7 @@
     srcs: [
         ":libaidl-integration-test-files",
         ":libaidl-integration-cpp-java-test-files",
+        "tests/bad_parcelable.cpp",
         "tests/simple_parcelable.cpp",
     ],
 }
@@ -485,6 +487,7 @@
         "tests/android/aidl/tests/extension/*.aidl",
         "tests/android/aidl/tests/nested/*.aidl",
         "tests/android/aidl/tests/unions/*.aidl",
+        "tests/java/src/android/aidl/tests/BadParcelable.java",
         "tests/java/src/android/aidl/tests/SimpleParcelable.java",
         "tests/java/src/android/aidl/tests/generic/Pair.java",
     ],
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index eee6a25..8aecd1a 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -494,6 +494,13 @@
     out << GenLogBeforeExecute(bn_name, method, true /* isServer */, false /* isNdk */);
   }
 
+  if (!method.GetArguments().empty() && options.GetMinSdkVersion() >= SDK_VERSION_Tiramisu) {
+    out << "if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {\n";
+    out << "  _aidl_ret_status = st.writeToParcel(_aidl_reply);\n";
+    out << "  break;\n";
+    out << "}\n";
+  }
+
   // Call the actual method.  This is implemented by the subclass.
   out.Write("%s %s(%s(%s));\n", kBinderStatusLiteral, kStatusVarName, method.GetName().c_str(),
             GenerateArgList(typenames, method, /*for_declaration=*/false, /*type_name_only=*/false)
diff --git a/options.cpp b/options.cpp
index 3148a64..b9878b8 100644
--- a/options.cpp
+++ b/options.cpp
@@ -195,9 +195,9 @@
 
 static const std::map<std::string, uint32_t> codeNameToVersion = {
     {"S", 31},
-    {"Tiramisu", 10000},
+    {"Tiramisu", SDK_VERSION_Tiramisu},
     // this is an alias for the latest in-development platform version
-    {"current", 10000},
+    {"current", SDK_VERSION_current},
     // this is an alias for use of all APIs, including those not in any API surface
     {"platform_apis", 10001},
 };
diff --git a/options.h b/options.h
index 2394395..064b805 100644
--- a/options.h
+++ b/options.h
@@ -38,6 +38,9 @@
 constexpr uint32_t DEFAULT_SDK_VERSION_NDK = 29;
 constexpr uint32_t DEFAULT_SDK_VERSION_RUST = 31;
 
+constexpr uint32_t SDK_VERSION_current = 10000;
+constexpr uint32_t SDK_VERSION_Tiramisu = SDK_VERSION_current;
+
 // A simple wrapper around ostringstream. This is just to make Options class
 // copiable by the implicit copy constructor. If ostingstream is not wrapped,
 // the implcit copy constructor is not generated because ostringstream isn't
diff --git a/tests/aidl_test_client_parcelables.cpp b/tests/aidl_test_client_parcelables.cpp
index bb95da4..8cd5f06 100644
--- a/tests/aidl_test_client_parcelables.cpp
+++ b/tests/aidl_test_client_parcelables.cpp
@@ -29,7 +29,9 @@
 using android::IInterface;
 using android::sp;
 using android::String16;
+using android::String8;
 using android::aidl::fixedsizearray::FixedSizeArrayExample;
+using android::aidl::tests::BadParcelable;
 using android::aidl::tests::ConstantExpressionEnum;
 using android::aidl::tests::GenericStructuredParcelable;
 using android::aidl::tests::INamedCallback;
@@ -57,6 +59,24 @@
 using std::string;
 using std::vector;
 
+TEST_F(AidlTest, BadParcelable) {
+  if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
+
+  BadParcelable output;
+  {
+    BadParcelable bad(/*bad=*/true, "Booya", 42);
+    Status status = cpp_java_tests->RepeatBadParcelable(bad, &output);
+    ASSERT_FALSE(status.isOk());
+    EXPECT_EQ(status.exceptionCode(), Status::Exception::EX_BAD_PARCELABLE);
+  }
+  {
+    BadParcelable not_bad(/*bad=*/false, "Booya", 42);
+    Status status = cpp_java_tests->RepeatBadParcelable(not_bad, &output);
+    ASSERT_TRUE(status.isOk());
+    EXPECT_EQ(not_bad, output);
+  }
+}
+
 TEST_F(AidlTest, RepeatSimpleParcelable) {
   if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
 
diff --git a/tests/aidl_test_service.cpp b/tests/aidl_test_service.cpp
index 3956d0b..f000372 100644
--- a/tests/aidl_test_service.cpp
+++ b/tests/aidl_test_service.cpp
@@ -87,6 +87,7 @@
 
 // Generated code:
 using android::aidl::tests::BackendType;
+using android::aidl::tests::BadParcelable;
 using android::aidl::tests::BnCppJavaTests;
 using android::aidl::tests::BnNamedCallback;
 using android::aidl::tests::BnNewName;
@@ -183,6 +184,11 @@
   CppJavaTests() = default;
   ~CppJavaTests() = default;
 
+  Status RepeatBadParcelable(const BadParcelable& input, BadParcelable* _aidl_return) override {
+    *_aidl_return = input;
+    return Status::ok();
+  }
+
   Status RepeatSimpleParcelable(const SimpleParcelable& input, SimpleParcelable* repeat,
                                 SimpleParcelable* _aidl_return) override {
     ALOGI("Repeated a SimpleParcelable %s", input.toString().c_str());
diff --git a/tests/android/aidl/tests/BadParcelable.aidl b/tests/android/aidl/tests/BadParcelable.aidl
new file mode 100644
index 0000000..3fc6ed5
--- /dev/null
+++ b/tests/android/aidl/tests/BadParcelable.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.aidl.tests;
+
+parcelable BadParcelable cpp_header "tests/bad_parcelable.h";
diff --git a/tests/android/aidl/tests/ICppJavaTests.aidl b/tests/android/aidl/tests/ICppJavaTests.aidl
index 8b38101..243d110 100644
--- a/tests/android/aidl/tests/ICppJavaTests.aidl
+++ b/tests/android/aidl/tests/ICppJavaTests.aidl
@@ -16,6 +16,7 @@
 
 package android.aidl.tests;
 
+import android.aidl.tests.BadParcelable;
 import android.aidl.tests.GenericStructuredParcelable;
 import android.aidl.tests.IntEnum;
 import android.aidl.tests.SimpleParcelable;
@@ -25,6 +26,8 @@
 
 // Tests that are only supported by the C++/Java backends, not NDK/Rust
 interface ICppJavaTests {
+    BadParcelable RepeatBadParcelable(in BadParcelable input);
+
     SimpleParcelable RepeatSimpleParcelable(in SimpleParcelable input, out SimpleParcelable repeat);
     GenericStructuredParcelable<int, StructuredParcelable, IntEnum> RepeatGenericParcelable(
             in GenericStructuredParcelable<int, StructuredParcelable, IntEnum> input,
diff --git a/tests/bad_parcelable.cpp b/tests/bad_parcelable.cpp
new file mode 100644
index 0000000..36ca727
--- /dev/null
+++ b/tests/bad_parcelable.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 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 "tests/bad_parcelable.h"
+
+#include <android-base/stringprintf.h>
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+using android::base::StringPrintf;
+
+namespace android {
+namespace aidl {
+namespace tests {
+
+BadParcelable::BadParcelable(bool bad, const std::string& name, int32_t number)
+    : bad_(bad), name_(name.c_str(), name.length()), number_(number) {}
+
+status_t BadParcelable::writeToParcel(Parcel* parcel) const {
+  if (auto status = parcel->writeBool(bad_); status != OK) return status;
+  if (auto status = parcel->writeString16(name_); status != OK) return status;
+  if (auto status = parcel->writeInt32(number_); status != OK) return status;
+  // BAD! write superfluous data
+  if (bad_) parcel->writeInt32(42);
+  return OK;
+}
+
+status_t BadParcelable::readFromParcel(const Parcel* parcel) {
+  if (auto status = parcel->readBool(&bad_); status != OK) return status;
+  if (auto status = parcel->readString16(&name_); status != OK) return status;
+  if (auto status = parcel->readInt32(&number_); status != OK) return status;
+  return OK;
+}
+
+std::string BadParcelable::toString() const {
+  return StringPrintf("BadParcelable{bad=%d,name=%s,number=%d}", bad_, String8(name_).string(),
+                      number_);
+}
+
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/tests/bad_parcelable.h b/tests/bad_parcelable.h
new file mode 100644
index 0000000..3dcc9bf
--- /dev/null
+++ b/tests/bad_parcelable.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <string>
+
+#include <binder/Parcelable.h>
+#include <utils/Errors.h>
+#include <utils/String16.h>
+
+namespace android {
+namespace aidl {
+namespace tests {
+
+class BadParcelable : public Parcelable {
+ public:
+  BadParcelable() = default;
+  BadParcelable(bool bad, const std::string& name, int32_t number);
+  virtual ~BadParcelable() = default;
+
+  status_t writeToParcel(Parcel* parcel) const override;
+  status_t readFromParcel(const Parcel* parcel) override;
+
+  std::string toString() const;
+
+  friend bool operator==(const BadParcelable& lhs, const BadParcelable& rhs) {
+    return (lhs.bad_ == rhs.bad_) && (lhs.name_ == rhs.name_) && (lhs.number_ == rhs.number_);
+  }
+  friend bool operator!=(const BadParcelable& lhs, const BadParcelable& rhs) {
+    return !(lhs == rhs);
+  }
+
+ private:
+  bool bad_;
+  String16 name_;
+  int32_t number_ = 0;
+};  // class BadParcelable
+
+}  // namespace tests
+}  // namespace aidl
+}  // namespace android
diff --git a/tests/golden_output/aidl-test-fixedsizearray-cpp-source/gen/android/aidl/fixedsizearray/FixedSizeArrayExample.cpp b/tests/golden_output/aidl-test-fixedsizearray-cpp-source/gen/android/aidl/fixedsizearray/FixedSizeArrayExample.cpp
index 3ae7885..11eae08 100644
--- a/tests/golden_output/aidl-test-fixedsizearray-cpp-source/gen/android/aidl/fixedsizearray/FixedSizeArrayExample.cpp
+++ b/tests/golden_output/aidl-test-fixedsizearray-cpp-source/gen/android/aidl/fixedsizearray/FixedSizeArrayExample.cpp
@@ -1068,6 +1068,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatBytes(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -1099,6 +1103,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatInts(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -1130,6 +1138,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatBinders(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -1161,6 +1173,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatParcelables(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -1192,6 +1208,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(Repeat2dBytes(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -1223,6 +1243,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(Repeat2dInts(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -1254,6 +1278,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(Repeat2dBinders(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -1285,6 +1313,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(Repeat2dParcelables(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ArrayOfInterfaces.cpp b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ArrayOfInterfaces.cpp
index 2116483..7c54f2e 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ArrayOfInterfaces.cpp
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ArrayOfInterfaces.cpp
@@ -251,6 +251,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(methodWithInterfaces(in_iface, in_nullable_iface, in_iface_array_in, &out_iface_array_out, &in_iface_array_inout, in_nullable_iface_array_in, &out_nullable_iface_array_out, &in_nullable_iface_array_inout, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ITestService.cpp b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ITestService.cpp
index 11b743a..f660e87 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ITestService.cpp
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ITestService.cpp
@@ -2629,6 +2629,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(UnimplementedMethod(in_arg, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2680,6 +2684,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatBoolean(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2706,6 +2714,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatByte(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2732,6 +2744,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatChar(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2758,6 +2774,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatInt(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2784,6 +2804,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatLong(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2810,6 +2834,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatFloat(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2836,6 +2864,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatDouble(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2862,6 +2894,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatString(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2888,6 +2924,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatByteEnum(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2914,6 +2954,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatIntEnum(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2940,6 +2984,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatLongEnum(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -2971,6 +3019,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseBoolean(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3006,6 +3058,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseByte(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3041,6 +3097,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseChar(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3076,6 +3136,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseInt(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3111,6 +3175,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseLong(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3146,6 +3214,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseFloat(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3181,6 +3253,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseDouble(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3216,6 +3292,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseString(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3251,6 +3331,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseByteEnum(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3286,6 +3370,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseIntEnum(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3321,6 +3409,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseLongEnum(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3351,6 +3443,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(GetOtherTestService(in_name, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3382,6 +3478,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(VerifyName(in_service, in_name, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3408,6 +3508,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(GetInterfaceArray(in_names, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3439,6 +3543,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(VerifyNamesWithInterfaceArray(in_services, in_names, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3465,6 +3573,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(GetNullableInterfaceArray(in_names, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3496,6 +3608,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(VerifyNamesWithNullableInterfaceArray(in_services, in_names, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3522,6 +3638,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(GetInterfaceList(in_names, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3553,6 +3673,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(VerifyNamesWithInterfaceList(in_services, in_names, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3580,6 +3704,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseStringList(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3610,6 +3738,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatParcelFileDescriptor(in_read, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3641,6 +3773,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseParcelFileDescriptorArray(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3670,6 +3806,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ThrowServiceException(in_code));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3692,6 +3832,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableIntArray(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3718,6 +3862,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableByteEnumArray(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3744,6 +3892,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableIntEnumArray(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3770,6 +3922,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableLongEnumArray(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3796,6 +3952,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableString(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3822,6 +3982,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableStringList(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3848,6 +4012,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableParcelable(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3874,6 +4042,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableParcelableArray(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3900,6 +4072,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableParcelableList(in_input, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3925,6 +4101,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(TakesAnIBinder(in_input));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3946,6 +4126,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(TakesANullableIBinder(in_input));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3967,6 +4151,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(TakesAnIBinderList(in_input));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -3988,6 +4176,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(TakesANullableIBinderList(in_input));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4010,6 +4202,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatUtf8CppString(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4036,6 +4232,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatNullableUtf8CppString(in_token, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4067,6 +4267,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseUtf8CppString(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4102,6 +4306,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseNullableUtf8CppString(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4133,6 +4341,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseUtf8CppStringList(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4163,6 +4375,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(GetCallback(in_return_null, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4188,6 +4404,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(FillOutStructuredParcelable(&in_parcel));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4214,6 +4434,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(RepeatExtendableParcelable(in_ep, &out_ep2));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4240,6 +4464,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseList(in_list, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4271,6 +4499,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseIBinderArray(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -4306,6 +4538,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(ReverseNullableIBinderArray(in_input, &out_repeated, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ListOfInterfaces.cpp b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ListOfInterfaces.cpp
index d787f45..1ab8acb 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ListOfInterfaces.cpp
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/ListOfInterfaces.cpp
@@ -235,6 +235,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(methodWithInterfaces(in_iface, in_nullable_iface, in_iface_list_in, &out_iface_list_out, &in_iface_list_inout, in_nullable_iface_list_in, &out_nullable_iface_list_out, &in_nullable_iface_list_inout, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
diff --git a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/nested/INestedService.cpp b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/nested/INestedService.cpp
index 805f67e..5a2352a 100644
--- a/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/nested/INestedService.cpp
+++ b/tests/golden_output/aidl-test-interface-cpp-source/gen/android/aidl/tests/nested/INestedService.cpp
@@ -130,6 +130,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(flipStatus(in_p, &_aidl_return));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -160,6 +164,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(flipStatusWithCallback(in_status, in_cb));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
@@ -318,6 +326,10 @@
     if (((_aidl_ret_status) != (::android::OK))) {
       break;
     }
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(done(in_status));
     _aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
     if (((_aidl_ret_status) != (::android::OK))) {
diff --git a/tests/golden_output/aidl_test_loggable_interface-cpp-source/gen/android/aidl/loggable/ILoggableInterface.cpp b/tests/golden_output/aidl_test_loggable_interface-cpp-source/gen/android/aidl/loggable/ILoggableInterface.cpp
index 2c9e3bf..85d9a52 100644
--- a/tests/golden_output/aidl_test_loggable_interface-cpp-source/gen/android/aidl/loggable/ILoggableInterface.cpp
+++ b/tests/golden_output/aidl_test_loggable_interface-cpp-source/gen/android/aidl/loggable/ILoggableInterface.cpp
@@ -395,6 +395,10 @@
       _transaction_log.input_args.emplace_back("in_pfdArray", ::android::internal::ToString(in_pfdArray));
     }
     auto _log_start = std::chrono::steady_clock::now();
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(LogThis(in_boolValue, &in_boolArray, in_byteValue, &in_byteArray, in_charValue, &in_charArray, in_intValue, &in_intArray, in_longValue, &in_longArray, in_floatValue, &in_floatArray, in_doubleValue, &in_doubleArray, in_stringValue, &in_stringArray, &in_listValue, in_dataValue, in_binderValue, &in_pfdValue, &in_pfdArray, &_aidl_return));
     if (BnLoggableInterface::logFunc != nullptr) {
       auto _log_end = std::chrono::steady_clock::now();
@@ -610,6 +614,10 @@
       _transaction_log.input_args.emplace_back("in_value", ::android::internal::ToString(in_value));
     }
     auto _log_start = std::chrono::steady_clock::now();
+    if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {
+      _aidl_ret_status = st.writeToParcel(_aidl_reply);
+      break;
+    }
     ::android::binder::Status _aidl_status(Log(in_value));
     if (ILoggableInterface::BnSub::logFunc != nullptr) {
       auto _log_end = std::chrono::steady_clock::now();
diff --git a/tests/java/src/android/aidl/service/TestServiceServer.java b/tests/java/src/android/aidl/service/TestServiceServer.java
index b42c716..0b012d3 100644
--- a/tests/java/src/android/aidl/service/TestServiceServer.java
+++ b/tests/java/src/android/aidl/service/TestServiceServer.java
@@ -17,6 +17,7 @@
 package android.aidl.service;
 
 import android.aidl.tests.BackendType;
+import android.aidl.tests.BadParcelable;
 import android.aidl.tests.ByteEnum;
 import android.aidl.tests.ConstantExpressionEnum;
 import android.aidl.tests.GenericStructuredParcelable;
@@ -588,6 +589,10 @@
 
   class MyCppJavaTests extends ICppJavaTests.Stub {
     @Override
+    public BadParcelable RepeatBadParcelable(BadParcelable input) throws RemoteException {
+      return input;
+    }
+    @Override
     public SimpleParcelable RepeatSimpleParcelable(SimpleParcelable input, SimpleParcelable repeat)
         throws RemoteException {
       repeat.set(input.getName(), input.getNumber());
diff --git a/tests/java/src/android/aidl/tests/BadParcelable.java b/tests/java/src/android/aidl/tests/BadParcelable.java
new file mode 100644
index 0000000..077fbf5
--- /dev/null
+++ b/tests/java/src/android/aidl/tests/BadParcelable.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021, 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.
+ */
+
+package android.aidl.tests;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class BadParcelable implements Parcelable {
+  private boolean mBad;
+  private String mName;
+  private int mNumber;
+
+  BadParcelable() {}
+  BadParcelable(boolean bad, String name, int number) {
+    this.mBad = bad;
+    this.mName = name;
+    this.mNumber = number;
+  }
+
+  public int describeContents() { return 0; }
+
+  public void writeToParcel(Parcel dest, int flags) {
+    dest.writeBoolean(mBad);
+    dest.writeString(mName);
+    dest.writeInt(mNumber);
+    // BAD! write superfluous data
+    if (mBad) {
+      dest.writeInt(42);
+    }
+  }
+
+  public void readFromParcel(Parcel source) {
+    mBad = source.readBoolean();
+    mName = source.readString();
+    mNumber = source.readInt();
+  }
+
+  public boolean equals(Object o) {
+    if (o == null) {
+      return false;
+    }
+    if (!(o instanceof BadParcelable)) {
+      return false;
+    }
+    BadParcelable p = (BadParcelable) o;
+    if (mBad != p.mBad) {
+      return false;
+    }
+    if ((mName == null && p.mName != null) || (mName != null && !mName.equals(p.mName))) {
+      return false;
+    }
+    return mNumber == p.mNumber;
+  }
+
+  public String toString() {
+    return "BadParcelable(bad=" + mBad + ",name=" + mName + ",number=" + mNumber + "}";
+  }
+
+  public static final Parcelable.Creator<BadParcelable> CREATOR =
+      new Parcelable.Creator<BadParcelable>() {
+        public BadParcelable createFromParcel(Parcel source) {
+          BadParcelable p = new BadParcelable();
+          p.readFromParcel(source);
+          return p;
+        }
+
+        public BadParcelable[] newArray(int size) { return new BadParcelable[size]; }
+      };
+}
diff --git a/tests/java/src/android/aidl/tests/TestServiceClient.java b/tests/java/src/android/aidl/tests/TestServiceClient.java
index 451b603..822509a 100644
--- a/tests/java/src/android/aidl/tests/TestServiceClient.java
+++ b/tests/java/src/android/aidl/tests/TestServiceClient.java
@@ -22,9 +22,11 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assume.assumeTrue;
 
+import android.aidl.tests.BadParcelable;
 import android.aidl.tests.ByteEnum;
 import android.aidl.tests.GenericStructuredParcelable;
 import android.aidl.tests.INamedCallback;
@@ -38,6 +40,7 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.os.BadParcelableException;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
@@ -347,6 +350,19 @@
     }
 
     @Test
+    public void testBadParcelable() throws RemoteException {
+      assumeTrue(cpp_java_tests != null);
+      BadParcelable bad = new BadParcelable(/*bad=*/true, "foo", 42);
+      Throwable error =
+          assertThrows(BadParcelableException.class, () -> cpp_java_tests.RepeatBadParcelable(bad));
+      assertTrue(error.getMessage().contains("Parcel data not fully consumed"));
+
+      BadParcelable notBad = new BadParcelable(/*bad=*/false, "foo", 42);
+      BadParcelable output = cpp_java_tests.RepeatBadParcelable(notBad);
+      assertThat(notBad, is(output));
+    }
+
+    @Test
     public void testRepeatParcelable() throws RemoteException {
         assumeTrue(cpp_java_tests != null);