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