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  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <android/aidl/fixedsizearray/FixedSizeArrayExample.h>
17 #include <android/aidl/tests/ParcelableForToString.h>
18 #include <android/aidl/tests/extension/MyExt.h>
19 #include <android/aidl/tests/extension/MyExt2.h>
20 #include <android/aidl/tests/extension/MyExtLike.h>
21 #include <android/aidl/tests/unions/EnumUnion.h>
22 #include <android/aidl/tests/vintf/VintfExtendableParcelable.h>
23 #include <android/aidl/tests/vintf/VintfParcelable.h>
24 #include <binder/Binder.h>
25 #include "aidl_test_client.h"
26 
27 #include <string>
28 #include <vector>
29 
30 using android::IInterface;
31 using android::sp;
32 using android::String16;
33 using android::String8;
34 using android::aidl::fixedsizearray::FixedSizeArrayExample;
35 using android::aidl::tests::BadParcelable;
36 using android::aidl::tests::ConstantExpressionEnum;
37 using android::aidl::tests::GenericStructuredParcelable;
38 using android::aidl::tests::INamedCallback;
39 using android::aidl::tests::IntEnum;
40 using android::aidl::tests::ITestService;
41 using android::aidl::tests::OtherParcelableForToString;
42 using android::aidl::tests::ParcelableForToString;
43 using android::aidl::tests::RecursiveList;
44 using android::aidl::tests::SimpleParcelable;
45 using android::aidl::tests::StructuredParcelable;
46 using android::aidl::tests::Union;
47 using android::aidl::tests::extension::ExtendableParcelable;
48 using android::aidl::tests::extension::MyExt;
49 using android::aidl::tests::extension::MyExt2;
50 using android::aidl::tests::extension::MyExtLike;
51 using android::aidl::tests::unions::EnumUnion;
52 using android::aidl::tests::vintf::VintfExtendableParcelable;
53 using android::aidl::tests::vintf::VintfParcelable;
54 using IntParcelable = android::aidl::fixedsizearray::FixedSizeArrayExample::IntParcelable;
55 using IRepeatFixedSizeArray =
56     android::aidl::fixedsizearray::FixedSizeArrayExample::IRepeatFixedSizeArray;
57 using android::BBinder;
58 using android::IBinder;
59 using android::OK;
60 using android::binder::Status;
61 using android::os::PersistableBundle;
62 using std::string;
63 using std::vector;
64 
TEST_F(AidlTest,BadParcelable)65 TEST_F(AidlTest, BadParcelable) {
66   if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
67 
68   BadParcelable output;
69   {
70     BadParcelable bad(/*bad=*/true, "Booya", 42);
71     Status status = cpp_java_tests->RepeatBadParcelable(bad, &output);
72     ASSERT_FALSE(status.isOk());
73     EXPECT_EQ(status.exceptionCode(), Status::Exception::EX_BAD_PARCELABLE);
74   }
75   {
76     BadParcelable not_bad(/*bad=*/false, "Booya", 42);
77     Status status = cpp_java_tests->RepeatBadParcelable(not_bad, &output);
78     ASSERT_TRUE(status.isOk());
79     EXPECT_EQ(not_bad, output);
80   }
81 }
82 
TEST_F(AidlTest,RepeatSimpleParcelable)83 TEST_F(AidlTest, RepeatSimpleParcelable) {
84   SimpleParcelable input("Booya", 42);
85   SimpleParcelable out_param, returned;
86   Status status = service->RepeatSimpleParcelable(input, &out_param, &returned);
87   ASSERT_TRUE(status.isOk()) << status.toString8();
88   EXPECT_EQ(input, out_param) << input.toString() << " " << out_param.toString();
89   EXPECT_EQ(input, returned) << input.toString() << " " << returned.toString();
90 }
91 
TEST_F(AidlTest,RepeatGenericStructureParcelable)92 TEST_F(AidlTest, RepeatGenericStructureParcelable) {
93   if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
94 
95   GenericStructuredParcelable<int32_t, StructuredParcelable, IntEnum> input, out_param, returned;
96   input.a = 41;
97   input.b = 42;
98   Status status = cpp_java_tests->RepeatGenericParcelable(input, &out_param, &returned);
99   ASSERT_TRUE(status.isOk()) << status.toString8();
100   EXPECT_EQ(input, out_param);
101   EXPECT_EQ(input, returned);
102 }
103 
TEST_F(AidlTest,ReverseSimpleParcelable)104 TEST_F(AidlTest, ReverseSimpleParcelable) {
105   const vector<SimpleParcelable> original{SimpleParcelable("first", 0),
106                                           SimpleParcelable("second", 1),
107                                           SimpleParcelable("third", 2)};
108   vector<SimpleParcelable> repeated;
109   if (backend == BackendType::JAVA) {
110     repeated = vector<SimpleParcelable>(original.size());
111   }
112   vector<SimpleParcelable> reversed;
113   Status status = service->ReverseSimpleParcelables(original, &repeated, &reversed);
114   ASSERT_TRUE(status.isOk()) << status.toString8();
115 
116   EXPECT_EQ(repeated, original);
117 
118   std::reverse(reversed.begin(), reversed.end());
119   EXPECT_EQ(reversed, original);
120 }
121 
TEST_F(AidlTest,RepeatExtendableParcelable)122 TEST_F(AidlTest, RepeatExtendableParcelable) {
123   MyExt ext;
124   ext.a = 42;
125   ext.b = "EXT";
126   ExtendableParcelable ep;
127   ep.a = 1;
128   ep.b = "a";
129   ep.ext.setParcelable(ext);
130 
131   ExtendableParcelable ep2;
132   Status status = service->RepeatExtendableParcelable(ep, &ep2);
133   ASSERT_TRUE(status.isOk()) << status.toString8();
134 
135   EXPECT_EQ(ep2.a, ep.a);
136   EXPECT_EQ(ep2.b, ep.b);
137 
138   std::shared_ptr<MyExt> ret_ext;
139   ASSERT_EQ(ep2.ext.getParcelable(&ret_ext), OK);
140   ASSERT_TRUE(ret_ext != nullptr);
141 
142   EXPECT_EQ(ret_ext->a, ext.a);
143   EXPECT_EQ(ret_ext->b, ext.b);
144 }
145 
TEST_F(AidlTest,RepeatExtendableParcelableVintf)146 TEST_F(AidlTest, RepeatExtendableParcelableVintf) {
147   VintfParcelable inner;
148   inner.a = 5;
149 
150   VintfExtendableParcelable ext;
151   ext.ext.setParcelable(inner);
152 
153   ExtendableParcelable ep;
154   ep.a = 1;
155   ep.b = "a";
156   ep.ext.setParcelable(ext);
157 
158   ExtendableParcelable ep2;
159   Status status = service->RepeatExtendableParcelableVintf(ep, &ep2);
160   ASSERT_TRUE(status.isOk()) << status.toString8();
161 
162   EXPECT_EQ(ep2.a, ep.a);
163   EXPECT_EQ(ep2.b, ep.b);
164 
165   std::shared_ptr<VintfExtendableParcelable> ret_ext;
166   ASSERT_EQ(ep2.ext.getParcelable(&ret_ext), OK);
167   ASSERT_TRUE(ret_ext != nullptr);
168 
169   std::shared_ptr<VintfParcelable> ret_inner;
170   ASSERT_EQ(ret_ext->ext.getParcelable(&ret_inner), OK);
171   ASSERT_TRUE(ret_inner != nullptr);
172   EXPECT_EQ(ret_inner->a, inner.a);
173 }
174 
TEST_F(AidlTest,ConfirmPersistableBundles)175 TEST_F(AidlTest, ConfirmPersistableBundles) {
176   if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
177 
178   PersistableBundle empty_bundle, returned;
179   Status status = cpp_java_tests->RepeatPersistableBundle(empty_bundle, &returned);
180   ASSERT_TRUE(status.isOk()) << status.toString8();
181   EXPECT_EQ(empty_bundle, returned);
182 }
183 
TEST_F(AidlTest,ConfirmPersistableBundlesNonEmpty)184 TEST_F(AidlTest, ConfirmPersistableBundlesNonEmpty) {
185   if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
186 
187   PersistableBundle non_empty_bundle, returned;
188   non_empty_bundle.putBoolean(String16("test_bool"), false);
189   non_empty_bundle.putInt(String16("test_int"), 33);
190   non_empty_bundle.putLong(String16("test_long"), 34359738368L);
191   non_empty_bundle.putDouble(String16("test_double"), 1.1);
192   non_empty_bundle.putString(String16("test_string"), String16("Woot!"));
193   non_empty_bundle.putBooleanVector(String16("test_bool_vector"),
194                                     {true, false, true});
195   non_empty_bundle.putIntVector(String16("test_int_vector"), {33, 44, 55, 142});
196   non_empty_bundle.putLongVector(String16("test_long_vector"),
197                                  {34L, 8371L, 34359738375L});
198   non_empty_bundle.putDoubleVector(String16("test_double_vector"), {2.2, 5.4});
199   non_empty_bundle.putStringVector(String16("test_string_vector"),
200                                    {String16("hello"), String16("world!")});
201   PersistableBundle nested_bundle;
202   nested_bundle.putInt(String16("test_nested_int"), 345);
203   non_empty_bundle.putPersistableBundle(String16("test_persistable_bundle"),
204                                         nested_bundle);
205 
206   Status status = cpp_java_tests->RepeatPersistableBundle(non_empty_bundle, &returned);
207   ASSERT_TRUE(status.isOk()) << status.toString8();
208   EXPECT_EQ(non_empty_bundle, returned);
209 }
210 
TEST_F(AidlTest,ReversePersistableBundles)211 TEST_F(AidlTest, ReversePersistableBundles) {
212   if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
213 
214   PersistableBundle first;
215   PersistableBundle second;
216   PersistableBundle third;
217   first.putInt(String16("test_int"), 1231);
218   second.putLong(String16("test_long"), 222222L);
219   third.putDouble(String16("test_double"), 10.8);
220   const vector<PersistableBundle> original{first, second, third};
221 
222   vector<PersistableBundle> repeated;
223   if (backend == BackendType::JAVA) {
224     repeated = vector<PersistableBundle>(original.size());
225   }
226   vector<PersistableBundle> reversed;
227   Status status = cpp_java_tests->ReversePersistableBundles(original, &repeated, &reversed);
228   ASSERT_TRUE(status.isOk()) << status.toString8();
229 
230   EXPECT_EQ(repeated, original);
231 
232   std::reverse(reversed.begin(), reversed.end());
233   EXPECT_EQ(reversed, original);
234 }
235 
TEST_F(AidlTest,ReverseUnion)236 TEST_F(AidlTest, ReverseUnion) {
237   if (!cpp_java_tests) GTEST_SKIP() << "Service does not support the CPP/Java-only tests.";
238 
239   Union original = Union::make<Union::ns>({1, 2, 3});
240   Union repeated, reversed;
241   Status status = cpp_java_tests->ReverseUnion(original, &repeated, &reversed);
242   ASSERT_TRUE(status.isOk()) << status.toString8();
243 
244   EXPECT_EQ(repeated, original);
245 
246   std::reverse(reversed.get<Union::ns>().begin(), reversed.get<Union::ns>().end());
247   EXPECT_EQ(reversed, original);
248 }
249 
TEST_F(AidlTest,UnionUsage)250 TEST_F(AidlTest, UnionUsage) {
251   // default ctor inits with first member's default value
252   EXPECT_EQ(Union::make<Union::ns>(), Union());
253 
254   // make<tag>(...) to create a value for a tag.
255   Union one_two_three = Union::make<Union::ns>({1, 2, 3});
256 
257   // getTag() queries the tag of the content
258   EXPECT_EQ(Union::ns, one_two_three.getTag());
259 
260   // Ctor(...) works if a target tag has a unique type among fields.
261   EXPECT_EQ(one_two_three, Union(std::vector{1, 2, 3}));
262   EXPECT_EQ(one_two_three, std::vector<int>({1, 2, 3}));
263 
264   // Use std::in_place_index<tag> to avoid "move"
265   // Note that make<tag>(...) involves "move" of the content value
266   EXPECT_EQ(Union::make<Union::ns>(3, 0),
267             Union(std::in_place_index<static_cast<size_t>(Union::ns)>, 3, 0));
268 
269   Union one_two = one_two_three;
270   // get<tag> can be used to modify the content
271   one_two.get<Union::ns>().pop_back();
272   EXPECT_EQ(one_two, std::vector<int>({1, 2}));
273   // get<tag> can be lvalue
274   one_two.get<Union::ns>() = std::vector<int>{1, 2};
275   EXPECT_EQ(one_two, std::vector<int>({1, 2}));
276 
277   // abort with a bad access
278   EXPECT_DEATH(one_two.get<Union::n>(), "bad access");
279 
280   // set<tag>(...) overwrites the content with a new tag
281   one_two_three.set<Union::s>("123");
282   EXPECT_EQ(one_two_three, std::string("123"));
283 
284   // Or, you can simply assign a new value.
285   // note that this works only if the target type is unique
286   one_two_three = std::vector<std::string>{"1", "2", "3"};
287   EXPECT_EQ(Union::ss, one_two_three.getTag());
288 }
289 
TEST_F(AidlTest,UnionDefaultConstructorInitializeWithFirstMember)290 TEST_F(AidlTest, UnionDefaultConstructorInitializeWithFirstMember) {
291   EXPECT_EQ(Union::make<Union::ns>(), Union());  // int[] ns
292   EXPECT_EQ(EnumUnion::make<EnumUnion::intEnum>(IntEnum::FOO),
293             EnumUnion());  // IntEnum intEnum = IntEnum.FOO
294 }
295 
TEST_F(AidlTest,StructuredParcelableEquality)296 TEST_F(AidlTest, StructuredParcelableEquality) {
297   // TODO: break up equality tests, these are hard to read, because you need to
298   // keep the state of the parcelables in mind
299   StructuredParcelable parcelable1;
300   StructuredParcelable parcelable2;
301 
302   parcelable1.f = 11;
303   parcelable2.f = 11;
304 
305   service->FillOutStructuredParcelable(&parcelable1);
306   service->FillOutStructuredParcelable(&parcelable2);
307 
308   sp<INamedCallback> callback1;
309   sp<INamedCallback> callback2;
310   service->GetOtherTestService(String16("callback1"), &callback1);
311   service->GetOtherTestService(String16("callback2"), &callback2);
312 
313   parcelable1.ibinder = IInterface::asBinder(callback1);
314   parcelable2.ibinder = IInterface::asBinder(callback1);
315 
316   EXPECT_EQ(parcelable1, parcelable2);
317 
318   parcelable1.f = 0;
319   EXPECT_LT(parcelable1, parcelable2);
320   parcelable1.f = 11;
321 
322   parcelable1.shouldBeJerry = "Jarry";
323   EXPECT_LT(parcelable1, parcelable2);
324   parcelable1.shouldBeJerry = "Jerry";
325 
326   parcelable2.shouldContainThreeFs = {};
327   EXPECT_GT(parcelable1, parcelable2);
328   parcelable2.shouldContainThreeFs = {parcelable2.f, parcelable2.f, parcelable2.f};
329 
330   parcelable2.shouldBeIntBar = IntEnum::FOO;
331   EXPECT_GT(parcelable1, parcelable2);
332   parcelable2.shouldBeIntBar = IntEnum::BAR;
333 
334   parcelable2.ibinder = IInterface::asBinder(callback2);
335   EXPECT_NE(parcelable1, parcelable2);
336 }
337 
TEST_F(AidlTest,ConfirmStructuredParcelables)338 TEST_F(AidlTest, ConfirmStructuredParcelables) {
339   constexpr int kDesiredValue = 23;
340 
341   StructuredParcelable parcelable;
342   parcelable.f = kDesiredValue;
343 
344   EXPECT_EQ(parcelable.stringDefaultsToFoo, String16("foo"));
345   EXPECT_EQ(parcelable.byteDefaultsToFour, 4);
346   EXPECT_EQ(parcelable.intDefaultsToFive, 5);
347   EXPECT_EQ(parcelable.longDefaultsToNegativeSeven, -7);
348   EXPECT_EQ(parcelable.booleanDefaultsToTrue, true);
349   EXPECT_EQ(parcelable.charDefaultsToC, 'C');
350   EXPECT_TRUE(parcelable.floatDefaultsToPi == 3.14f) << parcelable.floatDefaultsToPi;
351   EXPECT_TRUE(parcelable.doubleWithDefault == -3.14e17) << parcelable.doubleWithDefault;
352 
353   EXPECT_EQ(parcelable.boolDefault, false);
354   EXPECT_EQ(parcelable.byteDefault, 0);
355   EXPECT_EQ(parcelable.intDefault, 0);
356   EXPECT_EQ(parcelable.longDefault, 0);
357   EXPECT_EQ(parcelable.floatDefault, 0.0f);
358   EXPECT_EQ(parcelable.doubleDefault, 0.0);
359 
360   ASSERT_EQ(parcelable.arrayDefaultsTo123.size(), 3u);
361   EXPECT_EQ(parcelable.arrayDefaultsTo123[0], 1);
362   EXPECT_EQ(parcelable.arrayDefaultsTo123[1], 2);
363   EXPECT_EQ(parcelable.arrayDefaultsTo123[2], 3);
364   EXPECT_TRUE(parcelable.arrayDefaultsToEmpty.empty());
365 
366   EXPECT_EQ(parcelable.defaultWithFoo, IntEnum::FOO);
367 
368   service->FillOutStructuredParcelable(&parcelable);
369 
370   ASSERT_EQ(parcelable.shouldContainThreeFs.size(), 3u);
371   EXPECT_EQ(parcelable.shouldContainThreeFs[0], kDesiredValue);
372   EXPECT_EQ(parcelable.shouldContainThreeFs[1], kDesiredValue);
373   EXPECT_EQ(parcelable.shouldContainThreeFs[2], kDesiredValue);
374 
375   EXPECT_EQ(parcelable.shouldBeJerry, "Jerry");
376   EXPECT_EQ(parcelable.int32_min, INT32_MIN);
377   EXPECT_EQ(parcelable.int32_max, INT32_MAX);
378   EXPECT_EQ(parcelable.int64_max, INT64_MAX);
379   EXPECT_EQ(parcelable.hexInt32_neg_1, -1);
380 
381   for (size_t ndx = 0; ndx < parcelable.int8_1.size(); ndx++) {
382     EXPECT_EQ(parcelable.int8_1[ndx], 1) << ndx;
383   }
384 
385   for (size_t ndx = 0; ndx < parcelable.int32_1.size(); ndx++) {
386     EXPECT_EQ(parcelable.int32_1[ndx], 1) << ndx;
387   }
388 
389   for (size_t ndx = 0; ndx < parcelable.int64_1.size(); ndx++) {
390     EXPECT_EQ(parcelable.int64_1[ndx], 1) << ndx;
391   }
392 
393   EXPECT_EQ(parcelable.hexInt32_pos_1, 1);
394   EXPECT_EQ(parcelable.hexInt64_pos_1, 1);
395 
396   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_1), 1);
397   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_2), 1);
398   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_3), 1);
399   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_4), 1);
400   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_5), 1);
401   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_6), 1);
402   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_7), 1);
403   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_8), 1);
404   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_9), 1);
405   EXPECT_EQ(static_cast<int>(parcelable.const_exprs_10), 1);
406 
407   EXPECT_EQ(parcelable.addString1, "hello world!");
408   EXPECT_EQ(parcelable.addString2, "The quick brown fox jumps over the lazy dog.");
409 
410   EXPECT_EQ(StructuredParcelable::BIT0 | StructuredParcelable::BIT2,
411             parcelable.shouldSetBit0AndBit2);
412 
413   EXPECT_EQ(parcelable.u->get<Union::ns>(), vector<int32_t>({1, 2, 3}));
414   EXPECT_EQ(parcelable.shouldBeConstS1->get<Union::s>(), Union::S1());
415 }
416 
TEST_F(AidlTest,EmptyParcelableHolder)417 TEST_F(AidlTest, EmptyParcelableHolder) {
418   using namespace android::aidl::tests::extension;
419   android::Parcel parcel;
420   {
421     ExtendableParcelable ep;
422     ep.writeToParcel(&parcel);
423     std::shared_ptr<MyExt> emptyExt;
424     ep.ext.getParcelable(&emptyExt);
425     EXPECT_FALSE(emptyExt);
426   }
427   {
428     parcel.setDataPosition(0);
429     ExtendableParcelable ep;
430     ep.readFromParcel(&parcel);
431     std::shared_ptr<MyExt> emptyExt;
432     ep.ext.getParcelable(&emptyExt);
433     EXPECT_FALSE(emptyExt);
434   }
435 }
436 
TEST_F(AidlTest,ParcelableHolderEqualityOperator)437 TEST_F(AidlTest, ParcelableHolderEqualityOperator) {
438   auto ph1 = android::os::ParcelableHolder(android::Parcelable::Stability::STABILITY_LOCAL);
439   auto ph2 = android::os::ParcelableHolder(android::Parcelable::Stability::STABILITY_LOCAL);
440   auto ph3 = android::os::ParcelableHolder(android::Parcelable::Stability::STABILITY_LOCAL);
441   auto ptr1 = std::make_shared<MyExt>();
442   auto ptr2 = std::make_shared<MyExt>();
443   ptr1->a = 1;
444   ptr1->b = "a";
445   ptr2->a = 1;
446   ptr2->b = "a";
447 
448   ph1.setParcelable(ptr1);
449   ph2.setParcelable(ptr1);
450   ph3.setParcelable(ptr2);
451 
452   // ParcelableHolder always uses its address as a comparison criterion.
453   EXPECT_TRUE(ph1 != ph2);
454   EXPECT_TRUE(ph2 != ph3);
455   EXPECT_TRUE(ph1 == ph1);
456   EXPECT_TRUE(ph2 == ph2);
457   EXPECT_TRUE(ph3 == ph3);
458 
459   android::Parcel parcel;
460   ph1.writeToParcel(&parcel);
461   ph2.writeToParcel(&parcel);
462   ph3.writeToParcel(&parcel);
463   parcel.setDataPosition(0);
464 
465   ph1.readFromParcel(&parcel);
466   ph2.readFromParcel(&parcel);
467   ph3.readFromParcel(&parcel);
468 
469   // ParcelableHolder always uses its address as a comparison criterion.
470   EXPECT_TRUE(ph1 != ph2);
471   EXPECT_TRUE(ph2 != ph3);
472   EXPECT_TRUE(ph1 == ph1);
473   EXPECT_TRUE(ph2 == ph2);
474   EXPECT_TRUE(ph3 == ph3);
475 }
476 
TEST_F(AidlTest,NativeExtednableParcelable)477 TEST_F(AidlTest, NativeExtednableParcelable) {
478   using namespace android::aidl::tests::extension;
479   MyExt ext;
480   ext.a = 42;
481   ext.b = "EXT";
482 
483   MyExt2 ext2;
484   ext2.a = 42;
485   ext2.b.a = 24;
486   ext2.b.b = "INEXT";
487   ext2.c = "EXT2";
488   android::Parcel parcel;
489   {
490     ExtendableParcelable ep;
491     ep.a = 1;
492     ep.b = "a";
493     ep.c = 42L;
494 
495     EXPECT_TRUE(ep.ext.setParcelable(ext) == android::OK);
496     EXPECT_TRUE(ep.ext2.setParcelable(ext2) == android::OK);
497 
498     std::shared_ptr<MyExtLike> extLike;
499     ep.ext.getParcelable(&extLike);
500     EXPECT_FALSE(extLike) << "The extension type must be MyExt, so it has to fail even though "
501                              "MyExtLike has the same structure as MyExt.";
502 
503     std::shared_ptr<MyExt> actualExt;
504     ep.ext.getParcelable(&actualExt);
505     std::shared_ptr<MyExt2> actualExt2;
506     ep.ext2.getParcelable(&actualExt2);
507 
508     EXPECT_TRUE(actualExt);
509     EXPECT_TRUE(actualExt2);
510 
511     EXPECT_EQ(ext, *actualExt);
512     EXPECT_EQ(ext2, *actualExt2);
513 
514     ep.writeToParcel(&parcel);
515   }
516 
517   parcel.setDataPosition(0);
518   {
519     ExtendableParcelable ep;
520     ep.readFromParcel(&parcel);
521 
522     std::shared_ptr<MyExtLike> extLike;
523     ep.ext.getParcelable(&extLike);
524     EXPECT_FALSE(extLike) << "The extension type must be MyExt, so it has to fail even though "
525                              "MyExtLike has the same structure as MyExt.";
526 
527     std::shared_ptr<MyExt> actualExt;
528     ep.ext.getParcelable(&actualExt);
529     std::shared_ptr<MyExt2> actualExt2;
530     ep.ext2.getParcelable(&actualExt2);
531 
532     std::shared_ptr<MyExt> emptyExt;
533     ep.ext2.getParcelable(&emptyExt);
534     EXPECT_FALSE(emptyExt);
535 
536     EXPECT_TRUE(actualExt);
537     EXPECT_TRUE(actualExt2);
538 
539     EXPECT_EQ(ext, *actualExt);
540     EXPECT_EQ(ext2, *actualExt2);
541   }
542 }
543 
TEST_F(AidlTest,ParcelableToString)544 TEST_F(AidlTest, ParcelableToString) {
545   ParcelableForToString p;
546   p.intValue = 10;
547   p.intArray = {20, 30};
548   p.longValue = 100L;
549   p.longArray = {200L, 300L};
550   p.doubleValue = 3.14;
551   p.doubleArray = {1.1, 1.2};
552   p.floatValue = 3.14f;
553   p.floatArray = {1.1f, 1.2f};
554   p.byteValue = 3;
555   p.byteArray = {5, 6};
556   p.booleanValue = true;
557   p.booleanArray = {true, false};
558   p.stringValue = String16("this is a string");
559   p.stringArray = {String16("hello"), String16("world")};
560   p.stringList = {String16("alice"), String16("bob")};
561   OtherParcelableForToString op;
562   op.field = String16("other");
563   p.parcelableValue = op;
564   p.parcelableArray = {op, op};
565   p.enumValue = IntEnum::FOO;
566   p.enumArray = {IntEnum::FOO, IntEnum::BAR};
567   // p.nullArray = null;
568   // p.nullList = null;
569   GenericStructuredParcelable<int32_t, StructuredParcelable, IntEnum> gen;
570   gen.a = 1;
571   gen.b = 2;
572   p.parcelableGeneric = gen;
573   p.unionValue = Union(std::vector<std::string>{"union", "value"});
574 
575   const string expected =
576       "ParcelableForToString{"
577       "intValue: 10, "
578       "intArray: [20, 30], "
579       "longValue: 100, "
580       "longArray: [200, 300], "
581       "doubleValue: 3.140000, "
582       "doubleArray: [1.100000, 1.200000], "
583       "floatValue: 3.140000, "
584       "floatArray: [1.100000, 1.200000], "
585       "byteValue: 3, "
586       "byteArray: [5, 6], "
587       "booleanValue: true, "
588       "booleanArray: [true, false], "
589       "stringValue: this is a string, "
590       "stringArray: [hello, world], "
591       "stringList: [alice, bob], "
592       "parcelableValue: OtherParcelableForToString{field: other}, "
593       "parcelableArray: ["
594       "OtherParcelableForToString{field: other}, "
595       "OtherParcelableForToString{field: other}], "
596       "enumValue: FOO, "
597       "enumArray: [FOO, BAR], "
598       "nullArray: [], "
599       "nullList: [], "
600       "parcelableGeneric: GenericStructuredParcelable{a: 1, b: 2}, "
601       "unionValue: Union{ss: [union, value]}"
602       "}";
603 
604   EXPECT_EQ(expected, p.toString());
605 }
606 
TEST_F(AidlTest,ReverseRecursiveList)607 TEST_F(AidlTest, ReverseRecursiveList) {
608   std::unique_ptr<RecursiveList> head;
609   for (int i = 0; i < 10; i++) {
610     auto node = std::make_unique<RecursiveList>();
611     node->value = i;
612     node->next = std::move(head);
613     head = std::move(node);
614   }
615   // head: [9, 8, ... 0]
616 
617   RecursiveList reversed;
618   auto status = service->ReverseList(*head, &reversed);
619   ASSERT_TRUE(status.isOk()) << status.toString8();
620 
621   // reversed should be [0, 1, .. 9]
622   RecursiveList* cur = &reversed;
623   for (int i = 0; i < 10; i++) {
624     EXPECT_EQ(i, cur->value);
625     cur = cur->next.get();
626   }
627   EXPECT_EQ(nullptr, cur);
628 }
629 
TEST_F(AidlTest,GetUnionTags)630 TEST_F(AidlTest, GetUnionTags) {
631   std::vector<Union> unions;
632   std::vector<Union::Tag> tags;
633   // test empty
634   auto status = service->GetUnionTags(unions, &tags);
635   ASSERT_TRUE(status.isOk()) << status.toString8();
636   EXPECT_EQ(tags, (std::vector<Union::Tag>{}));
637   // test non-empty
638   unions.push_back(Union::make<Union::n>());
639   unions.push_back(Union::make<Union::ns>());
640   status = service->GetUnionTags(unions, &tags);
641   ASSERT_TRUE(status.isOk()) << status.toString8();
642   EXPECT_EQ(tags, (std::vector<Union::Tag>{Union::n, Union::ns}));
643 }
644 
TEST_F(AidlTest,FixedSizeArray)645 TEST_F(AidlTest, FixedSizeArray) {
646   android::Parcel parcel;
647 
648   FixedSizeArrayExample p;
649   p.byteMatrix[0][0] = 0;
650   p.byteMatrix[0][1] = 1;
651   p.byteMatrix[1][0] = 2;
652   p.byteMatrix[1][1] = 3;
653   p.floatMatrix[0][0] = 0.f;
654   p.floatMatrix[0][1] = 1.f;
655   p.floatMatrix[1][0] = 2.f;
656   p.floatMatrix[1][1] = 3.f;
657   EXPECT_EQ(OK, p.writeToParcel(&parcel));
658 
659   parcel.setDataPosition(0);
660 
661   FixedSizeArrayExample q;
662   EXPECT_EQ(OK, q.readFromParcel(&parcel));
663   EXPECT_EQ(p, q);
664 }
665 
TEST_F(AidlTest,FixedSizeArrayWithValuesAtNullableFields)666 TEST_F(AidlTest, FixedSizeArrayWithValuesAtNullableFields) {
667   android::Parcel parcel;
668 
669   FixedSizeArrayExample p;
670   p.boolNullableArray = std::array<bool, 2>{true, false};
671   p.byteNullableArray = std::array<uint8_t, 2>{42, 0};
672   p.stringNullableArray = std::array<std::optional<std::string>, 2>{"hello", "world"};
673 
674   p.boolNullableMatrix.emplace();
675   p.boolNullableMatrix->at(0) = std::array<bool, 2>{true, false};
676   p.byteNullableMatrix.emplace();
677   p.byteNullableMatrix->at(0) = std::array<uint8_t, 2>{42, 0};
678   p.stringNullableMatrix.emplace();
679   p.stringNullableMatrix->at(0) = std::array<std::optional<std::string>, 2>{"hello", "world"};
680 
681   EXPECT_EQ(OK, p.writeToParcel(&parcel));
682 
683   parcel.setDataPosition(0);
684 
685   FixedSizeArrayExample q;
686   EXPECT_EQ(OK, q.readFromParcel(&parcel));
687   EXPECT_EQ(p, q);
688 }
689 
TEST_F(AidlTest,FixedSizeArrayOfBytesShouldBePacked)690 TEST_F(AidlTest, FixedSizeArrayOfBytesShouldBePacked) {
691   android::Parcel parcel;
692 
693   std::array<std::array<uint8_t, 3>, 2> byte_array;
694   byte_array[0] = {1, 2, 3};
695   byte_array[1] = {4, 5, 6};
696   EXPECT_EQ(OK, parcel.writeFixedArray(byte_array));
697 
698   parcel.setDataPosition(0);
699 
700   int32_t len;
701   EXPECT_EQ(OK, parcel.readInt32(&len));
702   EXPECT_EQ(2, len);
703   std::vector<uint8_t> byte_vector;
704   EXPECT_EQ(OK, parcel.readByteVector(&byte_vector));
705   EXPECT_EQ(byte_vector, (std::vector<uint8_t>{1, 2, 3}));
706   EXPECT_EQ(OK, parcel.readByteVector(&byte_vector));
707   EXPECT_EQ(byte_vector, (std::vector<uint8_t>{4, 5, 6}));
708 }
709 
710 template <typename Service, typename MemFn, typename Input>
CheckRepeat(Service service,MemFn fn,Input input)711 void CheckRepeat(Service service, MemFn fn, Input input) {
712   Input out1, out2;
713   EXPECT_TRUE(std::invoke(fn, service, input, &out1, &out2).isOk());
714   EXPECT_EQ(input, out1);
715   EXPECT_EQ(input, out2);
716 }
717 
718 template <typename T>
Make2dArray(std::initializer_list<T> values)719 std::array<std::array<T, 3>, 2> Make2dArray(std::initializer_list<T> values) {
720   std::array<std::array<T, 3>, 2> arr = {};
721   auto it = std::begin(values);
722   for (auto& row : arr) {
723     for (auto& el : row) {
724       if (it == std::end(values)) break;
725       el = *it++;
726     }
727   }
728   return arr;
729 }
730 
TEST_F(AidlTest,FixedSizeArrayOverBinder)731 TEST_F(AidlTest, FixedSizeArrayOverBinder) {
732   sp<IRepeatFixedSizeArray> service =
733       android::waitForService<IRepeatFixedSizeArray>(IRepeatFixedSizeArray::descriptor);
734   ASSERT_NE(service, nullptr);
735 
736   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatBytes, (std::array<uint8_t, 3>{1, 2, 3}));
737 
738   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatInts, (std::array<int32_t, 3>{1, 2, 3}));
739 
740   sp<IBinder> binder1 = new BBinder();
741   sp<IBinder> binder2 = new BBinder();
742   sp<IBinder> binder3 = new BBinder();
743   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatBinders,
744               (std::array<sp<IBinder>, 3>{binder1, binder2, binder3}));
745 
746   IntParcelable p1, p2, p3;
747   p1.value = 1;
748   p2.value = 2;
749   p3.value = 3;
750   CheckRepeat(service, &IRepeatFixedSizeArray::RepeatParcelables,
751               (std::array<IntParcelable, 3>{p1, p2, p3}));
752 
753   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dBytes, Make2dArray<uint8_t>({1, 2, 3}));
754 
755   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dInts, Make2dArray<int32_t>({1, 2, 3}));
756 
757   // Not-nullable
758   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dBinders,
759               Make2dArray<sp<IBinder>>({binder1, binder2, binder3, binder1, binder2, binder3}));
760 
761   CheckRepeat(service, &IRepeatFixedSizeArray::Repeat2dParcelables,
762               Make2dArray<IntParcelable>({p1, p2, p3}));
763 }
764