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