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