Snap for 8479861 from b069a9a31a6c35833c3782b9a2f282a5dc8e0cae to tm-qpr1-release

Change-Id: I4959142373eb1dc52f45b0a89d99810057ef1e99
diff --git a/Android.bp b/Android.bp
index c795969..08df261 100644
--- a/Android.bp
+++ b/Android.bp
@@ -442,6 +442,7 @@
         "libbinder_ndk",
     ],
     srcs: [
+        "tests/aidl_test_client_ndk_delegate.cpp",
         "tests/aidl_test_client_ndk_loggable_interface.cpp",
         "tests/aidl_test_client_ndk_nested.cpp",
         "tests/aidl_test_client_ndk_nullables.cpp",
diff --git a/generate_ndk.cpp b/generate_ndk.cpp
index e3db352..4345a74 100644
--- a/generate_ndk.cpp
+++ b/generate_ndk.cpp
@@ -288,7 +288,7 @@
         includes.insert("chrono");
         includes.insert("sstream");
       }
-      // For nested interfacees client/server classes are defined in the same header.
+      // For nested interfaces client/server classes are defined in the same header.
       // So we need includes for client/server class as well.
       if (interface.GetParentType()) {
         includes.insert("android/binder_ibinder.h");
@@ -985,6 +985,59 @@
   LeaveNdkNamespace(out, defined_type);
 }
 
+void GenerateDelegatorClassDecl(CodeWriter& out, const AidlTypenames& types,
+                                const AidlInterface& defined_type, const Options& options) {
+  const std::string clazz = ClassName(defined_type, ClassNames::DELEGATOR_IMPL);
+  const std::string iface = ClassName(defined_type, ClassNames::INTERFACE);
+  const std::string bn_name = ClassName(defined_type, ClassNames::SERVER);
+  const std::string kDelegateImplVarName = "_impl";
+  const std::string kStatusType = "::ndk::ScopedAStatus";
+
+  out << "class";
+  cpp::GenerateDeprecated(out, defined_type);
+  out << " " << clazz << " : public " << bn_name << " {\n";
+  out << "public:\n";
+  out.Indent();
+  out << "explicit " << clazz << "(const std::shared_ptr<" << iface << "> &impl)"
+      << " : " << kDelegateImplVarName << "(impl) {\n";
+  if (options.Version() > 0) {
+    // TODO(b/222347502) If we need to support mismatched versions of delegator and
+    // impl, this check will be removed. The NDK backend can't override the
+    // getInterface* meta methods because they are marked "final". Removing
+    // "final" changes the ABI and breaks prebuilts.
+    out << "   int32_t _impl_ver = 0;\n";
+    out << "   if (!impl->" << kGetInterfaceVersion << "(&_impl_ver).isOk()) {;\n";
+    out << "      __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, \"Delegator failed to get "
+           "version of the implementation.\");\n";
+    out << "   }\n";
+    out << "   if (_impl_ver != " << iface << "::" << kVersion << ") {\n";
+    out << "      __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, \"Mismatched versions of "
+           "delegator and implementation is not allowed.\");\n";
+    out << "   }\n";
+  }
+  out << "}\n\n";
+  for (const auto& method : defined_type.GetMethods()) {
+    if (method->IsUserDefined()) {
+      out << kStatusType << " " << method->GetName() << "("
+          << NdkArgList(types, *method, FormatArgForDecl) << ") override";
+      cpp::GenerateDeprecated(out, *method);
+      out << " {\n"
+          << "  return " << kDelegateImplVarName << "->" << method->GetName() << "("
+          << NdkArgList(types, *method, FormatArgNameOnly) << ");\n";
+      out << "}\n";
+    }
+  }
+  out.Dedent();
+  out << "protected:\n";
+  out.Indent();
+  out.Dedent();
+  out << "private:\n";
+  out.Indent();
+  out << "std::shared_ptr<" << iface << "> " << kDelegateImplVarName << ";\n";
+  out.Dedent();
+  out << "};\n\n";
+}
+
 void GenerateServerClassDecl(CodeWriter& out, const AidlTypenames& types,
                              const AidlInterface& defined_type, const Options& options) {
   const std::string clazz = ClassName(defined_type, ClassNames::SERVER);
@@ -1033,9 +1086,18 @@
       << "\"\n";
   out << "\n";
   out << "#include <android/binder_ibinder.h>\n";
+  // Needed for *Delegator classes while delegator version is required to be
+  // the same as the implementation version
+  // TODO(b/222347502) If we ever need to support mismatched versions of delegator and
+  // impl, this include can be removed.
+  out << "#include <cassert>\n\n";
+  // TODO(b/31559095) bionic on host should define __assert2
+  out << "#ifndef __BIONIC__\n#ifndef __assert2\n#define __assert2(a,b,c,d) "
+         "((void)0)\n#endif\n#endif\n";
   out << "\n";
   EnterNdkNamespace(out, defined_type);
   GenerateServerClassDecl(out, types, defined_type, options);
+  GenerateDelegatorClassDecl(out, types, defined_type, options);
   LeaveNdkNamespace(out, defined_type);
 }
 
