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