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:
ASTTest(string file_path,string file_contents)656   ASTTest(string file_path, string file_contents)
657       : file_path_(file_path),
658         file_contents_(file_contents) {
659     types_.Init();
660   }
661 
Parse()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 
Compare(Document * doc,const char * expected)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:
ComplexTypeInterfaceASTTest()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 
TEST_F(ComplexTypeInterfaceASTTest,GeneratesClientHeader)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 
TEST_F(ComplexTypeInterfaceASTTest,GeneratesClientSource)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 
TEST_F(ComplexTypeInterfaceASTTest,GeneratesServerHeader)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 
TEST_F(ComplexTypeInterfaceASTTest,GeneratesServerSource)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 
TEST_F(ComplexTypeInterfaceASTTest,GeneratesInterfaceHeader)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 
TEST_F(ComplexTypeInterfaceASTTest,GeneratesInterfaceSource)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:
IoErrorHandlingTest()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:
GetOptions()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 
TEST_F(IoErrorHandlingTest,GenerateCorrectlyAbsentErrors)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 
TEST_F(IoErrorHandlingTest,HandlesBadHeaderWrite)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 
TEST_F(IoErrorHandlingTest,HandlesBadCppWrite)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