diff --git a/tests/aidl_test_client_ndk_delegate.cpp b/tests/aidl_test_client_ndk_delegate.cpp
new file mode 100644
index 0000000..6bec01a
--- /dev/null
+++ b/tests/aidl_test_client_ndk_delegate.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2022 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 <android/binder_auto_utils.h>
+#include <android/binder_manager.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <aidl/android/aidl/tests/BnTestService.h>
+#include <android-base/logging.h>
+
+using aidl::android::aidl::tests::BackendType;
+using aidl::android::aidl::tests::ITestService;
+using aidl::android::aidl::tests::ITestServiceDelegator;
+
+static constexpr int8_t kCustomByte = 8;
+
+struct CustomDelegator : public ITestServiceDelegator {
+ public:
+  CustomDelegator(std::shared_ptr<ITestService>& impl) : ITestServiceDelegator(impl) {}
+
+  // Change RepeatByte to always return the same byte.
+  ndk::ScopedAStatus RepeatByte(int8_t /* token */, int8_t* _aidl_return) override {
+    *_aidl_return = kCustomByte;
+    return ndk::ScopedAStatus::ok();
+  }
+};
+
+struct AidlDelegatorTest : testing::Test {
+  template <typename T>
+  std::shared_ptr<T> getService() {
+    ndk::SpAIBinder binder = ndk::SpAIBinder(AServiceManager_getService(T::descriptor));
+    return T::fromBinder(binder);
+  }
+  void SetUp() override { service = getService<ITestService>(); }
+  std::shared_ptr<ITestService> service;
+};
+
+TEST_F(AidlDelegatorTest, SimpleDelegator) {
+  auto delegator = ndk::SharedRefBase::make<ITestServiceDelegator>(service);
+  int8_t returned_value;
+  auto status = delegator->RepeatByte(12, &returned_value);
+  ASSERT_TRUE(status.isOk()) << status.getMessage();
+  EXPECT_EQ(12, returned_value);
+}
+
+TEST_F(AidlDelegatorTest, CustomDelegator) {
+  auto delegator = ndk::SharedRefBase::make<CustomDelegator>(service);
+  int8_t returned_value;
+  auto status = delegator->RepeatByte(12, &returned_value);
+  ASSERT_TRUE(status.isOk()) << status.getMessage();
+  EXPECT_EQ(kCustomByte, returned_value);
+}
+
+TEST_F(AidlDelegatorTest, SendDelegator) {
+  auto delegator = ndk::SharedRefBase::make<ITestServiceDelegator>(service);
+  auto fromAsBinder = ITestServiceDelegator::fromBinder(delegator->asBinder());
+  // Make sure the delegator works after asBinder -> fromBinder conversions
+  int8_t returned_value = 0;
+  auto status = fromAsBinder->RepeatByte(12, &returned_value);
+  ASSERT_TRUE(status.isOk()) << status.getDescription();
+  EXPECT_EQ(12, returned_value);
+}
diff --git a/tests/aidl_test_client_ndk_versioned_interface.cpp b/tests/aidl_test_client_ndk_versioned_interface.cpp
index 97da834..f1d0207 100644
--- a/tests/aidl_test_client_ndk_versioned_interface.cpp
+++ b/tests/aidl_test_client_ndk_versioned_interface.cpp
@@ -72,4 +72,4 @@
   EXPECT_EQ(43, ret);
   EXPECT_EQ(0, inoutFoo.intDefault42);
   EXPECT_EQ(0, outFoo.intDefault42);
