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 }