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