-}
\ No newline at end of file
+}
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnDeprecated.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnDeprecated.h
index 0b6f042..356e9a4 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnDeprecated.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnDeprecated.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/tests/IDeprecated.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -16,6 +23,16 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class __attribute__((deprecated("test"))) IDeprecatedDelegator : public BnDeprecated {
+public:
+  explicit IDeprecatedDelegator(const std::shared_ptr<IDeprecated> &impl) : _impl(impl) {
+  }
+
+protected:
+private:
+  std::shared_ptr<IDeprecated> _impl;
+};
+
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNamedCallback.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNamedCallback.h
index 6f38a28..fa465fa 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNamedCallback.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNamedCallback.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/tests/INamedCallback.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -16,6 +23,19 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class INamedCallbackDelegator : public BnNamedCallback {
+public:
+  explicit INamedCallbackDelegator(const std::shared_ptr<INamedCallback> &impl) : _impl(impl) {
+  }
+
+  ::ndk::ScopedAStatus GetName(std::string* _aidl_return) override {
+    return _impl->GetName(_aidl_return);
+  }
+protected:
+private:
+  std::shared_ptr<INamedCallback> _impl;
+};
+
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNewName.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNewName.h
index 32d8a7b..78fcbaa 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNewName.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnNewName.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/tests/INewName.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -16,6 +23,19 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class INewNameDelegator : public BnNewName {
+public:
+  explicit INewNameDelegator(const std::shared_ptr<INewName> &impl) : _impl(impl) {
+  }
+
+  ::ndk::ScopedAStatus RealName(std::string* _aidl_return) override {
+    return _impl->RealName(_aidl_return);
+  }
+protected:
+private:
+  std::shared_ptr<INewName> _impl;
+};
+
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnOldName.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnOldName.h
index e1782d1..e08fcc1 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnOldName.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnOldName.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/tests/IOldName.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -16,6 +23,19 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class IOldNameDelegator : public BnOldName {
+public:
+  explicit IOldNameDelegator(const std::shared_ptr<IOldName> &impl) : _impl(impl) {
+  }
+
+  ::ndk::ScopedAStatus RealName(std::string* _aidl_return) override {
+    return _impl->RealName(_aidl_return);
+  }
+protected:
+private:
+  std::shared_ptr<IOldName> _impl;
+};
+
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnTestService.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnTestService.h
index a33592b..3b5a37d 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnTestService.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/BnTestService.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/tests/ITestService.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -16,6 +23,214 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class ITestServiceDelegator : public BnTestService {
+public:
+  explicit ITestServiceDelegator(const std::shared_ptr<ITestService> &impl) : _impl(impl) {
+  }
+
+  ::ndk::ScopedAStatus UnimplementedMethod(int32_t in_arg, int32_t* _aidl_return) override {
+    return _impl->UnimplementedMethod(in_arg, _aidl_return);
+  }
+  ::ndk::ScopedAStatus Deprecated() override __attribute__((deprecated("to make sure we have something in system/tools/aidl which does a compile check of deprecated and make sure this is reflected in goldens"))) {
+    return _impl->Deprecated();
+  }
+  ::ndk::ScopedAStatus TestOneway() override {
+    return _impl->TestOneway();
+  }
+  ::ndk::ScopedAStatus RepeatBoolean(bool in_token, bool* _aidl_return) override {
+    return _impl->RepeatBoolean(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatByte(int8_t in_token, int8_t* _aidl_return) override {
+    return _impl->RepeatByte(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatChar(char16_t in_token, char16_t* _aidl_return) override {
+    return _impl->RepeatChar(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatInt(int32_t in_token, int32_t* _aidl_return) override {
+    return _impl->RepeatInt(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatLong(int64_t in_token, int64_t* _aidl_return) override {
+    return _impl->RepeatLong(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatFloat(float in_token, float* _aidl_return) override {
+    return _impl->RepeatFloat(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatDouble(double in_token, double* _aidl_return) override {
+    return _impl->RepeatDouble(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatString(const std::string& in_token, std::string* _aidl_return) override {
+    return _impl->RepeatString(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatByteEnum(::aidl::android::aidl::tests::ByteEnum in_token, ::aidl::android::aidl::tests::ByteEnum* _aidl_return) override {
+    return _impl->RepeatByteEnum(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatIntEnum(::aidl::android::aidl::tests::IntEnum in_token, ::aidl::android::aidl::tests::IntEnum* _aidl_return) override {
+    return _impl->RepeatIntEnum(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatLongEnum(::aidl::android::aidl::tests::LongEnum in_token, ::aidl::android::aidl::tests::LongEnum* _aidl_return) override {
+    return _impl->RepeatLongEnum(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseBoolean(const std::vector<bool>& in_input, std::vector<bool>* out_repeated, std::vector<bool>* _aidl_return) override {
+    return _impl->ReverseBoolean(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseByte(const std::vector<uint8_t>& in_input, std::vector<uint8_t>* out_repeated, std::vector<uint8_t>* _aidl_return) override {
+    return _impl->ReverseByte(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseChar(const std::vector<char16_t>& in_input, std::vector<char16_t>* out_repeated, std::vector<char16_t>* _aidl_return) override {
+    return _impl->ReverseChar(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseInt(const std::vector<int32_t>& in_input, std::vector<int32_t>* out_repeated, std::vector<int32_t>* _aidl_return) override {
+    return _impl->ReverseInt(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseLong(const std::vector<int64_t>& in_input, std::vector<int64_t>* out_repeated, std::vector<int64_t>* _aidl_return) override {
+    return _impl->ReverseLong(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseFloat(const std::vector<float>& in_input, std::vector<float>* out_repeated, std::vector<float>* _aidl_return) override {
+    return _impl->ReverseFloat(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseDouble(const std::vector<double>& in_input, std::vector<double>* out_repeated, std::vector<double>* _aidl_return) override {
+    return _impl->ReverseDouble(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseString(const std::vector<std::string>& in_input, std::vector<std::string>* out_repeated, std::vector<std::string>* _aidl_return) override {
+    return _impl->ReverseString(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseByteEnum(const std::vector<::aidl::android::aidl::tests::ByteEnum>& in_input, std::vector<::aidl::android::aidl::tests::ByteEnum>* out_repeated, std::vector<::aidl::android::aidl::tests::ByteEnum>* _aidl_return) override {
+    return _impl->ReverseByteEnum(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseIntEnum(const std::vector<::aidl::android::aidl::tests::IntEnum>& in_input, std::vector<::aidl::android::aidl::tests::IntEnum>* out_repeated, std::vector<::aidl::android::aidl::tests::IntEnum>* _aidl_return) override {
+    return _impl->ReverseIntEnum(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseLongEnum(const std::vector<::aidl::android::aidl::tests::LongEnum>& in_input, std::vector<::aidl::android::aidl::tests::LongEnum>* out_repeated, std::vector<::aidl::android::aidl::tests::LongEnum>* _aidl_return) override {
+    return _impl->ReverseLongEnum(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus GetOtherTestService(const std::string& in_name, std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>* _aidl_return) override {
+    return _impl->GetOtherTestService(in_name, _aidl_return);
+  }
+  ::ndk::ScopedAStatus VerifyName(const std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>& in_service, const std::string& in_name, bool* _aidl_return) override {
+    return _impl->VerifyName(in_service, in_name, _aidl_return);
+  }
+  ::ndk::ScopedAStatus GetInterfaceArray(const std::vector<std::string>& in_names, std::vector<std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>>* _aidl_return) override {
+    return _impl->GetInterfaceArray(in_names, _aidl_return);
+  }
+  ::ndk::ScopedAStatus VerifyNamesWithInterfaceArray(const std::vector<std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>>& in_services, const std::vector<std::string>& in_names, bool* _aidl_return) override {
+    return _impl->VerifyNamesWithInterfaceArray(in_services, in_names, _aidl_return);
+  }
+  ::ndk::ScopedAStatus GetNullableInterfaceArray(const std::optional<std::vector<std::optional<std::string>>>& in_names, std::optional<std::vector<std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>>>* _aidl_return) override {
+    return _impl->GetNullableInterfaceArray(in_names, _aidl_return);
+  }
+  ::ndk::ScopedAStatus VerifyNamesWithNullableInterfaceArray(const std::optional<std::vector<std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>>>& in_services, const std::optional<std::vector<std::optional<std::string>>>& in_names, bool* _aidl_return) override {
+    return _impl->VerifyNamesWithNullableInterfaceArray(in_services, in_names, _aidl_return);
+  }
+  ::ndk::ScopedAStatus GetInterfaceList(const std::optional<std::vector<std::optional<std::string>>>& in_names, std::optional<std::vector<std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>>>* _aidl_return) override {
+    return _impl->GetInterfaceList(in_names, _aidl_return);
+  }
+  ::ndk::ScopedAStatus VerifyNamesWithInterfaceList(const std::optional<std::vector<std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>>>& in_services, const std::optional<std::vector<std::optional<std::string>>>& in_names, bool* _aidl_return) override {
+    return _impl->VerifyNamesWithInterfaceList(in_services, in_names, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseStringList(const std::vector<std::string>& in_input, std::vector<std::string>* out_repeated, std::vector<std::string>* _aidl_return) override {
+    return _impl->ReverseStringList(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatParcelFileDescriptor(const ::ndk::ScopedFileDescriptor& in_read, ::ndk::ScopedFileDescriptor* _aidl_return) override {
+    return _impl->RepeatParcelFileDescriptor(in_read, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseParcelFileDescriptorArray(const std::vector<::ndk::ScopedFileDescriptor>& in_input, std::vector<::ndk::ScopedFileDescriptor>* out_repeated, std::vector<::ndk::ScopedFileDescriptor>* _aidl_return) override {
+    return _impl->ReverseParcelFileDescriptorArray(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ThrowServiceException(int32_t in_code) override {
+    return _impl->ThrowServiceException(in_code);
+  }
+  ::ndk::ScopedAStatus RepeatNullableIntArray(const std::optional<std::vector<int32_t>>& in_input, std::optional<std::vector<int32_t>>* _aidl_return) override {
+    return _impl->RepeatNullableIntArray(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableByteEnumArray(const std::optional<std::vector<::aidl::android::aidl::tests::ByteEnum>>& in_input, std::optional<std::vector<::aidl::android::aidl::tests::ByteEnum>>* _aidl_return) override {
+    return _impl->RepeatNullableByteEnumArray(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableIntEnumArray(const std::optional<std::vector<::aidl::android::aidl::tests::IntEnum>>& in_input, std::optional<std::vector<::aidl::android::aidl::tests::IntEnum>>* _aidl_return) override {
+    return _impl->RepeatNullableIntEnumArray(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableLongEnumArray(const std::optional<std::vector<::aidl::android::aidl::tests::LongEnum>>& in_input, std::optional<std::vector<::aidl::android::aidl::tests::LongEnum>>* _aidl_return) override {
+    return _impl->RepeatNullableLongEnumArray(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableString(const std::optional<std::string>& in_input, std::optional<std::string>* _aidl_return) override {
+    return _impl->RepeatNullableString(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableStringList(const std::optional<std::vector<std::optional<std::string>>>& in_input, std::optional<std::vector<std::optional<std::string>>>* _aidl_return) override {
+    return _impl->RepeatNullableStringList(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableParcelable(const std::optional<::aidl::android::aidl::tests::ITestService::Empty>& in_input, std::optional<::aidl::android::aidl::tests::ITestService::Empty>* _aidl_return) override {
+    return _impl->RepeatNullableParcelable(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableParcelableArray(const std::optional<std::vector<std::optional<::aidl::android::aidl::tests::ITestService::Empty>>>& in_input, std::optional<std::vector<std::optional<::aidl::android::aidl::tests::ITestService::Empty>>>* _aidl_return) override {
+    return _impl->RepeatNullableParcelableArray(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableParcelableList(const std::optional<std::vector<std::optional<::aidl::android::aidl::tests::ITestService::Empty>>>& in_input, std::optional<std::vector<std::optional<::aidl::android::aidl::tests::ITestService::Empty>>>* _aidl_return) override {
+    return _impl->RepeatNullableParcelableList(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus TakesAnIBinder(const ::ndk::SpAIBinder& in_input) override {
+    return _impl->TakesAnIBinder(in_input);
+  }
+  ::ndk::ScopedAStatus TakesANullableIBinder(const ::ndk::SpAIBinder& in_input) override {
+    return _impl->TakesANullableIBinder(in_input);
+  }
+  ::ndk::ScopedAStatus TakesAnIBinderList(const std::vector<::ndk::SpAIBinder>& in_input) override {
+    return _impl->TakesAnIBinderList(in_input);
+  }
+  ::ndk::ScopedAStatus TakesANullableIBinderList(const std::optional<std::vector<::ndk::SpAIBinder>>& in_input) override {
+    return _impl->TakesANullableIBinderList(in_input);
+  }
+  ::ndk::ScopedAStatus RepeatUtf8CppString(const std::string& in_token, std::string* _aidl_return) override {
+    return _impl->RepeatUtf8CppString(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus RepeatNullableUtf8CppString(const std::optional<std::string>& in_token, std::optional<std::string>* _aidl_return) override {
+    return _impl->RepeatNullableUtf8CppString(in_token, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseUtf8CppString(const std::vector<std::string>& in_input, std::vector<std::string>* out_repeated, std::vector<std::string>* _aidl_return) override {
+    return _impl->ReverseUtf8CppString(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseNullableUtf8CppString(const std::optional<std::vector<std::optional<std::string>>>& in_input, std::optional<std::vector<std::optional<std::string>>>* out_repeated, std::optional<std::vector<std::optional<std::string>>>* _aidl_return) override {
+    return _impl->ReverseNullableUtf8CppString(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseUtf8CppStringList(const std::optional<std::vector<std::optional<std::string>>>& in_input, std::optional<std::vector<std::optional<std::string>>>* out_repeated, std::optional<std::vector<std::optional<std::string>>>* _aidl_return) override {
+    return _impl->ReverseUtf8CppStringList(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus GetCallback(bool in_return_null, std::shared_ptr<::aidl::android::aidl::tests::INamedCallback>* _aidl_return) override {
+    return _impl->GetCallback(in_return_null, _aidl_return);
+  }
+  ::ndk::ScopedAStatus FillOutStructuredParcelable(::aidl::android::aidl::tests::StructuredParcelable* in_parcel) override {
+    return _impl->FillOutStructuredParcelable(in_parcel);
+  }
+  ::ndk::ScopedAStatus RepeatExtendableParcelable(const ::aidl::android::aidl::tests::extension::ExtendableParcelable& in_ep, ::aidl::android::aidl::tests::extension::ExtendableParcelable* out_ep2) override {
+    return _impl->RepeatExtendableParcelable(in_ep, out_ep2);
+  }
+  ::ndk::ScopedAStatus ReverseList(const ::aidl::android::aidl::tests::RecursiveList& in_list, ::aidl::android::aidl::tests::RecursiveList* _aidl_return) override {
+    return _impl->ReverseList(in_list, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseIBinderArray(const std::vector<::ndk::SpAIBinder>& in_input, std::vector<::ndk::SpAIBinder>* out_repeated, std::vector<::ndk::SpAIBinder>* _aidl_return) override {
+    return _impl->ReverseIBinderArray(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ReverseNullableIBinderArray(const std::optional<std::vector<::ndk::SpAIBinder>>& in_input, std::optional<std::vector<::ndk::SpAIBinder>>* out_repeated, std::optional<std::vector<::ndk::SpAIBinder>>* _aidl_return) override {
+    return _impl->ReverseNullableIBinderArray(in_input, out_repeated, _aidl_return);
+  }
+  ::ndk::ScopedAStatus GetOldNameInterface(std::shared_ptr<::aidl::android::aidl::tests::IOldName>* _aidl_return) override {
+    return _impl->GetOldNameInterface(_aidl_return);
+  }
+  ::ndk::ScopedAStatus GetNewNameInterface(std::shared_ptr<::aidl::android::aidl::tests::INewName>* _aidl_return) override {
+    return _impl->GetNewNameInterface(_aidl_return);
+  }
+  ::ndk::ScopedAStatus GetUnionTags(const std::vector<::aidl::android::aidl::tests::Union>& in_input, std::vector<::aidl::android::aidl::tests::Union::Tag>* _aidl_return) override {
+    return _impl->GetUnionTags(in_input, _aidl_return);
+  }
+  ::ndk::ScopedAStatus GetCppJavaTests(::ndk::SpAIBinder* _aidl_return) override {
+    return _impl->GetCppJavaTests(_aidl_return);
+  }
+  ::ndk::ScopedAStatus getBackendType(::aidl::android::aidl::tests::BackendType* _aidl_return) override {
+    return _impl->getBackendType(_aidl_return);
+  }
+protected:
+private:
+  std::shared_ptr<ITestService> _impl;
+};
+
 }  // namespace tests
 }  // namespace aidl
 }  // namespace android
diff --git a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/nested/BnNestedService.h b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/nested/BnNestedService.h
index 98ec330..4fc97ab 100644
--- a/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/nested/BnNestedService.h
+++ b/tests/golden_output/aidl-test-interface-ndk-source/gen/include/aidl/android/aidl/tests/nested/BnNestedService.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/tests/nested/INestedService.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -17,6 +24,22 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class INestedServiceDelegator : public BnNestedService {
+public:
+  explicit INestedServiceDelegator(const std::shared_ptr<INestedService> &impl) : _impl(impl) {
+  }
+
+  ::ndk::ScopedAStatus flipStatus(const ::aidl::android::aidl::tests::nested::ParcelableWithNested& in_p, ::aidl::android::aidl::tests::nested::INestedService::Result* _aidl_return) override {
+    return _impl->flipStatus(in_p, _aidl_return);
+  }
+  ::ndk::ScopedAStatus flipStatusWithCallback(::aidl::android::aidl::tests::nested::ParcelableWithNested::Status in_status, const std::shared_ptr<::aidl::android::aidl::tests::nested::INestedService::ICallback>& in_cb) override {
+    return _impl->flipStatusWithCallback(in_status, in_cb);
+  }
+protected:
+private:
+  std::shared_ptr<INestedService> _impl;
+};
+
 }  // namespace nested
 }  // namespace tests
 }  // namespace aidl
diff --git a/tests/golden_output/aidl-test-versioned-interface-V1-ndk-source/gen/include/aidl/android/aidl/versioned/tests/BnFooInterface.h b/tests/golden_output/aidl-test-versioned-interface-V1-ndk-source/gen/include/aidl/android/aidl/versioned/tests/BnFooInterface.h
index f464a1e..cdb26d7 100644
--- a/tests/golden_output/aidl-test-versioned-interface-V1-ndk-source/gen/include/aidl/android/aidl/versioned/tests/BnFooInterface.h
+++ b/tests/golden_output/aidl-test-versioned-interface-V1-ndk-source/gen/include/aidl/android/aidl/versioned/tests/BnFooInterface.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/versioned/tests/IFooInterface.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -19,6 +26,35 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class IFooInterfaceDelegator : public BnFooInterface {
+public:
+  explicit IFooInterfaceDelegator(const std::shared_ptr<IFooInterface> &impl) : _impl(impl) {
+     int32_t _impl_ver = 0;
+     if (!impl->getInterfaceVersion(&_impl_ver).isOk()) {;
+        __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Delegator failed to get version of the implementation.");
+     }
+     if (_impl_ver != IFooInterface::version) {
+        __assert2(__FILE__, __LINE__, __PRETTY_FUNCTION__, "Mismatched versions of delegator and implementation is not allowed.");
+     }
+  }
+
+  ::ndk::ScopedAStatus originalApi() override {
+    return _impl->originalApi();
+  }
+  ::ndk::ScopedAStatus acceptUnionAndReturnString(const ::aidl::android::aidl::versioned::tests::BazUnion& in_u, std::string* _aidl_return) override {
+    return _impl->acceptUnionAndReturnString(in_u, _aidl_return);
+  }
+  ::ndk::ScopedAStatus ignoreParcelablesAndRepeatInt(const ::aidl::android::aidl::versioned::tests::Foo& in_inFoo, ::aidl::android::aidl::versioned::tests::Foo* in_inoutFoo, ::aidl::android::aidl::versioned::tests::Foo* out_outFoo, int32_t in_value, int32_t* _aidl_return) override {
+    return _impl->ignoreParcelablesAndRepeatInt(in_inFoo, in_inoutFoo, out_outFoo, in_value, _aidl_return);
+  }
+  ::ndk::ScopedAStatus returnsLengthOfFooArray(const std::vector<::aidl::android::aidl::versioned::tests::Foo>& in_foos, int32_t* _aidl_return) override {
+    return _impl->returnsLengthOfFooArray(in_foos, _aidl_return);
+  }
+protected:
+private:
+  std::shared_ptr<IFooInterface> _impl;
+};
+
 }  // namespace tests
 }  // namespace versioned
 }  // namespace aidl
diff --git a/tests/golden_output/aidl_test_loggable_interface-ndk-source/gen/include/aidl/android/aidl/loggable/BnLoggableInterface.h b/tests/golden_output/aidl_test_loggable_interface-ndk-source/gen/include/aidl/android/aidl/loggable/BnLoggableInterface.h
index 650ca86..d6f61e1 100644
--- a/tests/golden_output/aidl_test_loggable_interface-ndk-source/gen/include/aidl/android/aidl/loggable/BnLoggableInterface.h
+++ b/tests/golden_output/aidl_test_loggable_interface-ndk-source/gen/include/aidl/android/aidl/loggable/BnLoggableInterface.h
@@ -3,6 +3,13 @@
 #include "aidl/android/aidl/loggable/ILoggableInterface.h"
 
 #include <android/binder_ibinder.h>
+#include <cassert>
+
+#ifndef __BIONIC__
+#ifndef __assert2
+#define __assert2(a,b,c,d) ((void)0)
+#endif
+#endif
 
 namespace aidl {
 namespace android {
@@ -31,6 +38,19 @@
   ::ndk::SpAIBinder createBinder() override;
 private:
 };
+class ILoggableInterfaceDelegator : public BnLoggableInterface {
+public:
+  explicit ILoggableInterfaceDelegator(const std::shared_ptr<ILoggableInterface> &impl) : _impl(impl) {
+  }
+
+  ::ndk::ScopedAStatus LogThis(bool in_boolValue, std::vector<bool>* in_boolArray, int8_t in_byteValue, std::vector<uint8_t>* in_byteArray, char16_t in_charValue, std::vector<char16_t>* in_charArray, int32_t in_intValue, std::vector<int32_t>* in_intArray, int64_t in_longValue, std::vector<int64_t>* in_longArray, float in_floatValue, std::vector<float>* in_floatArray, double in_doubleValue, std::vector<double>* in_doubleArray, const std::string& in_stringValue, std::vector<std::string>* in_stringArray, std::vector<std::string>* in_listValue, const ::aidl::android::aidl::loggable::Data& in_dataValue, const ::ndk::SpAIBinder& in_binderValue, ::ndk::ScopedFileDescriptor* in_pfdValue, std::vector<::ndk::ScopedFileDescriptor>* in_pfdArray, std::vector<std::string>* _aidl_return) override {
+    return _impl->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);
+  }
+protected:
+private:
+  std::shared_ptr<ILoggableInterface> _impl;
+};
+
 }  // namespace loggable
 }  // namespace aidl
 }  // namespace android