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