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