1/* 2 * Copyright (C) 2015, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <string> 18 19#include <android-base/stringprintf.h> 20#include <gtest/gtest.h> 21 22#include "aidl.h" 23#include "aidl_language.h" 24#include "ast_cpp.h" 25#include "code_writer.h" 26#include "generate_cpp.h" 27#include "os.h" 28#include "tests/fake_io_delegate.h" 29#include "tests/test_util.h" 30#include "type_cpp.h" 31 32using ::android::aidl::test::FakeIoDelegate; 33using ::android::base::StringPrintf; 34using std::string; 35using std::unique_ptr; 36 37namespace android { 38namespace aidl { 39namespace cpp { 40namespace { 41 42const string kComplexTypeInterfaceAIDL = 43R"(package android.os; 44import foo.IFooType; 45interface IComplexTypeInterface { 46 const int MY_CONSTANT = 3; 47 int[] Send(in @nullable int[] goes_in, inout double[] goes_in_and_out, out boolean[] goes_out); 48 oneway void Piff(int times); 49 IFooType TakesABinder(IFooType f); 50 @nullable IFooType NullableBinder(); 51 List<String> StringListMethod(in java.util.List<String> input, out List<String> output); 52 List<IBinder> BinderListMethod(in java.util.List<IBinder> input, out List<IBinder> output); 53 FileDescriptor TakesAFileDescriptor(in FileDescriptor f); 54 FileDescriptor[] TakesAFileDescriptorArray(in FileDescriptor[] f); 55})"; 56 57const char kExpectedComplexTypeClientHeaderOutput[] = 58R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_ 59#define AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_ 60 61#include <binder/IBinder.h> 62#include <binder/IInterface.h> 63#include <utils/Errors.h> 64#include <android/os/IComplexTypeInterface.h> 65 66namespace android { 67 68namespace os { 69 70class BpComplexTypeInterface : public ::android::BpInterface<IComplexTypeInterface> { 71public: 72explicit BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl); 73virtual ~BpComplexTypeInterface() = default; 74::android::binder::Status Send(const ::std::unique_ptr<::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; 75::android::binder::Status Piff(int32_t times) override; 76::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) override; 77::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) override; 78::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) override; 79::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; 80::android::binder::Status TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) override; 81::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) override; 82}; // class BpComplexTypeInterface 83 84} // namespace os 85 86} // namespace android 87 88#endif // AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_ 89)"; 90 91const char kExpectedComplexTypeClientSourceOutput[] = 92R"(#include <android/os/BpComplexTypeInterface.h> 93#include <binder/Parcel.h> 94 95namespace android { 96 97namespace os { 98 99BpComplexTypeInterface::BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl) 100 : BpInterface<IComplexTypeInterface>(_aidl_impl){ 101} 102 103::android::binder::Status BpComplexTypeInterface::Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) { 104::android::Parcel _aidl_data; 105::android::Parcel _aidl_reply; 106::android::status_t _aidl_ret_status = ::android::OK; 107::android::binder::Status _aidl_status; 108_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 109if (((_aidl_ret_status) != (::android::OK))) { 110goto _aidl_error; 111} 112_aidl_ret_status = _aidl_data.writeInt32Vector(goes_in); 113if (((_aidl_ret_status) != (::android::OK))) { 114goto _aidl_error; 115} 116_aidl_ret_status = _aidl_data.writeDoubleVector(*goes_in_and_out); 117if (((_aidl_ret_status) != (::android::OK))) { 118goto _aidl_error; 119} 120_aidl_ret_status = _aidl_data.writeVectorSize(*goes_out); 121if (((_aidl_ret_status) != (::android::OK))) { 122goto _aidl_error; 123} 124_aidl_ret_status = remote()->transact(IComplexTypeInterface::SEND, _aidl_data, &_aidl_reply); 125if (((_aidl_ret_status) != (::android::OK))) { 126goto _aidl_error; 127} 128_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 129if (((_aidl_ret_status) != (::android::OK))) { 130goto _aidl_error; 131} 132if (!_aidl_status.isOk()) { 133return _aidl_status; 134} 135_aidl_ret_status = _aidl_reply.readInt32Vector(_aidl_return); 136if (((_aidl_ret_status) != (::android::OK))) { 137goto _aidl_error; 138} 139_aidl_ret_status = _aidl_reply.readDoubleVector(goes_in_and_out); 140if (((_aidl_ret_status) != (::android::OK))) { 141goto _aidl_error; 142} 143_aidl_ret_status = _aidl_reply.readBoolVector(goes_out); 144if (((_aidl_ret_status) != (::android::OK))) { 145goto _aidl_error; 146} 147_aidl_error: 148_aidl_status.setFromStatusT(_aidl_ret_status); 149return _aidl_status; 150} 151 152::android::binder::Status BpComplexTypeInterface::Piff(int32_t times) { 153::android::Parcel _aidl_data; 154::android::Parcel _aidl_reply; 155::android::status_t _aidl_ret_status = ::android::OK; 156::android::binder::Status _aidl_status; 157_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 158if (((_aidl_ret_status) != (::android::OK))) { 159goto _aidl_error; 160} 161_aidl_ret_status = _aidl_data.writeInt32(times); 162if (((_aidl_ret_status) != (::android::OK))) { 163goto _aidl_error; 164} 165_aidl_ret_status = remote()->transact(IComplexTypeInterface::PIFF, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY); 166if (((_aidl_ret_status) != (::android::OK))) { 167goto _aidl_error; 168} 169_aidl_error: 170_aidl_status.setFromStatusT(_aidl_ret_status); 171return _aidl_status; 172} 173 174::android::binder::Status BpComplexTypeInterface::TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) { 175::android::Parcel _aidl_data; 176::android::Parcel _aidl_reply; 177::android::status_t _aidl_ret_status = ::android::OK; 178::android::binder::Status _aidl_status; 179_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 180if (((_aidl_ret_status) != (::android::OK))) { 181goto _aidl_error; 182} 183_aidl_ret_status = _aidl_data.writeStrongBinder(::foo::IFooType::asBinder(f)); 184if (((_aidl_ret_status) != (::android::OK))) { 185goto _aidl_error; 186} 187_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESABINDER, _aidl_data, &_aidl_reply); 188if (((_aidl_ret_status) != (::android::OK))) { 189goto _aidl_error; 190} 191_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 192if (((_aidl_ret_status) != (::android::OK))) { 193goto _aidl_error; 194} 195if (!_aidl_status.isOk()) { 196return _aidl_status; 197} 198_aidl_ret_status = _aidl_reply.readStrongBinder(_aidl_return); 199if (((_aidl_ret_status) != (::android::OK))) { 200goto _aidl_error; 201} 202_aidl_error: 203_aidl_status.setFromStatusT(_aidl_ret_status); 204return _aidl_status; 205} 206 207::android::binder::Status BpComplexTypeInterface::NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) { 208::android::Parcel _aidl_data; 209::android::Parcel _aidl_reply; 210::android::status_t _aidl_ret_status = ::android::OK; 211::android::binder::Status _aidl_status; 212_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 213if (((_aidl_ret_status) != (::android::OK))) { 214goto _aidl_error; 215} 216_aidl_ret_status = remote()->transact(IComplexTypeInterface::NULLABLEBINDER, _aidl_data, &_aidl_reply); 217if (((_aidl_ret_status) != (::android::OK))) { 218goto _aidl_error; 219} 220_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 221if (((_aidl_ret_status) != (::android::OK))) { 222goto _aidl_error; 223} 224if (!_aidl_status.isOk()) { 225return _aidl_status; 226} 227_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return); 228if (((_aidl_ret_status) != (::android::OK))) { 229goto _aidl_error; 230} 231_aidl_error: 232_aidl_status.setFromStatusT(_aidl_ret_status); 233return _aidl_status; 234} 235 236::android::binder::Status BpComplexTypeInterface::StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) { 237::android::Parcel _aidl_data; 238::android::Parcel _aidl_reply; 239::android::status_t _aidl_ret_status = ::android::OK; 240::android::binder::Status _aidl_status; 241_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 242if (((_aidl_ret_status) != (::android::OK))) { 243goto _aidl_error; 244} 245_aidl_ret_status = _aidl_data.writeString16Vector(input); 246if (((_aidl_ret_status) != (::android::OK))) { 247goto _aidl_error; 248} 249_aidl_ret_status = remote()->transact(IComplexTypeInterface::STRINGLISTMETHOD, _aidl_data, &_aidl_reply); 250if (((_aidl_ret_status) != (::android::OK))) { 251goto _aidl_error; 252} 253_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 254if (((_aidl_ret_status) != (::android::OK))) { 255goto _aidl_error; 256} 257if (!_aidl_status.isOk()) { 258return _aidl_status; 259} 260_aidl_ret_status = _aidl_reply.readString16Vector(_aidl_return); 261if (((_aidl_ret_status) != (::android::OK))) { 262goto _aidl_error; 263} 264_aidl_ret_status = _aidl_reply.readString16Vector(output); 265if (((_aidl_ret_status) != (::android::OK))) { 266goto _aidl_error; 267} 268_aidl_error: 269_aidl_status.setFromStatusT(_aidl_ret_status); 270return _aidl_status; 271} 272 273::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) { 274::android::Parcel _aidl_data; 275::android::Parcel _aidl_reply; 276::android::status_t _aidl_ret_status = ::android::OK; 277::android::binder::Status _aidl_status; 278_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 279if (((_aidl_ret_status) != (::android::OK))) { 280goto _aidl_error; 281} 282_aidl_ret_status = _aidl_data.writeStrongBinderVector(input); 283if (((_aidl_ret_status) != (::android::OK))) { 284goto _aidl_error; 285} 286_aidl_ret_status = remote()->transact(IComplexTypeInterface::BINDERLISTMETHOD, _aidl_data, &_aidl_reply); 287if (((_aidl_ret_status) != (::android::OK))) { 288goto _aidl_error; 289} 290_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 291if (((_aidl_ret_status) != (::android::OK))) { 292goto _aidl_error; 293} 294if (!_aidl_status.isOk()) { 295return _aidl_status; 296} 297_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return); 298if (((_aidl_ret_status) != (::android::OK))) { 299goto _aidl_error; 300} 301_aidl_ret_status = _aidl_reply.readStrongBinderVector(output); 302if (((_aidl_ret_status) != (::android::OK))) { 303goto _aidl_error; 304} 305_aidl_error: 306_aidl_status.setFromStatusT(_aidl_ret_status); 307return _aidl_status; 308} 309 310::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) { 311::android::Parcel _aidl_data; 312::android::Parcel _aidl_reply; 313::android::status_t _aidl_ret_status = ::android::OK; 314::android::binder::Status _aidl_status; 315_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 316if (((_aidl_ret_status) != (::android::OK))) { 317goto _aidl_error; 318} 319_aidl_ret_status = _aidl_data.writeUniqueFileDescriptor(f); 320if (((_aidl_ret_status) != (::android::OK))) { 321goto _aidl_error; 322} 323_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTOR, _aidl_data, &_aidl_reply); 324if (((_aidl_ret_status) != (::android::OK))) { 325goto _aidl_error; 326} 327_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 328if (((_aidl_ret_status) != (::android::OK))) { 329goto _aidl_error; 330} 331if (!_aidl_status.isOk()) { 332return _aidl_status; 333} 334_aidl_ret_status = _aidl_reply.readUniqueFileDescriptor(_aidl_return); 335if (((_aidl_ret_status) != (::android::OK))) { 336goto _aidl_error; 337} 338_aidl_error: 339_aidl_status.setFromStatusT(_aidl_ret_status); 340return _aidl_status; 341} 342 343::android::binder::Status BpComplexTypeInterface::TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) { 344::android::Parcel _aidl_data; 345::android::Parcel _aidl_reply; 346::android::status_t _aidl_ret_status = ::android::OK; 347::android::binder::Status _aidl_status; 348_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor()); 349if (((_aidl_ret_status) != (::android::OK))) { 350goto _aidl_error; 351} 352_aidl_ret_status = _aidl_data.writeUniqueFileDescriptorVector(f); 353if (((_aidl_ret_status) != (::android::OK))) { 354goto _aidl_error; 355} 356_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTORARRAY, _aidl_data, &_aidl_reply); 357if (((_aidl_ret_status) != (::android::OK))) { 358goto _aidl_error; 359} 360_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply); 361if (((_aidl_ret_status) != (::android::OK))) { 362goto _aidl_error; 363} 364if (!_aidl_status.isOk()) { 365return _aidl_status; 366} 367_aidl_ret_status = _aidl_reply.readUniqueFileDescriptorVector(_aidl_return); 368if (((_aidl_ret_status) != (::android::OK))) { 369goto _aidl_error; 370} 371_aidl_error: 372_aidl_status.setFromStatusT(_aidl_ret_status); 373return _aidl_status; 374} 375 376} // namespace os 377 378} // namespace android 379)"; 380 381const char kExpectedComplexTypeServerHeaderOutput[] = 382R"(#ifndef AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 383#define AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 384 385#include <binder/IInterface.h> 386#include <android/os/IComplexTypeInterface.h> 387 388namespace android { 389 390namespace os { 391 392class BnComplexTypeInterface : public ::android::BnInterface<IComplexTypeInterface> { 393public: 394::android::status_t onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags = 0) override; 395}; // class BnComplexTypeInterface 396 397} // namespace os 398 399} // namespace android 400 401#endif // AIDL_GENERATED_ANDROID_OS_BN_COMPLEX_TYPE_INTERFACE_H_ 402)"; 403 404const char kExpectedComplexTypeServerSourceOutput[] = 405R"(#include <android/os/BnComplexTypeInterface.h> 406#include <binder/Parcel.h> 407 408namespace android { 409 410namespace os { 411 412::android::status_t BnComplexTypeInterface::onTransact(uint32_t _aidl_code, const ::android::Parcel& _aidl_data, ::android::Parcel* _aidl_reply, uint32_t _aidl_flags) { 413::android::status_t _aidl_ret_status = ::android::OK; 414switch (_aidl_code) { 415case Call::SEND: 416{ 417::std::unique_ptr<::std::vector<int32_t>> in_goes_in; 418::std::vector<double> in_goes_in_and_out; 419::std::vector<bool> out_goes_out; 420::std::vector<int32_t> _aidl_return; 421if (!(_aidl_data.checkInterface(this))) { 422_aidl_ret_status = ::android::BAD_TYPE; 423break; 424} 425_aidl_ret_status = _aidl_data.readInt32Vector(&in_goes_in); 426if (((_aidl_ret_status) != (::android::OK))) { 427break; 428} 429_aidl_ret_status = _aidl_data.readDoubleVector(&in_goes_in_and_out); 430if (((_aidl_ret_status) != (::android::OK))) { 431break; 432} 433_aidl_ret_status = _aidl_data.resizeOutVector(&out_goes_out); 434if (((_aidl_ret_status) != (::android::OK))) { 435break; 436} 437::android::binder::Status _aidl_status(Send(in_goes_in, &in_goes_in_and_out, &out_goes_out, &_aidl_return)); 438_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); 439if (((_aidl_ret_status) != (::android::OK))) { 440break; 441} 442if (!_aidl_status.isOk()) { 443break; 444} 445_aidl_ret_status = _aidl_reply->writeInt32Vector(_aidl_return); 446if (((_aidl_ret_status) != (::android::OK))) { 447break; 448} 449_aidl_ret_status = _aidl_reply->writeDoubleVector(in_goes_in_and_out); 450if (((_aidl_ret_status) != (::android::OK))) { 451break; 452} 453_aidl_ret_status = _aidl_reply->writeBoolVector(out_goes_out); 454if (((_aidl_ret_status) != (::android::OK))) { 455break; 456} 457} 458break; 459case Call::PIFF: 460{ 461int32_t in_times; 462if (!(_aidl_data.checkInterface(this))) { 463_aidl_ret_status = ::android::BAD_TYPE; 464break; 465} 466_aidl_ret_status = _aidl_data.readInt32(&in_times); 467if (((_aidl_ret_status) != (::android::OK))) { 468break; 469} 470::android::binder::Status _aidl_status(Piff(in_times)); 471} 472break; 473case Call::TAKESABINDER: 474{ 475::android::sp<::foo::IFooType> in_f; 476::android::sp<::foo::IFooType> _aidl_return; 477if (!(_aidl_data.checkInterface(this))) { 478_aidl_ret_status = ::android::BAD_TYPE; 479break; 480} 481_aidl_ret_status = _aidl_data.readStrongBinder(&in_f); 482if (((_aidl_ret_status) != (::android::OK))) { 483break; 484} 485::android::binder::Status _aidl_status(TakesABinder(in_f, &_aidl_return)); 486_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); 487if (((_aidl_ret_status) != (::android::OK))) { 488break; 489} 490if (!_aidl_status.isOk()) { 491break; 492} 493_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return)); 494if (((_aidl_ret_status) != (::android::OK))) { 495break; 496} 497} 498break; 499case Call::NULLABLEBINDER: 500{ 501::android::sp<::foo::IFooType> _aidl_return; 502if (!(_aidl_data.checkInterface(this))) { 503_aidl_ret_status = ::android::BAD_TYPE; 504break; 505} 506::android::binder::Status _aidl_status(NullableBinder(&_aidl_return)); 507_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); 508if (((_aidl_ret_status) != (::android::OK))) { 509break; 510} 511if (!_aidl_status.isOk()) { 512break; 513} 514_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return)); 515if (((_aidl_ret_status) != (::android::OK))) { 516break; 517} 518} 519break; 520case Call::STRINGLISTMETHOD: 521{ 522::std::vector<::android::String16> in_input; 523::std::vector<::android::String16> out_output; 524::std::vector<::android::String16> _aidl_return; 525if (!(_aidl_data.checkInterface(this))) { 526_aidl_ret_status = ::android::BAD_TYPE; 527break; 528} 529_aidl_ret_status = _aidl_data.readString16Vector(&in_input); 530if (((_aidl_ret_status) != (::android::OK))) { 531break; 532} 533::android::binder::Status _aidl_status(StringListMethod(in_input, &out_output, &_aidl_return)); 534_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); 535if (((_aidl_ret_status) != (::android::OK))) { 536break; 537} 538if (!_aidl_status.isOk()) { 539break; 540} 541_aidl_ret_status = _aidl_reply->writeString16Vector(_aidl_return); 542if (((_aidl_ret_status) != (::android::OK))) { 543break; 544} 545_aidl_ret_status = _aidl_reply->writeString16Vector(out_output); 546if (((_aidl_ret_status) != (::android::OK))) { 547break; 548} 549} 550break; 551case Call::BINDERLISTMETHOD: 552{ 553::std::vector<::android::sp<::android::IBinder>> in_input; 554::std::vector<::android::sp<::android::IBinder>> out_output; 555::std::vector<::android::sp<::android::IBinder>> _aidl_return; 556if (!(_aidl_data.checkInterface(this))) { 557_aidl_ret_status = ::android::BAD_TYPE; 558break; 559} 560_aidl_ret_status = _aidl_data.readStrongBinderVector(&in_input); 561if (((_aidl_ret_status) != (::android::OK))) { 562break; 563} 564::android::binder::Status _aidl_status(BinderListMethod(in_input, &out_output, &_aidl_return)); 565_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); 566if (((_aidl_ret_status) != (::android::OK))) { 567break; 568} 569if (!_aidl_status.isOk()) { 570break; 571} 572_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return); 573if (((_aidl_ret_status) != (::android::OK))) { 574break; 575} 576_aidl_ret_status = _aidl_reply->writeStrongBinderVector(out_output); 577if (((_aidl_ret_status) != (::android::OK))) { 578break; 579} 580} 581break; 582case Call::TAKESAFILEDESCRIPTOR: 583{ 584::android::base::unique_fd in_f; 585::android::base::unique_fd _aidl_return; 586if (!(_aidl_data.checkInterface(this))) { 587_aidl_ret_status = ::android::BAD_TYPE; 588break; 589} 590_aidl_ret_status = _aidl_data.readUniqueFileDescriptor(&in_f); 591if (((_aidl_ret_status) != (::android::OK))) { 592break; 593} 594::android::binder::Status _aidl_status(TakesAFileDescriptor(in_f, &_aidl_return)); 595_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); 596if (((_aidl_ret_status) != (::android::OK))) { 597break; 598} 599if (!_aidl_status.isOk()) { 600break; 601} 602_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptor(_aidl_return); 603if (((_aidl_ret_status) != (::android::OK))) { 604break; 605} 606} 607break; 608case Call::TAKESAFILEDESCRIPTORARRAY: 609{ 610::std::vector<::android::base::unique_fd> in_f; 611::std::vector<::android::base::unique_fd> _aidl_return; 612if (!(_aidl_data.checkInterface(this))) { 613_aidl_ret_status = ::android::BAD_TYPE; 614break; 615} 616_aidl_ret_status = _aidl_data.readUniqueFileDescriptorVector(&in_f); 617if (((_aidl_ret_status) != (::android::OK))) { 618break; 619} 620::android::binder::Status _aidl_status(TakesAFileDescriptorArray(in_f, &_aidl_return)); 621_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply); 622if (((_aidl_ret_status) != (::android::OK))) { 623break; 624} 625if (!_aidl_status.isOk()) { 626break; 627} 628_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptorVector(_aidl_return); 629if (((_aidl_ret_status) != (::android::OK))) { 630break; 631} 632} 633break; 634default: 635{ 636_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags); 637} 638break; 639} 640if (_aidl_ret_status == ::android::UNEXPECTED_NULL) { 641_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply); 642} 643return _aidl_ret_status; 644} 645 646} // namespace os 647 648} // namespace android 649)"; 650 651const char kExpectedComplexTypeInterfaceHeaderOutput[] = 652R"(#ifndef AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 653#define AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 654 655#include <android-base/unique_fd.h> 656#include <binder/IBinder.h> 657#include <binder/IInterface.h> 658#include <binder/Status.h> 659#include <cstdint> 660#include <foo/IFooType.h> 661#include <memory> 662#include <utils/String16.h> 663#include <utils/StrongPointer.h> 664#include <vector> 665 666namespace android { 667 668namespace os { 669 670class IComplexTypeInterface : public ::android::IInterface { 671public: 672DECLARE_META_INTERFACE(ComplexTypeInterface) 673enum : int32_t { 674 MY_CONSTANT = 3, 675}; 676virtual ::android::binder::Status Send(const ::std::unique_ptr<::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; 677virtual ::android::binder::Status Piff(int32_t times) = 0; 678virtual ::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) = 0; 679virtual ::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) = 0; 680virtual ::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) = 0; 681virtual ::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; 682virtual ::android::binder::Status TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) = 0; 683virtual ::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) = 0; 684enum Call { 685 SEND = ::android::IBinder::FIRST_CALL_TRANSACTION + 0, 686 PIFF = ::android::IBinder::FIRST_CALL_TRANSACTION + 1, 687 TAKESABINDER = ::android::IBinder::FIRST_CALL_TRANSACTION + 2, 688 NULLABLEBINDER = ::android::IBinder::FIRST_CALL_TRANSACTION + 3, 689 STRINGLISTMETHOD = ::android::IBinder::FIRST_CALL_TRANSACTION + 4, 690 BINDERLISTMETHOD = ::android::IBinder::FIRST_CALL_TRANSACTION + 5, 691 TAKESAFILEDESCRIPTOR = ::android::IBinder::FIRST_CALL_TRANSACTION + 6, 692 TAKESAFILEDESCRIPTORARRAY = ::android::IBinder::FIRST_CALL_TRANSACTION + 7, 693}; 694}; // class IComplexTypeInterface 695 696} // namespace os 697 698} // namespace android 699 700#endif // AIDL_GENERATED_ANDROID_OS_I_COMPLEX_TYPE_INTERFACE_H_ 701)"; 702 703const char kExpectedComplexTypeInterfaceSourceOutput[] = 704R"(#include <android/os/IComplexTypeInterface.h> 705#include <android/os/BpComplexTypeInterface.h> 706 707namespace android { 708 709namespace os { 710 711IMPLEMENT_META_INTERFACE(ComplexTypeInterface, "android.os.IComplexTypeInterface") 712 713} // namespace os 714 715} // namespace android 716)"; 717 718} // namespace 719 720class ASTTest : public ::testing::Test { 721 protected: 722 ASTTest(string file_path, string file_contents) 723 : file_path_(file_path), 724 file_contents_(file_contents) { 725 types_.Init(); 726 } 727 728 unique_ptr<AidlInterface> Parse() { 729 io_delegate_.SetFileContents(file_path_, file_contents_); 730 731 unique_ptr<AidlInterface> ret; 732 std::vector<std::unique_ptr<AidlImport>> imports; 733 AidlError err = ::android::aidl::internals::load_and_validate_aidl( 734 {}, // no preprocessed files 735 {"."}, 736 file_path_, 737 io_delegate_, 738 &types_, 739 &ret, 740 &imports); 741 742 if (err != AidlError::OK) 743 return nullptr; 744 745 return ret; 746 } 747 748 void Compare(Document* doc, const char* expected) { 749 string output; 750 unique_ptr<CodeWriter> cw = GetStringWriter(&output); 751 752 doc->Write(cw.get()); 753 754 if (expected == output) { 755 return; // Success 756 } 757 758 test::PrintDiff(expected, output); 759 FAIL() << "Document contents did not match expected contents"; 760 } 761 762 const string file_path_; 763 const string file_contents_; 764 FakeIoDelegate io_delegate_; 765 TypeNamespace types_; 766}; 767 768class ComplexTypeInterfaceASTTest : public ASTTest { 769 public: 770 ComplexTypeInterfaceASTTest() 771 : ASTTest("android/os/IComplexTypeInterface.aidl", 772 kComplexTypeInterfaceAIDL) { 773 io_delegate_.SetFileContents("foo/IFooType.aidl", 774 "package foo; interface IFooType {}"); 775 } 776}; 777 778TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientHeader) { 779 unique_ptr<AidlInterface> interface = Parse(); 780 ASSERT_NE(interface, nullptr); 781 unique_ptr<Document> doc = internals::BuildClientHeader(types_, *interface); 782 Compare(doc.get(), kExpectedComplexTypeClientHeaderOutput); 783} 784 785TEST_F(ComplexTypeInterfaceASTTest, GeneratesClientSource) { 786 unique_ptr<AidlInterface> interface = Parse(); 787 ASSERT_NE(interface, nullptr); 788 unique_ptr<Document> doc = internals::BuildClientSource(types_, *interface); 789 Compare(doc.get(), kExpectedComplexTypeClientSourceOutput); 790} 791 792TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerHeader) { 793 unique_ptr<AidlInterface> interface = Parse(); 794 ASSERT_NE(interface, nullptr); 795 unique_ptr<Document> doc = internals::BuildServerHeader(types_, *interface); 796 Compare(doc.get(), kExpectedComplexTypeServerHeaderOutput); 797} 798 799TEST_F(ComplexTypeInterfaceASTTest, GeneratesServerSource) { 800 unique_ptr<AidlInterface> interface = Parse(); 801 ASSERT_NE(interface, nullptr); 802 unique_ptr<Document> doc = internals::BuildServerSource(types_, *interface); 803 Compare(doc.get(), kExpectedComplexTypeServerSourceOutput); 804} 805 806TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceHeader) { 807 unique_ptr<AidlInterface> interface = Parse(); 808 ASSERT_NE(interface, nullptr); 809 unique_ptr<Document> doc = internals::BuildInterfaceHeader(types_, *interface); 810 Compare(doc.get(), kExpectedComplexTypeInterfaceHeaderOutput); 811} 812 813TEST_F(ComplexTypeInterfaceASTTest, GeneratesInterfaceSource) { 814 unique_ptr<AidlInterface> interface = Parse(); 815 ASSERT_NE(interface, nullptr); 816 unique_ptr<Document> doc = internals::BuildInterfaceSource(types_, *interface); 817 Compare(doc.get(), kExpectedComplexTypeInterfaceSourceOutput); 818} 819 820namespace test_io_handling { 821 822const char kInputPath[] = "a/IFoo.aidl"; 823const char kOutputPath[] = "output.cpp"; 824const char kHeaderDir[] = "headers"; 825const char kInterfaceHeaderRelPath[] = "a/IFoo.h"; 826 827} // namespace test_io_handling 828 829class IoErrorHandlingTest : public ASTTest { 830 public: 831 IoErrorHandlingTest () 832 : ASTTest(test_io_handling::kInputPath, 833 "package a; interface IFoo {}"), 834 options_(GetOptions()) {} 835 836 const unique_ptr<CppOptions> options_; 837 838 private: 839 static unique_ptr<CppOptions> GetOptions() { 840 using namespace test_io_handling; 841 842 const int argc = 4; 843 const char* cmdline[argc] = { 844 "aidl-cpp", kInputPath, kHeaderDir, kOutputPath 845 }; 846 return CppOptions::Parse(argc, cmdline); 847 } 848}; 849 850TEST_F(IoErrorHandlingTest, GenerateCorrectlyAbsentErrors) { 851 // Confirm that this is working correctly without I/O problems. 852 const unique_ptr<AidlInterface> interface = Parse(); 853 ASSERT_NE(interface, nullptr); 854 ASSERT_TRUE(GenerateCpp(*options_, types_, *interface, io_delegate_)); 855} 856 857TEST_F(IoErrorHandlingTest, HandlesBadHeaderWrite) { 858 using namespace test_io_handling; 859 const unique_ptr<AidlInterface> interface = Parse(); 860 ASSERT_NE(interface, nullptr); 861 862 // Simulate issues closing the interface header. 863 const string header_path = 864 StringPrintf("%s%c%s", kHeaderDir, OS_PATH_SEPARATOR, 865 kInterfaceHeaderRelPath); 866 io_delegate_.AddBrokenFilePath(header_path); 867 ASSERT_FALSE(GenerateCpp(*options_, types_, *interface, io_delegate_)); 868 // We should never attempt to write the C++ file if we fail writing headers. 869 ASSERT_FALSE(io_delegate_.GetWrittenContents(kOutputPath, nullptr)); 870 // We should remove partial results. 871 ASSERT_TRUE(io_delegate_.PathWasRemoved(header_path)); 872} 873 874TEST_F(IoErrorHandlingTest, HandlesBadCppWrite) { 875 using test_io_handling::kOutputPath; 876 const unique_ptr<AidlInterface> interface = Parse(); 877 ASSERT_NE(interface, nullptr); 878 879 // Simulate issues closing the cpp file. 880 io_delegate_.AddBrokenFilePath(kOutputPath); 881 ASSERT_FALSE(GenerateCpp(*options_, types_, *interface, io_delegate_)); 882 // We should remove partial results. 883 ASSERT_TRUE(io_delegate_.PathWasRemoved(kOutputPath)); 884} 885 886} // namespace cpp 887} // namespace aidl 888} // namespace android 889