blob: 8a1b23f01880155289bb3c8a0829caa721f83265 [file] [log] [blame]
/*
* Copyright (C) 2015, 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 <string>
#include <android-base/stringprintf.h>
#include <gtest/gtest.h>
#include "aidl.h"
#include "aidl_language.h"
#include "ast_cpp.h"
#include "code_writer.h"
#include "generate_cpp.h"
#include "os.h"
#include "tests/fake_io_delegate.h"
#include "tests/test_util.h"
using ::android::aidl::test::FakeIoDelegate;
using ::android::base::StringPrintf;
using std::string;
using std::unique_ptr;
namespace android {
namespace aidl {
namespace cpp {
namespace {
// clang-format off
const string kComplexTypeInterfaceAIDL =
R"(package android.os;
import foo.IFooType;
interface IComplexTypeInterface {
const int MY_CONSTANT = 3;
int[] Send(in @nullable int[] goes_in, inout double[] goes_in_and_out, out boolean[] goes_out);
oneway void Piff(int times);
IFooType TakesABinder(IFooType f);
@nullable IFooType NullableBinder();
List<String> StringListMethod(in java.util.List<String> input, out List<String> output);
List<IBinder> BinderListMethod(in java.util.List<IBinder> input, out List<IBinder> output);
FileDescriptor TakesAFileDescriptor(in FileDescriptor f);
FileDescriptor[] TakesAFileDescriptorArray(in FileDescriptor[] f);
})";
const char kExpectedComplexTypeClientHeaderOutput[] =
R"(#pragma once
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <utils/Errors.h>
#include <android/os/IComplexTypeInterface.h>
namespace android {
namespace os {
class BpComplexTypeInterface : public ::android::BpInterface<IComplexTypeInterface> {
public:
explicit BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl);
virtual ~BpComplexTypeInterface() = default;
::android::binder::Status Send(const ::std::optional<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) override;
::android::binder::Status Piff(int32_t times) override;
::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) override;
::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) override;
::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) override;
::android::binder::Status BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) override;
::android::binder::Status TakesAFileDescriptor(::android::base::unique_fd f, ::android::base::unique_fd* _aidl_return) override;
::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) override;
}; // class BpComplexTypeInterface
} // namespace os
} // namespace android
)";
const char kExpectedComplexTypeClientSourceOutput[] =
R"(#include <android/os/BpComplexTypeInterface.h>
#include <android/os/BnComplexTypeInterface.h>
#include <binder/Parcel.h>
#include <android-base/macros.h>
namespace android {
namespace os {
BpComplexTypeInterface::BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl)
: BpInterface<IComplexTypeInterface>(_aidl_impl){
}
::android::binder::Status BpComplexTypeInterface::Send(const ::std::optional<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeInt32Vector(goes_in);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeDoubleVector(*goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeVectorSize(*goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_Send, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->Send(goes_in, goes_in_and_out, goes_out, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readInt32Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readDoubleVector(goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readBoolVector(goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::Piff(int32_t times) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeInt32(times);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_Piff, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->Piff(times);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeStrongBinder(::foo::IFooType::asBinder(f));
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_TakesABinder, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->TakesABinder(f, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_NullableBinder, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->NullableBinder(_aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeString16Vector(input);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_StringListMethod, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->StringListMethod(input, output, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readString16Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readString16Vector(output);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeStrongBinderVector(input);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_BinderListMethod, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->BinderListMethod(input, output, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readStrongBinderVector(output);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptor(::android::base::unique_fd f, ::android::base::unique_fd* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeUniqueFileDescriptor(f);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptor, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->TakesAFileDescriptor(std::move(f), _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readUniqueFileDescriptor(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeUniqueFileDescriptorVector(f);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptorArray, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->TakesAFileDescriptorArray(f, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readUniqueFileDescriptorVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
} // namespace os
} // namespace android
)";
const char kExpectedComplexTypeClientWithTraceSourceOutput[] =
R"(#include <android/os/BpComplexTypeInterface.h>
#include <android/os/BnComplexTypeInterface.h>
#include <binder/Parcel.h>
#include <android-base/macros.h>
namespace android {
namespace os {
BpComplexTypeInterface::BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl)
: BpInterface<IComplexTypeInterface>(_aidl_impl){
}
::android::binder::Status BpComplexTypeInterface::Send(const ::std::optional<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::Send::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeInt32Vector(goes_in);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeDoubleVector(*goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeVectorSize(*goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_Send, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->Send(goes_in, goes_in_and_out, goes_out, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readInt32Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readDoubleVector(goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readBoolVector(goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::Piff(int32_t times) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::Piff::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeInt32(times);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_Piff, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->Piff(times);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::TakesABinder::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeStrongBinder(::foo::IFooType::asBinder(f));
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_TakesABinder, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->TakesABinder(f, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::NullableBinder::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_NullableBinder, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->NullableBinder(_aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::StringListMethod::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeString16Vector(input);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_StringListMethod, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->StringListMethod(input, output, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readString16Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readString16Vector(output);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::BinderListMethod::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeStrongBinderVector(input);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_BinderListMethod, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->BinderListMethod(input, output, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_reply.readStrongBinderVector(output);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptor(::android::base::unique_fd f, ::android::base::unique_fd* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::TakesAFileDescriptor::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeUniqueFileDescriptor(f);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptor, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->TakesAFileDescriptor(std::move(f), _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readUniqueFileDescriptor(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) {
::android::Parcel _aidl_data;
::android::Parcel _aidl_reply;
::android::status_t _aidl_ret_status = ::android::OK;
::android::binder::Status _aidl_status;
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::TakesAFileDescriptorArray::cppClient");
_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_data.writeUniqueFileDescriptorVector(f);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = remote()->transact(BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptorArray, _aidl_data, &_aidl_reply, 0);
if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IComplexTypeInterface::getDefaultImpl())) {
return IComplexTypeInterface::getDefaultImpl()->TakesAFileDescriptorArray(f, _aidl_return);
}
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
if (!_aidl_status.isOk()) {
return _aidl_status;
}
_aidl_ret_status = _aidl_reply.readUniqueFileDescriptorVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
goto _aidl_error;
}
_aidl_error:
_aidl_status.setFromStatusT(_aidl_ret_status);
return _aidl_status;
}
} // namespace os
} // namespace android
)";
const char kExpectedComplexTypeServerHeaderOutput[] =
R"(#pragma once
#include <binder/IInterface.h>
#include <android/os/IComplexTypeInterface.h>
namespace android {
namespace os {
class BnComplexTypeInterface : public ::android::BnInterface<IComplexTypeInterface> {
public:
static constexpr uint32_t TRANSACTION_Send = ::android::IBinder::FIRST_CALL_TRANSACTION + 0;
static constexpr uint32_t TRANSACTION_Piff = ::android::IBinder::FIRST_CALL_TRANSACTION + 1;
static constexpr uint32_t TRANSACTION_TakesABinder = ::android::IBinder::FIRST_CALL_TRANSACTION + 2;
static constexpr uint32_t TRANSACTION_NullableBinder = ::android::IBinder::FIRST_CALL_TRANSACTION + 3;
static constexpr uint32_t TRANSACTION_StringListMethod = ::android::IBinder::FIRST_CALL_TRANSACTION + 4;
static constexpr uint32_t TRANSACTION_BinderListMethod = ::android::IBinder::FIRST_CALL_TRANSACTION + 5;
static constexpr uint32_t TRANSACTION_TakesAFileDescriptor = ::android::IBinder::FIRST_CALL_TRANSACTION + 6;
static constexpr uint32_t TRANSACTION_TakesAFileDescriptorArray = ::android::IBinder::FIRST_CALL_TRANSACTION + 7;
explicit BnComplexTypeInterface();
::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) override;
}; // class BnComplexTypeInterface
} // namespace os
} // namespace android
)";
const char kExpectedComplexTypeServerSourceOutput[] =
R"(#include <android/os/BnComplexTypeInterface.h>
#include <binder/Parcel.h>
#include <binder/Stability.h>
namespace android {
namespace os {
BnComplexTypeInterface::BnComplexTypeInterface()
{
::android::internal::Stability::markCompilationUnit(this);
}
::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
case BnComplexTypeInterface::TRANSACTION_Send:
{
::std::optional<::std::vector<int32_t>> in_goes_in;
::std::vector<double> in_goes_in_and_out;
::std::vector<bool> out_goes_out;
::std::vector<int32_t> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readInt32Vector(&in_goes_in);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_data.readDoubleVector(&in_goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_data.resizeOutVector(&out_goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(Send(in_goes_in, &in_goes_in_and_out, &out_goes_out, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeInt32Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeDoubleVector(in_goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeBoolVector(out_goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_Piff:
{
int32_t in_times;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readInt32(&in_times);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(Piff(in_times));
}
break;
case BnComplexTypeInterface::TRANSACTION_TakesABinder:
{
::android::sp<::foo::IFooType> in_f;
::android::sp<::foo::IFooType> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readStrongBinder(&in_f);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(TakesABinder(in_f, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_NullableBinder:
{
::android::sp<::foo::IFooType> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::binder::Status _aidl_status(NullableBinder(&_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_StringListMethod:
{
::std::vector<::android::String16> in_input;
::std::vector<::android::String16> out_output;
::std::vector<::android::String16> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readString16Vector(&in_input);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(StringListMethod(in_input, &out_output, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeString16Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeString16Vector(out_output);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_BinderListMethod:
{
::std::vector<::android::sp<::android::IBinder>> in_input;
::std::vector<::android::sp<::android::IBinder>> out_output;
::std::vector<::android::sp<::android::IBinder>> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readStrongBinderVector(&in_input);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(BinderListMethod(in_input, &out_output, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinderVector(out_output);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptor:
{
::android::base::unique_fd in_f;
::android::base::unique_fd _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readUniqueFileDescriptor(&in_f);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(TakesAFileDescriptor(std::move(in_f), &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptor(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptorArray:
{
::std::vector<::android::base::unique_fd> in_f;
::std::vector<::android::base::unique_fd> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
_aidl_ret_status = _aidl_data.readUniqueFileDescriptorVector(&in_f);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(TakesAFileDescriptorArray(in_f, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptorVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
default:
{
_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
}
break;
}
if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
}
return _aidl_ret_status;
}
} // namespace os
} // namespace android
)";
const char kExpectedComplexTypeServerWithTraceSourceOutput[] =
R"(#include <android/os/BnComplexTypeInterface.h>
#include <binder/Parcel.h>
#include <binder/Stability.h>
namespace android {
namespace os {
BnComplexTypeInterface::BnComplexTypeInterface()
{
::android::internal::Stability::markCompilationUnit(this);
}
::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) {
::android::status_t _aidl_ret_status = ::android::OK;
switch (_aidl_code) {
case BnComplexTypeInterface::TRANSACTION_Send:
{
::std::optional<::std::vector<int32_t>> in_goes_in;
::std::vector<double> in_goes_in_and_out;
::std::vector<bool> out_goes_out;
::std::vector<int32_t> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::Send::cppServer");
_aidl_ret_status = _aidl_data.readInt32Vector(&in_goes_in);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_data.readDoubleVector(&in_goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_data.resizeOutVector(&out_goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(Send(in_goes_in, &in_goes_in_and_out, &out_goes_out, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeInt32Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeDoubleVector(in_goes_in_and_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeBoolVector(out_goes_out);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_Piff:
{
int32_t in_times;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::Piff::cppServer");
_aidl_ret_status = _aidl_data.readInt32(&in_times);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(Piff(in_times));
}
break;
case BnComplexTypeInterface::TRANSACTION_TakesABinder:
{
::android::sp<::foo::IFooType> in_f;
::android::sp<::foo::IFooType> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::TakesABinder::cppServer");
_aidl_ret_status = _aidl_data.readStrongBinder(&in_f);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(TakesABinder(in_f, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_NullableBinder:
{
::android::sp<::foo::IFooType> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::NullableBinder::cppServer");
::android::binder::Status _aidl_status(NullableBinder(&_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_StringListMethod:
{
::std::vector<::android::String16> in_input;
::std::vector<::android::String16> out_output;
::std::vector<::android::String16> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::StringListMethod::cppServer");
_aidl_ret_status = _aidl_data.readString16Vector(&in_input);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(StringListMethod(in_input, &out_output, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeString16Vector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeString16Vector(out_output);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_BinderListMethod:
{
::std::vector<::android::sp<::android::IBinder>> in_input;
::std::vector<::android::sp<::android::IBinder>> out_output;
::std::vector<::android::sp<::android::IBinder>> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::BinderListMethod::cppServer");
_aidl_ret_status = _aidl_data.readStrongBinderVector(&in_input);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(BinderListMethod(in_input, &out_output, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
_aidl_ret_status = _aidl_reply->writeStrongBinderVector(out_output);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptor:
{
::android::base::unique_fd in_f;
::android::base::unique_fd _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::TakesAFileDescriptor::cppServer");
_aidl_ret_status = _aidl_data.readUniqueFileDescriptor(&in_f);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(TakesAFileDescriptor(std::move(in_f), &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptor(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
case BnComplexTypeInterface::TRANSACTION_TakesAFileDescriptorArray:
{
::std::vector<::android::base::unique_fd> in_f;
::std::vector<::android::base::unique_fd> _aidl_return;
if (!(_aidl_data.checkInterface(this))) {
_aidl_ret_status = ::android::BAD_TYPE;
break;
}
::android::ScopedTrace _aidl_trace(ATRACE_TAG_AIDL, "AIDL::cpp::IComplexTypeInterface::TakesAFileDescriptorArray::cppServer");
_aidl_ret_status = _aidl_data.readUniqueFileDescriptorVector(&in_f);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
::android::binder::Status _aidl_status(TakesAFileDescriptorArray(in_f, &_aidl_return));
_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
if (!_aidl_status.isOk()) {
break;
}
_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptorVector(_aidl_return);
if (((_aidl_ret_status) != (::android::OK))) {
break;
}
}
break;
default:
{
_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
}
break;
}
if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
}
return _aidl_ret_status;
}
} // namespace os
} // namespace android
)";
const char kExpectedComplexTypeInterfaceHeaderOutput[] =
R"(#pragma once
#include <android-base/unique_fd.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
#include <binder/Status.h>
#include <cstdint>
#include <foo/IFooType.h>
#include <optional>
#include <utils/String16.h>
#include <utils/StrongPointer.h>
#include <vector>
namespace android {
namespace os {
class IComplexTypeInterface : public ::android::IInterface {
public:
DECLARE_META_INTERFACE(ComplexTypeInterface)
enum : int32_t {
MY_CONSTANT = 3,
};
virtual ::android::binder::Status Send(const ::std::optional<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) = 0;
virtual ::android::binder::Status Piff(int32_t times) = 0;
virtual ::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) = 0;
virtual ::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) = 0;
virtual ::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) = 0;
virtual ::android::binder::Status BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) = 0;
virtual ::android::binder::Status TakesAFileDescriptor(::android::base::unique_fd f, ::android::base::unique_fd* _aidl_return) = 0;
virtual ::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) = 0;
}; // class IComplexTypeInterface
class IComplexTypeInterfaceDefault : public IComplexTypeInterface {
public:
::android::IBinder* onAsBinder() override {
return nullptr;
}
::android::binder::Status Send(const ::std::optional<::std::vector<int32_t>>&, ::std::vector<double>*, ::std::vector<bool>*, ::std::vector<int32_t>*) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
::android::binder::Status Piff(int32_t) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>&, ::android::sp<::foo::IFooType>*) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>*) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
::android::binder::Status StringListMethod(const ::std::vector<::android::String16>&, ::std::vector<::android::String16>*, ::std::vector<::android::String16>*) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
::android::binder::Status BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>&, ::std::vector<::android::sp<::android::IBinder>>*, ::std::vector<::android::sp<::android::IBinder>>*) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
::android::binder::Status TakesAFileDescriptor(::android::base::unique_fd, ::android::base::unique_fd*) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>&, ::std::vector<::android::base::unique_fd>*) override {
return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);
}
}; // class IComplexTypeInterfaceDefault
} // namespace os
} // namespace android
)";
const char kExpectedComplexTypeInterfaceSourceOutput[] =
R"(#include <android/os/IComplexTypeInterface.h>
#include <android/os/BpComplexTypeInterface.h>
namespace android {
namespace os {
DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(ComplexTypeInterface, "android.os.IComplexTypeInterface")
} // namespace os
} // namespace android
)";
const string kEnumAIDL = R"(package android.os;
enum TestEnum {
ZERO,
ONE,
THREE = 3,
FOUR = 3 + 1,
FIVE,
SIX,
SEVEN,
EIGHT = 16 / 2,
NINE,
TEN,
})";
const char kExpectedEnumHeaderOutput[] =
R"(#pragma once
#include <array>
#include <binder/Enums.h>
#include <cstdint>
#include <string>
namespace android {
namespace os {
enum class TestEnum : int8_t {
ZERO = 0,
ONE = 1,
THREE = 3,
FOUR = 4,
FIVE = 5,
SIX = 6,
SEVEN = 7,
EIGHT = 8,
NINE = 9,
TEN = 10,
};
static inline std::string toString(TestEnum val) {
switch(val) {
case TestEnum::ZERO:
return "ZERO";
case TestEnum::ONE:
return "ONE";
case TestEnum::THREE:
return "THREE";
case TestEnum::FOUR:
return "FOUR";
case TestEnum::FIVE:
return "FIVE";
case TestEnum::SIX:
return "SIX";
case TestEnum::SEVEN:
return "SEVEN";
case TestEnum::EIGHT:
return "EIGHT";
case TestEnum::NINE:
return "NINE";
case TestEnum::TEN:
return "TEN";
default:
return std::to_string(static_cast<int8_t>(val));
}
}
} // namespace os
} // namespace android
namespace android {
namespace internal {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++17-extensions"
template <>
constexpr inline std::array<::android::os::TestEnum, 10> enum_values<::android::os::TestEnum> = {
::android::os::TestEnum::ZERO,
::android::os::TestEnum::ONE,
::android::os::TestEnum::THREE,
::android::os::TestEnum::FOUR,
::android::os::TestEnum::FIVE,
::android::os::TestEnum::SIX,
::android::os::TestEnum::SEVEN,
::android::os::TestEnum::EIGHT,
::android::os::TestEnum::NINE,
::android::os::TestEnum::TEN,
};
#pragma clang diagnostic pop
} // namespace internal
} // namespace android
)";
const string kEnumWithBackingTypeAIDL = R"(package android.os;
@Backing(type="long")
enum TestEnum {
FOO = 1,
BAR = 2,
})";
const char kExpectedEnumWithBackingTypeHeaderOutput[] =
R"(#pragma once
#include <array>
#include <binder/Enums.h>
#include <cstdint>
#include <string>
namespace android {
namespace os {
enum class TestEnum : int64_t {
FOO = 1L,
BAR = 2L,
};
static inline std::string toString(TestEnum val) {
switch(val) {
case TestEnum::FOO:
return "FOO";
case TestEnum::BAR:
return "BAR";
default:
return std::to_string(static_cast<int64_t>(val));
}
}
} // namespace os
} // namespace android
namespace android {
namespace internal {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wc++17-extensions"
template <>
constexpr inline std::array<::android::os::TestEnum, 2> enum_values<::android::os::TestEnum> = {
::android::os::TestEnum::FOO,
::android::os::TestEnum::BAR,
};
#pragma clang diagnostic pop
} // namespace internal
} // namespace android
)";
// clang-format on
} // namespace
class ASTTest : public ::testing::Test {
protected:
ASTTest(const string& cmdline, const string& file_contents)
: options_(Options::From(cmdline)), file_contents_(file_contents) {
}
AidlInterface* ParseSingleInterface() {
io_delegate_.SetFileContents(options_.InputFiles().at(0), file_contents_);
vector<string> imported_files;
ImportResolver import_resolver{io_delegate_, options_.InputFiles().at(0), {"."}, {}};
AidlError err = ::android::aidl::internals::load_and_validate_aidl(
options_.InputFiles().front(), options_, io_delegate_, &typenames_, &imported_files);
if (err != AidlError::OK) {
return nullptr;
}
const auto& defined_types = typenames_.MainDocument().DefinedTypes();
EXPECT_EQ(1ul, defined_types.size());
EXPECT_NE(nullptr, defined_types.front().get()->AsInterface());
return defined_types.front().get()->AsInterface();
}
AidlEnumDeclaration* ParseSingleEnumDeclaration() {
io_delegate_.SetFileContents(options_.InputFiles().at(0), file_contents_);
vector<string> imported_files;
AidlError err = ::android::aidl::internals::load_and_validate_aidl(
options_.InputFiles().front(), options_, io_delegate_, &typenames_, &imported_files);
if (err != AidlError::OK) {
return nullptr;
}
const auto& defined_types = typenames_.MainDocument().DefinedTypes();
EXPECT_EQ(1ul, defined_types.size());
EXPECT_NE(nullptr, defined_types.front().get()->AsEnumDeclaration());
return defined_types.front().get()->AsEnumDeclaration();
}
void Compare(Document* doc, const char* expected) {
string output;
doc->Write(CodeWriter::ForString(&output).get());
if (expected == output) {
return; // Success
}
test::PrintDiff(expected, output);
FAIL() << "Document contents did not match expected contents";
}
const Options options_;
const string file_contents_;
FakeIoDelegate io_delegate_;
AidlTypenames typenames_;
};
class ComplexTypeInterfaceASTTest : public ASTTest {
public:
ComplexTypeInterfaceASTTest()
: ASTTest("aidl --lang=cpp -I . -o out android/os/IComplexTypeInterface.aidl",
kComplexTypeInterfaceAIDL) {
io_delegate_.SetFileContents("foo/IFooType.aidl",
"package foo; interface IFooType {}");
}
};
TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildClientHeader(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildClientSource(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeClientSourceOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildServerHeader(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildServerSource(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeServerSourceOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildInterfaceHeader(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput);
}
TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildInterfaceSource(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput);
}
class ComplexTypeInterfaceASTTestWithTrace : public ASTTest {
public:
ComplexTypeInterfaceASTTestWithTrace()
: ASTTest("aidl --lang=cpp -t -I . -o out android/os/IComplexTypeInterface.aidl",
kComplexTypeInterfaceAIDL) {
io_delegate_.SetFileContents("foo/IFooType.aidl", "package foo; interface IFooType {}");
}
};
TEST_F(ComplexTypeInterfaceASTTestWithTrace, GeneratesClientSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildClientSource(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeClientWithTraceSourceOutput);
}
TEST_F(ComplexTypeInterfaceASTTestWithTrace, GeneratesServerSource) {
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
unique_ptr<Document> doc = internals::BuildServerSource(typenames_, *interface, options_);
Compare(doc.get(), kExpectedComplexTypeServerWithTraceSourceOutput);
}
namespace test_io_handling {
const char kInputPath[] = "a/IFoo.aidl";
const char kOutputPath[] = "output.cpp";
const char kHeaderDir[] = "headers";
const char kInterfaceHeaderRelPath[] = "a/IFoo.h";
const string kCmdline = string("aidl-cpp ") + kInputPath + " " + kHeaderDir + " " + kOutputPath;
} // namespace test_io_handling
class IoErrorHandlingTest : public ASTTest {
public:
IoErrorHandlingTest() : ASTTest(test_io_handling::kCmdline, "package a; interface IFoo {}") {}
};
TEST_F(IoErrorHandlingTest, GenerateCorrectlyAbsentErrors) {
// Confirm that this is working correctly without I/O problems.
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
ASSERT_TRUE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
}
TEST_F(IoErrorHandlingTest, HandlesBadHeaderWrite) {
using namespace test_io_handling;
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
// Simulate issues closing the interface header.
const string header_path =
StringPrintf("%s%c%s", kHeaderDir, OS_PATH_SEPARATOR,
kInterfaceHeaderRelPath);
io_delegate_.AddBrokenFilePath(header_path);
ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
// We should never attempt to write the C++ file if we fail writing headers.
ASSERT_FALSE(io_delegate_.GetWrittenContents(kOutputPath, nullptr));
// We should remove partial results.
ASSERT_TRUE(io_delegate_.PathWasRemoved(header_path));
}
TEST_F(IoErrorHandlingTest, HandlesBadCppWrite) {
using test_io_handling::kOutputPath;
AidlInterface* interface = ParseSingleInterface();
ASSERT_NE(interface, nullptr);
// Simulate issues closing the cpp file.
io_delegate_.AddBrokenFilePath(kOutputPath);
ASSERT_FALSE(GenerateCpp(options_.OutputFile(), options_, typenames_, *interface, io_delegate_));
// We should remove partial results.
ASSERT_TRUE(io_delegate_.PathWasRemoved(kOutputPath));
}
class EnumASTTest : public ASTTest {
public:
EnumASTTest() : ASTTest("aidl --lang=cpp -I . -o out android/os/TestEnum.aidl", kEnumAIDL) {}
};
TEST_F(EnumASTTest, GeneratesEnumHeader) {
AidlEnumDeclaration* enum_decl = ParseSingleEnumDeclaration();
ASSERT_NE(enum_decl, nullptr);
unique_ptr<Document> doc = internals::BuildEnumHeader(typenames_, *enum_decl);
Compare(doc.get(), kExpectedEnumHeaderOutput);
}
class EnumWithBackingTypeASTTest : public ASTTest {
public:
EnumWithBackingTypeASTTest()
: ASTTest("aidl --lang=cpp -I . -o out android/os/TestEnum.aidl", kEnumWithBackingTypeAIDL) {}
};
TEST_F(EnumWithBackingTypeASTTest, GeneratesEnumHeader) {
AidlEnumDeclaration* enum_decl = ParseSingleEnumDeclaration();
ASSERT_NE(enum_decl, nullptr);
unique_ptr<Document> doc = internals::BuildEnumHeader(typenames_, *enum_decl);
Compare(doc.get(), kExpectedEnumWithBackingTypeHeaderOutput);
}
} // namespace cpp
} // namespace aidl
} // namespace android