1/*
2 * Copyright (C) 2015, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <string>
18
19#include <android-base/stringprintf.h>
20#include <gtest/gtest.h>
21
22#include "aidl.h"
23#include "aidl_language.h"
24#include "ast_cpp.h"
25#include "code_writer.h"
26#include "generate_cpp.h"
27#include "os.h"
28#include "tests/fake_io_delegate.h"
29#include "tests/test_util.h"
30#include "type_cpp.h"
31
32using ::android::aidl::test::FakeIoDelegate;
33using ::android::base::StringPrintf;
34using std::string;
35using std::unique_ptr;
36
37namespace android {
38namespace aidl {
39namespace cpp {
40namespace {
41
42const string kComplexTypeInterfaceAIDL =
43R"(package android.os;
44import foo.IFooType;
45interface IComplexTypeInterface {
46  const int MY_CONSTANT = 3;
47  int[] Send(in @nullable int[] goes_in, inout double[] goes_in_and_out, out boolean[] goes_out);
48  oneway void Piff(int times);
49  IFooType TakesABinder(IFooType f);
50  @nullable IFooType NullableBinder();
51  List<String> StringListMethod(in java.util.List<String> input, out List<String> output);
52  List<IBinder> BinderListMethod(in java.util.List<IBinder> input, out List<IBinder> output);
53  FileDescriptor TakesAFileDescriptor(in FileDescriptor f);
54  FileDescriptor[] TakesAFileDescriptorArray(in FileDescriptor[] f);
55})";
56
57const char kExpectedComplexTypeClientHeaderOutput[] =
58R"(#ifndef AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_
59#define AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_
60
61#include <binder/IBinder.h>
62#include <binder/IInterface.h>
63#include <utils/Errors.h>
64#include <android/os/IComplexTypeInterface.h>
65
66namespace android {
67
68namespace os {
69
70class BpComplexTypeInterface : public ::android::BpInterface<IComplexTypeInterface> {
71public:
72explicit BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl);
73virtual ~BpComplexTypeInterface() = default;
74::android::binder::Status Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) override;
75::android::binder::Status Piff(int32_t times) override;
76::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) override;
77::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) override;
78::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) override;
79::android::binder::Status BinderListMethod(const ::std::vector<::android::sp<::android::IBinder>>& input, ::std::vector<::android::sp<::android::IBinder>>* output, ::std::vector<::android::sp<::android::IBinder>>* _aidl_return) override;
80::android::binder::Status TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) override;
81::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) override;
82};  // class BpComplexTypeInterface
83
84}  // namespace os
85
86}  // namespace android
87
88#endif  // AIDL_GENERATED_ANDROID_OS_BP_COMPLEX_TYPE_INTERFACE_H_
89)";
90
91const char kExpectedComplexTypeClientSourceOutput[] =
92R"(#include <android/os/BpComplexTypeInterface.h>
93#include <binder/Parcel.h>
94
95namespace android {
96
97namespace os {
98
99BpComplexTypeInterface::BpComplexTypeInterface(const ::android::sp<::android::IBinder>& _aidl_impl)
100    : BpInterface<IComplexTypeInterface>(_aidl_impl){
101}
102
103::android::binder::Status BpComplexTypeInterface::Send(const ::std::unique_ptr<::std::vector<int32_t>>& goes_in, ::std::vector<double>* goes_in_and_out, ::std::vector<bool>* goes_out, ::std::vector<int32_t>* _aidl_return) {
104::android::Parcel _aidl_data;
105::android::Parcel _aidl_reply;
106::android::status_t _aidl_ret_status = ::android::OK;
107::android::binder::Status _aidl_status;
108_aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
109if (((_aidl_ret_status) != (::android::OK))) {
110goto _aidl_error;
111}
112_aidl_ret_status = _aidl_data.writeInt32Vector(goes_in);
113if (((_aidl_ret_status) != (::android::OK))) {
114goto _aidl_error;
115}
116_aidl_ret_status = _aidl_data.writeDoubleVector(*goes_in_and_out);
117if (((_aidl_ret_status) != (::android::OK))) {
118goto _aidl_error;
119}
120_aidl_ret_status = _aidl_data.writeVectorSize(*goes_out);
121if (((_aidl_ret_status) != (::android::OK))) {
122goto _aidl_error;
123}
124_aidl_ret_status = remote()->transact(IComplexTypeInterface::SEND, _aidl_data, &_aidl_reply);
125if (((_aidl_ret_status) != (::android::OK))) {
126goto _aidl_error;
127}
128_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
129if (((_aidl_ret_status) != (::android::OK))) {
130goto _aidl_error;
131}
132if (!_aidl_status.isOk()) {
133return _aidl_status;
134}
135_aidl_ret_status = _aidl_reply.readInt32Vector(_aidl_return);
136if (((_aidl_ret_status) != (::android::OK))) {
137goto _aidl_error;
138}
139_aidl_ret_status = _aidl_reply.readDoubleVector(goes_in_and_out);
140if (((_aidl_ret_status) != (::android::OK))) {
141goto _aidl_error;
142}
143_aidl_ret_status = _aidl_reply.readBoolVector(goes_out);
144if (((_aidl_ret_status) != (::android::OK))) {
145goto _aidl_error;
146}
147_aidl_error:
148_aidl_status.setFromStatusT(_aidl_ret_status);
149return _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());
158if (((_aidl_ret_status) != (::android::OK))) {
159goto _aidl_error;
160}
161_aidl_ret_status = _aidl_data.writeInt32(times);
162if (((_aidl_ret_status) != (::android::OK))) {
163goto _aidl_error;
164}
165_aidl_ret_status = remote()->transact(IComplexTypeInterface::PIFF, _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
166if (((_aidl_ret_status) != (::android::OK))) {
167goto _aidl_error;
168}
169_aidl_error:
170_aidl_status.setFromStatusT(_aidl_ret_status);
171return _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());
180if (((_aidl_ret_status) != (::android::OK))) {
181goto _aidl_error;
182}
183_aidl_ret_status = _aidl_data.writeStrongBinder(::foo::IFooType::asBinder(f));
184if (((_aidl_ret_status) != (::android::OK))) {
185goto _aidl_error;
186}
187_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESABINDER, _aidl_data, &_aidl_reply);
188if (((_aidl_ret_status) != (::android::OK))) {
189goto _aidl_error;
190}
191_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
192if (((_aidl_ret_status) != (::android::OK))) {
193goto _aidl_error;
194}
195if (!_aidl_status.isOk()) {
196return _aidl_status;
197}
198_aidl_ret_status = _aidl_reply.readStrongBinder(_aidl_return);
199if (((_aidl_ret_status) != (::android::OK))) {
200goto _aidl_error;
201}
202_aidl_error:
203_aidl_status.setFromStatusT(_aidl_ret_status);
204return _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());
213if (((_aidl_ret_status) != (::android::OK))) {
214goto _aidl_error;
215}
216_aidl_ret_status = remote()->transact(IComplexTypeInterface::NULLABLEBINDER, _aidl_data, &_aidl_reply);
217if (((_aidl_ret_status) != (::android::OK))) {
218goto _aidl_error;
219}
220_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
221if (((_aidl_ret_status) != (::android::OK))) {
222goto _aidl_error;
223}
224if (!_aidl_status.isOk()) {
225return _aidl_status;
226}
227_aidl_ret_status = _aidl_reply.readNullableStrongBinder(_aidl_return);
228if (((_aidl_ret_status) != (::android::OK))) {
229goto _aidl_error;
230}
231_aidl_error:
232_aidl_status.setFromStatusT(_aidl_ret_status);
233return _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());
242if (((_aidl_ret_status) != (::android::OK))) {
243goto _aidl_error;
244}
245_aidl_ret_status = _aidl_data.writeString16Vector(input);
246if (((_aidl_ret_status) != (::android::OK))) {
247goto _aidl_error;
248}
249_aidl_ret_status = remote()->transact(IComplexTypeInterface::STRINGLISTMETHOD, _aidl_data, &_aidl_reply);
250if (((_aidl_ret_status) != (::android::OK))) {
251goto _aidl_error;
252}
253_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
254if (((_aidl_ret_status) != (::android::OK))) {
255goto _aidl_error;
256}
257if (!_aidl_status.isOk()) {
258return _aidl_status;
259}
260_aidl_ret_status = _aidl_reply.readString16Vector(_aidl_return);
261if (((_aidl_ret_status) != (::android::OK))) {
262goto _aidl_error;
263}
264_aidl_ret_status = _aidl_reply.readString16Vector(output);
265if (((_aidl_ret_status) != (::android::OK))) {
266goto _aidl_error;
267}
268_aidl_error:
269_aidl_status.setFromStatusT(_aidl_ret_status);
270return _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());
279if (((_aidl_ret_status) != (::android::OK))) {
280goto _aidl_error;
281}
282_aidl_ret_status = _aidl_data.writeStrongBinderVector(input);
283if (((_aidl_ret_status) != (::android::OK))) {
284goto _aidl_error;
285}
286_aidl_ret_status = remote()->transact(IComplexTypeInterface::BINDERLISTMETHOD, _aidl_data, &_aidl_reply);
287if (((_aidl_ret_status) != (::android::OK))) {
288goto _aidl_error;
289}
290_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
291if (((_aidl_ret_status) != (::android::OK))) {
292goto _aidl_error;
293}
294if (!_aidl_status.isOk()) {
295return _aidl_status;
296}
297_aidl_ret_status = _aidl_reply.readStrongBinderVector(_aidl_return);
298if (((_aidl_ret_status) != (::android::OK))) {
299goto _aidl_error;
300}
301_aidl_ret_status = _aidl_reply.readStrongBinderVector(output);
302if (((_aidl_ret_status) != (::android::OK))) {
303goto _aidl_error;
304}
305_aidl_error:
306_aidl_status.setFromStatusT(_aidl_ret_status);
307return _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());
316if (((_aidl_ret_status) != (::android::OK))) {
317goto _aidl_error;
318}
319_aidl_ret_status = _aidl_data.writeUniqueFileDescriptor(f);
320if (((_aidl_ret_status) != (::android::OK))) {
321goto _aidl_error;
322}
323_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTOR, _aidl_data, &_aidl_reply);
324if (((_aidl_ret_status) != (::android::OK))) {
325goto _aidl_error;
326}
327_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
328if (((_aidl_ret_status) != (::android::OK))) {
329goto _aidl_error;
330}
331if (!_aidl_status.isOk()) {
332return _aidl_status;
333}
334_aidl_ret_status = _aidl_reply.readUniqueFileDescriptor(_aidl_return);
335if (((_aidl_ret_status) != (::android::OK))) {
336goto _aidl_error;
337}
338_aidl_error:
339_aidl_status.setFromStatusT(_aidl_ret_status);
340return _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());
349if (((_aidl_ret_status) != (::android::OK))) {
350goto _aidl_error;
351}
352_aidl_ret_status = _aidl_data.writeUniqueFileDescriptorVector(f);
353if (((_aidl_ret_status) != (::android::OK))) {
354goto _aidl_error;
355}
356_aidl_ret_status = remote()->transact(IComplexTypeInterface::TAKESAFILEDESCRIPTORARRAY, _aidl_data, &_aidl_reply);
357if (((_aidl_ret_status) != (::android::OK))) {
358goto _aidl_error;
359}
360_aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
361if (((_aidl_ret_status) != (::android::OK))) {
362goto _aidl_error;
363}
364if (!_aidl_status.isOk()) {
365return _aidl_status;
366}
367_aidl_ret_status = _aidl_reply.readUniqueFileDescriptorVector(_aidl_return);
368if (((_aidl_ret_status) != (::android::OK))) {
369goto _aidl_error;
370}
371_aidl_error:
372_aidl_status.setFromStatusT(_aidl_ret_status);
373return _aidl_status;
374}
375
376}  // namespace os
377
378}  // namespace android
379)";
380
381const char kExpectedComplexTypeServerHeaderOutput[] =
382R"(#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
388namespace android {
389
390namespace os {
391
392class BnComplexTypeInterface : public ::android::BnInterface<IComplexTypeInterface> {
393public:
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
404const char kExpectedComplexTypeServerSourceOutput[] =
405R"(#include <android/os/BnComplexTypeInterface.h>
406#include <binder/Parcel.h>
407
408namespace android {
409
410namespace 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;
414switch (_aidl_code) {
415case 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;
421if (!(_aidl_data.checkInterface(this))) {
422_aidl_ret_status = ::android::BAD_TYPE;
423break;
424}
425_aidl_ret_status = _aidl_data.readInt32Vector(&in_goes_in);
426if (((_aidl_ret_status) != (::android::OK))) {
427break;
428}
429_aidl_ret_status = _aidl_data.readDoubleVector(&in_goes_in_and_out);
430if (((_aidl_ret_status) != (::android::OK))) {
431break;
432}
433_aidl_ret_status = _aidl_data.resizeOutVector(&out_goes_out);
434if (((_aidl_ret_status) != (::android::OK))) {
435break;
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);
439if (((_aidl_ret_status) != (::android::OK))) {
440break;
441}
442if (!_aidl_status.isOk()) {
443break;
444}
445_aidl_ret_status = _aidl_reply->writeInt32Vector(_aidl_return);
446if (((_aidl_ret_status) != (::android::OK))) {
447break;
448}
449_aidl_ret_status = _aidl_reply->writeDoubleVector(in_goes_in_and_out);
450if (((_aidl_ret_status) != (::android::OK))) {
451break;
452}
453_aidl_ret_status = _aidl_reply->writeBoolVector(out_goes_out);
454if (((_aidl_ret_status) != (::android::OK))) {
455break;
456}
457}
458break;
459case Call::PIFF:
460{
461int32_t in_times;
462if (!(_aidl_data.checkInterface(this))) {
463_aidl_ret_status = ::android::BAD_TYPE;
464break;
465}
466_aidl_ret_status = _aidl_data.readInt32(&in_times);
467if (((_aidl_ret_status) != (::android::OK))) {
468break;
469}
470::android::binder::Status _aidl_status(Piff(in_times));
471}
472break;
473case Call::TAKESABINDER:
474{
475::android::sp<::foo::IFooType> in_f;
476::android::sp<::foo::IFooType> _aidl_return;
477if (!(_aidl_data.checkInterface(this))) {
478_aidl_ret_status = ::android::BAD_TYPE;
479break;
480}
481_aidl_ret_status = _aidl_data.readStrongBinder(&in_f);
482if (((_aidl_ret_status) != (::android::OK))) {
483break;
484}
485::android::binder::Status _aidl_status(TakesABinder(in_f, &_aidl_return));
486_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
487if (((_aidl_ret_status) != (::android::OK))) {
488break;
489}
490if (!_aidl_status.isOk()) {
491break;
492}
493_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
494if (((_aidl_ret_status) != (::android::OK))) {
495break;
496}
497}
498break;
499case Call::NULLABLEBINDER:
500{
501::android::sp<::foo::IFooType> _aidl_return;
502if (!(_aidl_data.checkInterface(this))) {
503_aidl_ret_status = ::android::BAD_TYPE;
504break;
505}
506::android::binder::Status _aidl_status(NullableBinder(&_aidl_return));
507_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
508if (((_aidl_ret_status) != (::android::OK))) {
509break;
510}
511if (!_aidl_status.isOk()) {
512break;
513}
514_aidl_ret_status = _aidl_reply->writeStrongBinder(::foo::IFooType::asBinder(_aidl_return));
515if (((_aidl_ret_status) != (::android::OK))) {
516break;
517}
518}
519break;
520case Call::STRINGLISTMETHOD:
521{
522::std::vector<::android::String16> in_input;
523::std::vector<::android::String16> out_output;
524::std::vector<::android::String16> _aidl_return;
525if (!(_aidl_data.checkInterface(this))) {
526_aidl_ret_status = ::android::BAD_TYPE;
527break;
528}
529_aidl_ret_status = _aidl_data.readString16Vector(&in_input);
530if (((_aidl_ret_status) != (::android::OK))) {
531break;
532}
533::android::binder::Status _aidl_status(StringListMethod(in_input, &out_output, &_aidl_return));
534_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
535if (((_aidl_ret_status) != (::android::OK))) {
536break;
537}
538if (!_aidl_status.isOk()) {
539break;
540}
541_aidl_ret_status = _aidl_reply->writeString16Vector(_aidl_return);
542if (((_aidl_ret_status) != (::android::OK))) {
543break;
544}
545_aidl_ret_status = _aidl_reply->writeString16Vector(out_output);
546if (((_aidl_ret_status) != (::android::OK))) {
547break;
548}
549}
550break;
551case 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;
556if (!(_aidl_data.checkInterface(this))) {
557_aidl_ret_status = ::android::BAD_TYPE;
558break;
559}
560_aidl_ret_status = _aidl_data.readStrongBinderVector(&in_input);
561if (((_aidl_ret_status) != (::android::OK))) {
562break;
563}
564::android::binder::Status _aidl_status(BinderListMethod(in_input, &out_output, &_aidl_return));
565_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
566if (((_aidl_ret_status) != (::android::OK))) {
567break;
568}
569if (!_aidl_status.isOk()) {
570break;
571}
572_aidl_ret_status = _aidl_reply->writeStrongBinderVector(_aidl_return);
573if (((_aidl_ret_status) != (::android::OK))) {
574break;
575}
576_aidl_ret_status = _aidl_reply->writeStrongBinderVector(out_output);
577if (((_aidl_ret_status) != (::android::OK))) {
578break;
579}
580}
581break;
582case Call::TAKESAFILEDESCRIPTOR:
583{
584::android::base::unique_fd in_f;
585::android::base::unique_fd _aidl_return;
586if (!(_aidl_data.checkInterface(this))) {
587_aidl_ret_status = ::android::BAD_TYPE;
588break;
589}
590_aidl_ret_status = _aidl_data.readUniqueFileDescriptor(&in_f);
591if (((_aidl_ret_status) != (::android::OK))) {
592break;
593}
594::android::binder::Status _aidl_status(TakesAFileDescriptor(in_f, &_aidl_return));
595_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
596if (((_aidl_ret_status) != (::android::OK))) {
597break;
598}
599if (!_aidl_status.isOk()) {
600break;
601}
602_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptor(_aidl_return);
603if (((_aidl_ret_status) != (::android::OK))) {
604break;
605}
606}
607break;
608case Call::TAKESAFILEDESCRIPTORARRAY:
609{
610::std::vector<::android::base::unique_fd> in_f;
611::std::vector<::android::base::unique_fd> _aidl_return;
612if (!(_aidl_data.checkInterface(this))) {
613_aidl_ret_status = ::android::BAD_TYPE;
614break;
615}
616_aidl_ret_status = _aidl_data.readUniqueFileDescriptorVector(&in_f);
617if (((_aidl_ret_status) != (::android::OK))) {
618break;
619}
620::android::binder::Status _aidl_status(TakesAFileDescriptorArray(in_f, &_aidl_return));
621_aidl_ret_status = _aidl_status.writeToParcel(_aidl_reply);
622if (((_aidl_ret_status) != (::android::OK))) {
623break;
624}
625if (!_aidl_status.isOk()) {
626break;
627}
628_aidl_ret_status = _aidl_reply->writeUniqueFileDescriptorVector(_aidl_return);
629if (((_aidl_ret_status) != (::android::OK))) {
630break;
631}
632}
633break;
634default:
635{
636_aidl_ret_status = ::android::BBinder::onTransact(_aidl_code, _aidl_data, _aidl_reply, _aidl_flags);
637}
638break;
639}
640if (_aidl_ret_status == ::android::UNEXPECTED_NULL) {
641_aidl_ret_status = ::android::binder::Status::fromExceptionCode(::android::binder::Status::EX_NULL_POINTER).writeToParcel(_aidl_reply);
642}
643return _aidl_ret_status;
644}
645
646}  // namespace os
647
648}  // namespace android
649)";
650
651const char kExpectedComplexTypeInterfaceHeaderOutput[] =
652R"(#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
666namespace android {
667
668namespace os {
669
670class IComplexTypeInterface : public ::android::IInterface {
671public:
672DECLARE_META_INTERFACE(ComplexTypeInterface)
673enum  : int32_t {
674  MY_CONSTANT = 3,
675};
676virtual ::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;
677virtual ::android::binder::Status Piff(int32_t times) = 0;
678virtual ::android::binder::Status TakesABinder(const ::android::sp<::foo::IFooType>& f, ::android::sp<::foo::IFooType>* _aidl_return) = 0;
679virtual ::android::binder::Status NullableBinder(::android::sp<::foo::IFooType>* _aidl_return) = 0;
680virtual ::android::binder::Status StringListMethod(const ::std::vector<::android::String16>& input, ::std::vector<::android::String16>* output, ::std::vector<::android::String16>* _aidl_return) = 0;
681virtual ::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;
682virtual ::android::binder::Status TakesAFileDescriptor(const ::android::base::unique_fd& f, ::android::base::unique_fd* _aidl_return) = 0;
683virtual ::android::binder::Status TakesAFileDescriptorArray(const ::std::vector<::android::base::unique_fd>& f, ::std::vector<::android::base::unique_fd>* _aidl_return) = 0;
684enum 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
703const char kExpectedComplexTypeInterfaceSourceOutput[] =
704R"(#include <android/os/IComplexTypeInterface.h>
705#include <android/os/BpComplexTypeInterface.h>
706
707namespace android {
708
709namespace os {
710
711IMPLEMENT_META_INTERFACE(ComplexTypeInterface, "android.os.IComplexTypeInterface")
712
713}  // namespace os
714
715}  // namespace android
716)";
717
718}  // namespace
719
720class ASTTest : public ::testing::Test {
721 protected:
722  ASTTest(string file_path, string file_contents)
723      : file_path_(file_path),
724        file_contents_(file_contents) {
725    types_.Init();
726  }
727
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
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
768class ComplexTypeInterfaceASTTest : public ASTTest {
769 public:
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
778TEST_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
785TEST_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
792TEST_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
799TEST_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
806TEST_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
813TEST_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
820namespace test_io_handling {
821
822const char kInputPath[] = "a/IFoo.aidl";
823const char kOutputPath[] = "output.cpp";
824const char kHeaderDir[] = "headers";
825const char kInterfaceHeaderRelPath[] = "a/IFoo.h";
826
827}  // namespace test_io_handling
828
829class IoErrorHandlingTest : public ASTTest {
830 public:
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:
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
850TEST_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
857TEST_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
874TEST_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