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