1 /*
2 * Copyright (C) 2018 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 #define LOG_TAG "Cts-NdkBinderTest"
17
18 #include <aidl/test_package/BnEmpty.h>
19 #include <aidl/test_package/BpCompatTest.h>
20 #include <aidl/test_package/BpTest.h>
21 #include <aidl/test_package/ByteEnum.h>
22 #include <aidl/test_package/ExtendableParcelable.h>
23 #include <aidl/test_package/FixedSize.h>
24 #include <aidl/test_package/FixedSizeUnion.h>
25 #include <aidl/test_package/Foo.h>
26 #include <aidl/test_package/IntEnum.h>
27 #include <aidl/test_package/LongEnum.h>
28 #include <aidl/test_package/RegularPolygon.h>
29 #include <android/binder_ibinder_jni.h>
30 #include <android/log.h>
31 #include <gtest/gtest.h>
32 #include "itest_impl.h"
33 #include "utilities.h"
34
35 #include <stdio.h>
36 #include <sys/socket.h>
37 #include <sys/types.h>
38 #include <type_traits>
39
40 using ::aidl::test_package::Bar;
41 using ::aidl::test_package::BpTest;
42 using ::aidl::test_package::ByteEnum;
43 using ::aidl::test_package::ExtendableParcelable;
44 using ::aidl::test_package::FixedSize;
45 using ::aidl::test_package::FixedSizeUnion;
46 using ::aidl::test_package::Foo;
47 using ::aidl::test_package::GenericBar;
48 using ::aidl::test_package::ICompatTest;
49 using ::aidl::test_package::IntEnum;
50 using ::aidl::test_package::ITest;
51 using ::aidl::test_package::LongEnum;
52 using ::aidl::test_package::MyExt;
53 using ::aidl::test_package::RegularPolygon;
54 using ::ndk::ScopedAStatus;
55 using ::ndk::ScopedFileDescriptor;
56 using ::ndk::SharedRefBase;
57 using ::ndk::SpAIBinder;
58
59 // This client is built for 32 and 64-bit targets. The size of FixedSize must remain the same.
60 static_assert(sizeof(FixedSize) == 16);
61 static_assert(offsetof(FixedSize, a) == 0);
62 static_assert(offsetof(FixedSize, b) == 8);
63
64 static_assert(sizeof(FixedSizeUnion) == 16); // tag(uint8_t), value(union of {int32_t, long64_t})
65 static_assert(alignof(FixedSizeUnion) == 8);
66
67 static_assert(FixedSizeUnion::fixed_size::value);
68
69 class MyEmpty : public ::aidl::test_package::BnEmpty {};
70 class YourEmpty : public ::aidl::test_package::BnEmpty {};
71
72 // AIDL tests which are independent of the service
73 class NdkBinderTest_AidlLocal : public NdkBinderTest {};
74
TEST_F(NdkBinderTest_AidlLocal,FromBinder)75 TEST_F(NdkBinderTest_AidlLocal, FromBinder) {
76 std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
77 SpAIBinder binder = test->asBinder();
78 EXPECT_EQ(test, ITest::fromBinder(binder));
79
80 EXPECT_FALSE(test->isRemote());
81 }
82
TEST_F(NdkBinderTest_AidlLocal,ConfirmFixedSizeTrue)83 TEST_F(NdkBinderTest_AidlLocal, ConfirmFixedSizeTrue) {
84 bool res = std::is_same<FixedSize::fixed_size, std::true_type>::value;
85 EXPECT_EQ(res, true);
86 }
87
TEST_F(NdkBinderTest_AidlLocal,ConfirmFixedSizeFalse)88 TEST_F(NdkBinderTest_AidlLocal, ConfirmFixedSizeFalse) {
89 bool res = std::is_same<RegularPolygon::fixed_size, std::true_type>::value;
90 EXPECT_EQ(res, false);
91 }
92
93 struct Params {
94 std::shared_ptr<ITest> iface;
95 bool shouldBeRemote;
96 bool shouldBeWrapped;
97 std::string expectedName;
98 bool shouldBeOld;
99 };
100
101 #define iface GetParam().iface
102 #define shouldBeRemote GetParam().shouldBeRemote
103 #define shouldBeWrapped GetParam().shouldBeWrapped
104
105 // AIDL tests which run on each type of service (local C++, local Java, remote C++, remote Java,
106 // etc..)
107 class NdkBinderTest_Aidl : public NdkBinderTest,
108 public ::testing::WithParamInterface<Params> {};
109
TEST_P(NdkBinderTest_Aidl,GotTest)110 TEST_P(NdkBinderTest_Aidl, GotTest) { ASSERT_NE(nullptr, iface); }
111
TEST_P(NdkBinderTest_Aidl,SanityCheckSource)112 TEST_P(NdkBinderTest_Aidl, SanityCheckSource) {
113 std::string name;
114 ASSERT_OK(iface->GetName(&name));
115 EXPECT_EQ(GetParam().expectedName, name);
116 }
117
TEST_P(NdkBinderTest_Aidl,Remoteness)118 TEST_P(NdkBinderTest_Aidl, Remoteness) {
119 ASSERT_EQ(shouldBeRemote, iface->isRemote());
120 }
121
TEST_P(NdkBinderTest_Aidl,UseBinder)122 TEST_P(NdkBinderTest_Aidl, UseBinder) {
123 ASSERT_EQ(STATUS_OK, AIBinder_ping(iface->asBinder().get()));
124 }
125
TEST_P(NdkBinderTest_Aidl,GetExtension)126 TEST_P(NdkBinderTest_Aidl, GetExtension) {
127 SpAIBinder ext;
128 ASSERT_EQ(STATUS_OK, AIBinder_getExtension(iface->asBinder().get(), ext.getR()));
129
130 // TODO(b/139325468): add support in Java as well
131 if (GetParam().expectedName == "CPP") {
132 EXPECT_EQ(STATUS_OK, AIBinder_ping(ext.get()));
133 } else {
134 ASSERT_EQ(nullptr, ext.get());
135 }
136 }
137
ReadFdToString(int fd,std::string * content)138 bool ReadFdToString(int fd, std::string* content) {
139 char buf[64];
140 ssize_t n;
141 while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
142 content->append(buf, n);
143 }
144 return (n == 0) ? true : false;
145 }
146
dumpToString(std::shared_ptr<ITest> itest,std::vector<const char * > args)147 std::string dumpToString(std::shared_ptr<ITest> itest, std::vector<const char*> args) {
148 int fd[2] = {-1, -1};
149 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, fd));
150
151 EXPECT_OK(itest->dump(fd[0], args.data(), args.size()));
152 close(fd[0]);
153
154 std::string ret;
155 EXPECT_TRUE(ReadFdToString(fd[1], &ret));
156
157 close(fd[1]);
158 return ret;
159 }
160
getCompatTest(std::shared_ptr<ITest> itest)161 auto getCompatTest(std::shared_ptr<ITest> itest) {
162 SpAIBinder binder;
163 itest->getICompatTest(&binder);
164 return ICompatTest::fromBinder(binder);
165 }
166
TEST_P(NdkBinderTest_Aidl,UseDump)167 TEST_P(NdkBinderTest_Aidl, UseDump) {
168 std::string name;
169 EXPECT_OK(iface->GetName(&name));
170 if (name == "JAVA" && !iface->isRemote()) {
171 // TODO(b/127361166): GTEST_SKIP is considered a failure, would prefer to use that here
172 // TODO(b/127339049): JavaBBinder doesn't implement dump
173 return;
174 }
175
176 EXPECT_EQ("", dumpToString(iface, {}));
177 EXPECT_EQ("", dumpToString(iface, {"", ""}));
178 EXPECT_EQ("Hello World!", dumpToString(iface, {"Hello ", "World!"}));
179 EXPECT_EQ("ABC", dumpToString(iface, {"A", "B", "C"}));
180 }
181
TEST_P(NdkBinderTest_Aidl,Trivial)182 TEST_P(NdkBinderTest_Aidl, Trivial) {
183 ASSERT_OK(iface->TestVoidReturn());
184
185 if (shouldBeWrapped) {
186 ASSERT_OK(iface->TestOneway());
187 } else {
188 ASSERT_EQ(STATUS_UNKNOWN_ERROR, AStatus_getStatus(iface->TestOneway().get()));
189 }
190 }
191
TEST_P(NdkBinderTest_Aidl,CallingInfo)192 TEST_P(NdkBinderTest_Aidl, CallingInfo) {
193 EXPECT_OK(iface->CacheCallingInfoFromOneway());
194 int32_t res;
195
196 EXPECT_OK(iface->GiveMeMyCallingPid(&res));
197 EXPECT_EQ(getpid(), res);
198
199 EXPECT_OK(iface->GiveMeMyCallingUid(&res));
200 EXPECT_EQ(getuid(), res);
201
202 EXPECT_OK(iface->GiveMeMyCallingPidFromOneway(&res));
203 if (shouldBeRemote) {
204 // PID is hidden from oneway calls
205 EXPECT_EQ(0, res);
206 } else {
207 EXPECT_EQ(getpid(), res);
208 }
209
210 EXPECT_OK(iface->GiveMeMyCallingUidFromOneway(&res));
211 EXPECT_EQ(getuid(), res);
212 }
213
TEST_P(NdkBinderTest_Aidl,ConstantsInInterface)214 TEST_P(NdkBinderTest_Aidl, ConstantsInInterface) {
215 ASSERT_EQ(0, ITest::kZero);
216 ASSERT_EQ(1, ITest::kOne);
217 ASSERT_EQ(0xffffffff, ITest::kOnes);
218 ASSERT_EQ(1, ITest::kByteOne);
219 ASSERT_EQ(0xffffffffffffffff, ITest::kLongOnes);
220 ASSERT_EQ(std::string(""), ITest::kEmpty);
221 ASSERT_EQ(std::string("foo"), ITest::kFoo);
222 }
223
TEST_P(NdkBinderTest_Aidl,ConstantsInParcelable)224 TEST_P(NdkBinderTest_Aidl, ConstantsInParcelable) {
225 ASSERT_EQ(0, Foo::kZero);
226 ASSERT_EQ(1, Foo::kOne);
227 ASSERT_EQ(0xffffffff, Foo::kOnes);
228 ASSERT_EQ(1, Foo::kByteOne);
229 ASSERT_EQ(0xffffffffffffffff, Foo::kLongOnes);
230 ASSERT_EQ(std::string(""), Foo::kEmpty);
231 ASSERT_EQ(std::string("foo"), Foo::kFoo);
232 }
233
TEST_P(NdkBinderTest_Aidl,ConstantsInUnion)234 TEST_P(NdkBinderTest_Aidl, ConstantsInUnion) {
235 ASSERT_EQ(0, SimpleUnion::kZero);
236 ASSERT_EQ(1, SimpleUnion::kOne);
237 ASSERT_EQ(0xffffffff, SimpleUnion::kOnes);
238 ASSERT_EQ(1, SimpleUnion::kByteOne);
239 ASSERT_EQ(0xffffffffffffffff, SimpleUnion::kLongOnes);
240 ASSERT_EQ(std::string(""), SimpleUnion::kEmpty);
241 ASSERT_EQ(std::string("foo"), SimpleUnion::kFoo);
242 }
243
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveInt)244 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveInt) {
245 int32_t out;
246 ASSERT_OK(iface->RepeatInt(3, &out));
247 EXPECT_EQ(3, out);
248 }
249
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveLong)250 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveLong) {
251 int64_t out;
252 ASSERT_OK(iface->RepeatLong(3, &out));
253 EXPECT_EQ(3, out);
254 }
255
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveFloat)256 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveFloat) {
257 float out;
258 ASSERT_OK(iface->RepeatFloat(2.0f, &out));
259 EXPECT_EQ(2.0f, out);
260 }
261
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveDouble)262 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveDouble) {
263 double out;
264 ASSERT_OK(iface->RepeatDouble(3.0, &out));
265 EXPECT_EQ(3.0, out);
266 }
267
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveBoolean)268 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveBoolean) {
269 bool out;
270 ASSERT_OK(iface->RepeatBoolean(true, &out));
271 EXPECT_EQ(true, out);
272 }
273
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveChar)274 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveChar) {
275 char16_t out;
276 ASSERT_OK(iface->RepeatChar(L'@', &out));
277 EXPECT_EQ(L'@', out);
278 }
279
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveByte)280 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveByte) {
281 int8_t out;
282 ASSERT_OK(iface->RepeatByte(3, &out));
283 EXPECT_EQ(3, out);
284 }
285
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveByteEnum)286 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveByteEnum) {
287 ByteEnum out;
288 ASSERT_OK(iface->RepeatByteEnum(ByteEnum::FOO, &out));
289 EXPECT_EQ(ByteEnum::FOO, out);
290 }
291
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveIntEnum)292 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveIntEnum) {
293 IntEnum out;
294 ASSERT_OK(iface->RepeatIntEnum(IntEnum::FOO, &out));
295 EXPECT_EQ(IntEnum::FOO, out);
296 }
297
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveLongEnum)298 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveLongEnum) {
299 LongEnum out;
300 ASSERT_OK(iface->RepeatLongEnum(LongEnum::FOO, &out));
301 EXPECT_EQ(LongEnum::FOO, out);
302 }
303
TEST_P(NdkBinderTest_Aidl,EnumToString)304 TEST_P(NdkBinderTest_Aidl, EnumToString) {
305 EXPECT_EQ(toString(ByteEnum::FOO), "FOO");
306 EXPECT_EQ(toString(IntEnum::BAR), "BAR");
307 EXPECT_EQ(toString(LongEnum::FOO), "FOO");
308
309 EXPECT_EQ(toString(static_cast<IntEnum>(-1)), "-1");
310 }
311
TEST_P(NdkBinderTest_Aidl,EnumValues)312 TEST_P(NdkBinderTest_Aidl, EnumValues) {
313 auto range = ::ndk::enum_range<ByteEnum>();
314 auto iter = range.begin();
315 EXPECT_EQ(ByteEnum::FOO, *iter++);
316 EXPECT_EQ(ByteEnum::BAR, *iter++);
317 EXPECT_EQ(range.end(), iter);
318 }
319
TEST_P(NdkBinderTest_Aidl,RepeatBinder)320 TEST_P(NdkBinderTest_Aidl, RepeatBinder) {
321 SpAIBinder binder = iface->asBinder();
322 SpAIBinder ret;
323
324 ASSERT_OK(iface->RepeatBinder(binder, &ret));
325 EXPECT_EQ(binder.get(), ret.get());
326
327 if (shouldBeWrapped) {
328 ndk::ScopedAStatus status = iface->RepeatBinder(nullptr, &ret);
329 ASSERT_EQ(STATUS_UNEXPECTED_NULL, AStatus_getStatus(status.get()));
330 } else {
331 ASSERT_OK(iface->RepeatBinder(nullptr, &ret));
332 EXPECT_EQ(nullptr, ret.get());
333 }
334
335 ASSERT_OK(iface->RepeatNullableBinder(binder, &ret));
336 EXPECT_EQ(binder.get(), ret.get());
337
338 ASSERT_OK(iface->RepeatNullableBinder(nullptr, &ret));
339 EXPECT_EQ(nullptr, ret.get());
340 }
341
TEST_P(NdkBinderTest_Aidl,RepeatInterface)342 TEST_P(NdkBinderTest_Aidl, RepeatInterface) {
343 std::shared_ptr<IEmpty> empty = SharedRefBase::make<MyEmpty>();
344
345 std::shared_ptr<IEmpty> ret;
346 ASSERT_OK(iface->RepeatInterface(empty, &ret));
347 EXPECT_EQ(empty.get(), ret.get());
348
349 // b/210547999
350 // interface writes are always nullable in AIDL C++ (but reads are not
351 // nullable by default). However, the NDK backend follows the Java behavior
352 // and always allows interfaces to be nullable (for reads and writes).
353 ASSERT_OK(iface->RepeatInterface(nullptr, &ret));
354 EXPECT_EQ(nullptr, ret.get());
355
356 ASSERT_OK(iface->RepeatNullableInterface(empty, &ret));
357 EXPECT_EQ(empty.get(), ret.get());
358
359 ASSERT_OK(iface->RepeatNullableInterface(nullptr, &ret));
360 EXPECT_EQ(nullptr, ret.get());
361 }
362
checkInOut(const ScopedFileDescriptor & inFd,const ScopedFileDescriptor & outFd)363 static void checkInOut(const ScopedFileDescriptor& inFd,
364 const ScopedFileDescriptor& outFd) {
365 static const std::string kContent = "asdf";
366
367 ASSERT_EQ(static_cast<int>(kContent.size()),
368 write(inFd.get(), kContent.data(), kContent.size()));
369
370 std::string out;
371 out.resize(kContent.size());
372 ASSERT_EQ(static_cast<int>(kContent.size()),
373 read(outFd.get(), &out[0], kContent.size()));
374
375 EXPECT_EQ(kContent, out);
376 }
377
checkFdRepeat(const std::shared_ptr<ITest> & test,ScopedAStatus (ITest::* repeatFd)(const ScopedFileDescriptor &,ScopedFileDescriptor *))378 static void checkFdRepeat(
379 const std::shared_ptr<ITest>& test,
380 ScopedAStatus (ITest::*repeatFd)(const ScopedFileDescriptor&,
381 ScopedFileDescriptor*)) {
382 int fds[2];
383
384 while (pipe(fds) == -1 && errno == EAGAIN)
385 ;
386
387 ScopedFileDescriptor readFd(fds[0]);
388 ScopedFileDescriptor writeFd(fds[1]);
389
390 ScopedFileDescriptor readOutFd;
391 ASSERT_OK((test.get()->*repeatFd)(readFd, &readOutFd));
392
393 checkInOut(writeFd, readOutFd);
394 }
395
TEST_P(NdkBinderTest_Aidl,RepeatFdArray)396 TEST_P(NdkBinderTest_Aidl, RepeatFdArray) {
397 int fds[2];
398
399 while (pipe(fds) == -1 && errno == EAGAIN)
400 ;
401 std::vector<ScopedFileDescriptor> sfds;
402 sfds.emplace_back(fds[0]);
403 sfds.emplace_back(fds[1]);
404
405 std::vector<ScopedFileDescriptor> sfds_out1;
406 sfds_out1.resize(sfds.size());
407 std::vector<ScopedFileDescriptor> sfds_out2;
408
409 ASSERT_OK((iface->RepeatFdArray(sfds, &sfds_out1, &sfds_out2)));
410
411 // sfds <-> sfds_out1
412 checkInOut(sfds[1], sfds_out1[0]);
413 checkInOut(sfds_out1[1], sfds[0]);
414
415 // sfds_out1 <-> sfds_out2
416 checkInOut(sfds_out1[1], sfds_out2[0]);
417 checkInOut(sfds_out2[1], sfds_out1[0]);
418
419 // sfds <-> sfds_out2
420 checkInOut(sfds[1], sfds_out2[0]);
421 checkInOut(sfds_out2[1], sfds[0]);
422 }
423
TEST_P(NdkBinderTest_Aidl,RepeatFd)424 TEST_P(NdkBinderTest_Aidl, RepeatFd) { checkFdRepeat(iface, &ITest::RepeatFd); }
425
TEST_P(NdkBinderTest_Aidl,RepeatFdNull)426 TEST_P(NdkBinderTest_Aidl, RepeatFdNull) {
427 ScopedFileDescriptor fd;
428 // FD is different from most types because the standard type used to represent
429 // it can also contain a null value (this is why many other types don't have
430 // 'null' tests for the non-@nullable Repeat* functions).
431 //
432 // Even worse, these are default initialized to this value, so it's a pretty
433 // common error:
434 EXPECT_EQ(fd.get(), -1);
435 ScopedFileDescriptor out;
436
437 if (shouldBeWrapped) {
438 ASSERT_EQ(STATUS_UNEXPECTED_NULL, AStatus_getStatus(iface->RepeatFd(fd, &out).get()));
439 } else {
440 // another in/out-process difference
441 ASSERT_OK(iface->RepeatFd(fd, &out));
442 }
443 }
444
TEST_P(NdkBinderTest_Aidl,RepeatNullableFd)445 TEST_P(NdkBinderTest_Aidl, RepeatNullableFd) {
446 checkFdRepeat(iface, &ITest::RepeatNullableFd);
447
448 ScopedFileDescriptor in;
449 EXPECT_EQ(-1, in.get());
450
451 ScopedFileDescriptor out;
452 ASSERT_OK(iface->RepeatNullableFd(in, &out));
453
454 EXPECT_EQ(-1, out.get());
455 }
456
TEST_P(NdkBinderTest_Aidl,RepeatString)457 TEST_P(NdkBinderTest_Aidl, RepeatString) {
458 std::string res;
459
460 EXPECT_OK(iface->RepeatString("", &res));
461 EXPECT_EQ("", res);
462
463 EXPECT_OK(iface->RepeatString("a", &res));
464 EXPECT_EQ("a", res);
465
466 EXPECT_OK(iface->RepeatString("say what?", &res));
467 EXPECT_EQ("say what?", res);
468
469 std::string stringWithNulls = "asdf";
470 stringWithNulls[1] = '\0';
471
472 EXPECT_OK(iface->RepeatString(stringWithNulls, &res));
473 EXPECT_EQ(stringWithNulls, res);
474 }
475
TEST_P(NdkBinderTest_Aidl,RepeatNullableString)476 TEST_P(NdkBinderTest_Aidl, RepeatNullableString) {
477 std::optional<std::string> res;
478
479 EXPECT_OK(iface->RepeatNullableString(std::nullopt, &res));
480 EXPECT_EQ(std::nullopt, res);
481
482 EXPECT_OK(iface->RepeatNullableString("", &res));
483 EXPECT_EQ("", *res);
484
485 EXPECT_OK(iface->RepeatNullableString("a", &res));
486 EXPECT_EQ("a", *res);
487
488 EXPECT_OK(iface->RepeatNullableString("say what?", &res));
489 EXPECT_EQ("say what?", *res);
490 }
491
TEST_P(NdkBinderTest_Aidl,ParcelableOrder)492 TEST_P(NdkBinderTest_Aidl, ParcelableOrder) {
493 RegularPolygon p1 = {"A", 1, 1.0f};
494
495 // tests on self
496 EXPECT_EQ(p1, p1);
497 EXPECT_LE(p1, p1);
498 EXPECT_GE(p1, p1);
499 EXPECT_FALSE(p1 < p1);
500 EXPECT_FALSE(p1 > p1);
501
502 RegularPolygon p2 = {"A", 2, 1.0f};
503 RegularPolygon p3 = {"B", 1, 1.0f};
504 for (const auto& bigger : {p2, p3}) {
505 EXPECT_FALSE(p1 == bigger);
506 EXPECT_LE(p1, bigger);
507 EXPECT_GE(bigger, p1);
508 EXPECT_LT(p1, bigger);
509 EXPECT_GT(bigger, p1);
510 }
511 }
512
TEST_P(NdkBinderTest_Aidl,ParcelableDefaults)513 TEST_P(NdkBinderTest_Aidl, ParcelableDefaults) {
514 RegularPolygon polygon;
515
516 EXPECT_EQ("square", polygon.name);
517 EXPECT_EQ(4, polygon.numSides);
518 EXPECT_EQ(1.0f, polygon.sideLength);
519 }
520
TEST_P(NdkBinderTest_Aidl,RepeatPolygon)521 TEST_P(NdkBinderTest_Aidl, RepeatPolygon) {
522 RegularPolygon defaultPolygon = {"hexagon", 6, 2.0f};
523 RegularPolygon outputPolygon;
524 ASSERT_OK(iface->RepeatPolygon(defaultPolygon, &outputPolygon));
525 EXPECT_EQ(defaultPolygon, outputPolygon);
526 }
527
TEST_P(NdkBinderTest_Aidl,RepeatNullNullablePolygon)528 TEST_P(NdkBinderTest_Aidl, RepeatNullNullablePolygon) {
529 std::optional<RegularPolygon> defaultPolygon;
530 std::optional<RegularPolygon> outputPolygon;
531 ASSERT_OK(iface->RepeatNullablePolygon(defaultPolygon, &outputPolygon));
532 EXPECT_EQ(defaultPolygon, outputPolygon);
533 }
534
TEST_P(NdkBinderTest_Aidl,RepeatPresentNullablePolygon)535 TEST_P(NdkBinderTest_Aidl, RepeatPresentNullablePolygon) {
536 std::optional<RegularPolygon> defaultPolygon =
537 std::optional<RegularPolygon>({"septagon", 7, 3.0f});
538 std::optional<RegularPolygon> outputPolygon;
539 ASSERT_OK(iface->RepeatNullablePolygon(defaultPolygon, &outputPolygon));
540 EXPECT_EQ(defaultPolygon, outputPolygon);
541 }
542
TEST_P(NdkBinderTest_Aidl,InsAndOuts)543 TEST_P(NdkBinderTest_Aidl, InsAndOuts) {
544 RegularPolygon defaultPolygon;
545 ASSERT_OK(iface->RenamePolygon(&defaultPolygon, "Jerry"));
546 EXPECT_EQ("Jerry", defaultPolygon.name);
547 }
548
TEST_P(NdkBinderTest_Aidl,NewField)549 TEST_P(NdkBinderTest_Aidl, NewField) {
550 Baz baz;
551 baz.d = {"a", "b", "c"};
552
553 Baz outbaz;
554
555 ASSERT_OK(getCompatTest(iface)->repeatBaz(baz, &outbaz));
556
557 if (GetParam().shouldBeOld) {
558 EXPECT_EQ(std::nullopt, outbaz.d);
559 } else {
560 EXPECT_EQ(baz.d, outbaz.d);
561 }
562 }
563
TEST_P(NdkBinderTest_Aidl,RenameFoo)564 TEST_P(NdkBinderTest_Aidl, RenameFoo) {
565 Foo foo;
566 Foo outputFoo;
567 ASSERT_OK(iface->renameFoo(&foo, "MYFOO"));
568
569 EXPECT_EQ("MYFOO", foo.a);
570 }
571
TEST_P(NdkBinderTest_Aidl,RenameBar)572 TEST_P(NdkBinderTest_Aidl, RenameBar) {
573 Foo foo;
574 Foo outputFoo;
575 ASSERT_OK(iface->renameBar(&foo, "MYBAR"));
576
577 EXPECT_EQ("MYBAR", foo.d.a);
578 }
579
TEST_P(NdkBinderTest_Aidl,GetLastItem)580 TEST_P(NdkBinderTest_Aidl, GetLastItem) {
581 Foo foo;
582 foo.f = 15;
583 int retF;
584 ASSERT_OK(iface->getF(foo, &retF));
585 EXPECT_EQ(15, retF);
586 }
587
TEST_P(NdkBinderTest_Aidl,RepeatFoo)588 TEST_P(NdkBinderTest_Aidl, RepeatFoo) {
589 Foo foo;
590 foo.a = "NEW FOO";
591 foo.b = 57;
592 foo.d.b = "a";
593 foo.e.d = 99;
594 foo.shouldBeByteBar = ByteEnum::BAR;
595 foo.shouldBeIntBar = IntEnum::BAR;
596 foo.shouldBeLongBar = LongEnum::BAR;
597 foo.shouldContainTwoByteFoos = {ByteEnum::FOO, ByteEnum::FOO};
598 foo.shouldContainTwoIntFoos = {IntEnum::FOO, IntEnum::FOO};
599 foo.shouldContainTwoLongFoos = {LongEnum::FOO, LongEnum::FOO};
600 foo.u = SimpleUnion::make<SimpleUnion::c>("hello");
601 foo.shouldSetBit0AndBit2 = Foo::BIT0 | Foo::BIT2;
602 foo.shouldBeConstS1 = SimpleUnion::S1;
603
604 Foo retFoo;
605
606 ASSERT_OK(iface->repeatFoo(foo, &retFoo));
607
608 EXPECT_EQ(foo.a, retFoo.a);
609 EXPECT_EQ(foo.b, retFoo.b);
610 EXPECT_EQ(foo.d.b, retFoo.d.b);
611 EXPECT_EQ(foo.e.d, retFoo.e.d);
612 EXPECT_EQ(foo.shouldBeByteBar, retFoo.shouldBeByteBar);
613 EXPECT_EQ(foo.shouldBeIntBar, retFoo.shouldBeIntBar);
614 EXPECT_EQ(foo.shouldBeLongBar, retFoo.shouldBeLongBar);
615 EXPECT_EQ(foo.shouldContainTwoByteFoos, retFoo.shouldContainTwoByteFoos);
616 EXPECT_EQ(foo.shouldContainTwoIntFoos, retFoo.shouldContainTwoIntFoos);
617 EXPECT_EQ(foo.shouldContainTwoLongFoos, retFoo.shouldContainTwoLongFoos);
618 EXPECT_EQ(foo.u, retFoo.u);
619 EXPECT_EQ(foo.shouldSetBit0AndBit2, retFoo.shouldSetBit0AndBit2);
620 EXPECT_EQ(foo.shouldBeConstS1, retFoo.shouldBeConstS1);
621 }
622
TEST_P(NdkBinderTest_Aidl,RepeatGenericBar)623 TEST_P(NdkBinderTest_Aidl, RepeatGenericBar) {
624 GenericBar<int32_t> bar;
625 bar.a = 40;
626 bar.shouldBeGenericFoo.a = 41;
627 bar.shouldBeGenericFoo.b = 42;
628
629 GenericBar<int32_t> retBar;
630
631 ASSERT_OK(iface->repeatGenericBar(bar, &retBar));
632
633 EXPECT_EQ(bar.a, retBar.a);
634 EXPECT_EQ(bar.shouldBeGenericFoo.a, retBar.shouldBeGenericFoo.a);
635 EXPECT_EQ(bar.shouldBeGenericFoo.b, retBar.shouldBeGenericFoo.b);
636 }
637
638 template <typename T>
639 using RepeatMethod = ScopedAStatus (ITest::*)(const std::vector<T>&,
640 std::vector<T>*, std::vector<T>*);
641
642 template <typename T>
testRepeat(const std::shared_ptr<ITest> & i,RepeatMethod<T> repeatMethod,std::vector<std::vector<T>> tests)643 void testRepeat(const std::shared_ptr<ITest>& i, RepeatMethod<T> repeatMethod,
644 std::vector<std::vector<T>> tests) {
645 for (const auto& input : tests) {
646 std::vector<T> out1;
647 out1.resize(input.size());
648 std::vector<T> out2;
649
650 ASSERT_OK((i.get()->*repeatMethod)(input, &out1, &out2)) << input.size();
651 EXPECT_EQ(input, out1);
652 EXPECT_EQ(input, out2);
653 }
654 }
655
656 template <typename T>
testRepeat2List(const std::shared_ptr<ITest> & i,RepeatMethod<T> repeatMethod,std::vector<std::vector<T>> tests)657 void testRepeat2List(const std::shared_ptr<ITest>& i, RepeatMethod<T> repeatMethod,
658 std::vector<std::vector<T>> tests) {
659 for (const auto& input : tests) {
660 std::vector<T> out1;
661 std::vector<T> out2;
662 std::vector<T> expected;
663
664 expected.insert(expected.end(), input.begin(), input.end());
665 expected.insert(expected.end(), input.begin(), input.end());
666
667 ASSERT_OK((i.get()->*repeatMethod)(input, &out1, &out2)) << expected.size();
668 EXPECT_EQ(expected, out1);
669 EXPECT_EQ(expected, out2);
670 }
671 }
672
TEST_P(NdkBinderTest_Aidl,Arrays)673 TEST_P(NdkBinderTest_Aidl, Arrays) {
674 testRepeat<bool>(iface, &ITest::RepeatBooleanArray,
675 {
676 {},
677 {true},
678 {false, true, false},
679 });
680 testRepeat<uint8_t>(iface, &ITest::RepeatByteArray,
681 {
682 {},
683 {1},
684 {1, 2, 3},
685 });
686 testRepeat<char16_t>(iface, &ITest::RepeatCharArray,
687 {
688 {},
689 {L'@'},
690 {L'@', L'!', L'A'},
691 });
692 testRepeat<int32_t>(iface, &ITest::RepeatIntArray,
693 {
694 {},
695 {1},
696 {1, 2, 3},
697 });
698 testRepeat<int64_t>(iface, &ITest::RepeatLongArray,
699 {
700 {},
701 {1},
702 {1, 2, 3},
703 });
704 testRepeat<float>(iface, &ITest::RepeatFloatArray,
705 {
706 {},
707 {1.0f},
708 {1.0f, 2.0f, 3.0f},
709 });
710 testRepeat<double>(iface, &ITest::RepeatDoubleArray,
711 {
712 {},
713 {1.0},
714 {1.0, 2.0, 3.0},
715 });
716 testRepeat<ByteEnum>(iface, &ITest::RepeatByteEnumArray,
717 {
718 {},
719 {ByteEnum::FOO},
720 {ByteEnum::FOO, ByteEnum::BAR},
721 });
722 testRepeat<IntEnum>(iface, &ITest::RepeatIntEnumArray,
723 {
724 {},
725 {IntEnum::FOO},
726 {IntEnum::FOO, IntEnum::BAR},
727 });
728 testRepeat<LongEnum>(iface, &ITest::RepeatLongEnumArray,
729 {
730 {},
731 {LongEnum::FOO},
732 {LongEnum::FOO, LongEnum::BAR},
733 });
734 testRepeat<std::string>(iface, &ITest::RepeatStringArray,
735 {
736 {},
737 {"asdf"},
738 {"", "aoeu", "lol", "brb"},
739 });
740 testRepeat<RegularPolygon>(iface, &ITest::RepeatRegularPolygonArray,
741 {
742 {},
743 {{"hexagon", 6, 2.0f}},
744 {{"hexagon", 6, 2.0f}, {"square", 4, 7.0f}, {"pentagon", 5, 4.2f}},
745 });
746 std::shared_ptr<IEmpty> my_empty = SharedRefBase::make<MyEmpty>();
747 testRepeat<SpAIBinder>(iface, &ITest::RepeatBinderArray,
748 {
749 {},
750 {iface->asBinder()},
751 {iface->asBinder(), my_empty->asBinder()},
752 });
753
754 std::shared_ptr<IEmpty> your_empty = SharedRefBase::make<YourEmpty>();
755 testRepeat<std::shared_ptr<IEmpty>>(iface, &ITest::RepeatInterfaceArray,
756 {
757 {},
758 {my_empty},
759 {my_empty, your_empty},
760 // Legacy behavior: allow null for non-nullable interface
761 {my_empty, your_empty, nullptr},
762 });
763 }
764
TEST_P(NdkBinderTest_Aidl,Lists)765 TEST_P(NdkBinderTest_Aidl, Lists) {
766 testRepeat2List<std::string>(iface, &ITest::Repeat2StringList,
767 {
768 {},
769 {"asdf"},
770 {"", "aoeu", "lol", "brb"},
771 });
772 testRepeat2List<RegularPolygon>(
773 iface, &ITest::Repeat2RegularPolygonList,
774 {
775 {},
776 {{"hexagon", 6, 2.0f}},
777 {{"hexagon", 6, 2.0f}, {"square", 4, 7.0f}, {"pentagon", 5, 4.2f}},
778 });
779 }
780
781 template <typename T>
782 using RepeatNullableMethod = ScopedAStatus (ITest::*)(
783 const std::optional<std::vector<std::optional<T>>>&,
784 std::optional<std::vector<std::optional<T>>>*,
785 std::optional<std::vector<std::optional<T>>>*);
786
787 template <typename T>
testRepeat(const std::shared_ptr<ITest> & i,RepeatNullableMethod<T> repeatMethod,std::vector<std::optional<std::vector<std::optional<T>>>> tests)788 void testRepeat(
789 const std::shared_ptr<ITest>& i, RepeatNullableMethod<T> repeatMethod,
790 std::vector<std::optional<std::vector<std::optional<T>>>> tests) {
791 for (const auto& input : tests) {
792 std::optional<std::vector<std::optional<T>>> out1;
793 if (input) {
794 out1 = std::vector<std::optional<T>>{};
795 out1->resize(input->size());
796 }
797 std::optional<std::vector<std::optional<T>>> out2;
798
799 ASSERT_OK((i.get()->*repeatMethod)(input, &out1, &out2))
800 << (input ? input->size() : -1);
801 EXPECT_EQ(input, out1);
802 EXPECT_EQ(input, out2);
803 }
804 }
805
806 template <typename T>
807 using SingleRepeatNullableMethod = ScopedAStatus (ITest::*)(
808 const std::optional<std::vector<T>>&, std::optional<std::vector<T>>*);
809
810 template <typename T>
testRepeat(const std::shared_ptr<ITest> & i,SingleRepeatNullableMethod<T> repeatMethod,std::vector<std::optional<std::vector<T>>> tests)811 void testRepeat(const std::shared_ptr<ITest>& i,
812 SingleRepeatNullableMethod<T> repeatMethod,
813 std::vector<std::optional<std::vector<T>>> tests) {
814 for (const auto& input : tests) {
815 std::optional<std::vector<T>> ret;
816 ASSERT_OK((i.get()->*repeatMethod)(input, &ret))
817 << (input ? input->size() : -1);
818 EXPECT_EQ(input, ret);
819 }
820 }
821
TEST_P(NdkBinderTest_Aidl,NullableArrays)822 TEST_P(NdkBinderTest_Aidl, NullableArrays) {
823 testRepeat<bool>(iface, &ITest::RepeatNullableBooleanArray,
824 {
825 std::nullopt,
826 {{}},
827 {{true}},
828 {{false, true, false}},
829 });
830 testRepeat<uint8_t>(iface, &ITest::RepeatNullableByteArray,
831 {
832 std::nullopt,
833 {{}},
834 {{1}},
835 {{1, 2, 3}},
836 });
837 testRepeat<char16_t>(iface, &ITest::RepeatNullableCharArray,
838 {
839 std::nullopt,
840 {{}},
841 {{L'@'}},
842 {{L'@', L'!', L'A'}},
843 });
844 testRepeat<int32_t>(iface, &ITest::RepeatNullableIntArray,
845 {
846 std::nullopt,
847 {{}},
848 {{1}},
849 {{1, 2, 3}},
850 });
851 testRepeat<int64_t>(iface, &ITest::RepeatNullableLongArray,
852 {
853 std::nullopt,
854 {{}},
855 {{1}},
856 {{1, 2, 3}},
857 });
858 testRepeat<float>(iface, &ITest::RepeatNullableFloatArray,
859 {
860 std::nullopt,
861 {{}},
862 {{1.0f}},
863 {{1.0f, 2.0f, 3.0f}},
864 });
865 testRepeat<double>(iface, &ITest::RepeatNullableDoubleArray,
866 {
867 std::nullopt,
868 {{}},
869 {{1.0}},
870 {{1.0, 2.0, 3.0}},
871 });
872 testRepeat<ByteEnum>(iface, &ITest::RepeatNullableByteEnumArray,
873 {
874 std::nullopt,
875 {{}},
876 {{ByteEnum::FOO}},
877 {{ByteEnum::FOO, ByteEnum::BAR}},
878 });
879 testRepeat<IntEnum>(iface, &ITest::RepeatNullableIntEnumArray,
880 {
881 std::nullopt,
882 {{}},
883 {{IntEnum::FOO}},
884 {{IntEnum::FOO, IntEnum::BAR}},
885 });
886 testRepeat<LongEnum>(iface, &ITest::RepeatNullableLongEnumArray,
887 {
888 std::nullopt,
889 {{}},
890 {{LongEnum::FOO}},
891 {{LongEnum::FOO, LongEnum::BAR}},
892 });
893 testRepeat<std::optional<std::string>>(
894 iface, &ITest::RepeatNullableStringArray,
895 {
896 std::nullopt,
897 {{}},
898 {{"asdf"}},
899 {{std::nullopt}},
900 {{"aoeu", "lol", "brb"}},
901 {{"", "aoeu", std::nullopt, "brb"}},
902 });
903 testRepeat<std::string>(iface, &ITest::DoubleRepeatNullableStringArray,
904 {
905 {{}},
906 {{"asdf"}},
907 {{std::nullopt}},
908 {{"aoeu", "lol", "brb"}},
909 {{"", "aoeu", std::nullopt, "brb"}},
910 });
911 std::shared_ptr<IEmpty> my_empty = SharedRefBase::make<MyEmpty>();
912 testRepeat<SpAIBinder>(iface, &ITest::RepeatNullableBinderArray,
913 {
914 std::nullopt,
915 {{}},
916 {{iface->asBinder()}},
917 {{nullptr}},
918 {{iface->asBinder(), my_empty->asBinder()}},
919 {{iface->asBinder(), nullptr, my_empty->asBinder()}},
920 });
921 std::shared_ptr<IEmpty> your_empty = SharedRefBase::make<YourEmpty>();
922 testRepeat<std::shared_ptr<IEmpty>>(iface, &ITest::RepeatNullableInterfaceArray,
923 {
924 std::nullopt,
925 {{}},
926 {{my_empty}},
927 {{nullptr}},
928 {{my_empty, your_empty}},
929 {{my_empty, nullptr, your_empty}},
930 });
931 }
932
933 class DefaultImpl : public ::aidl::test_package::ICompatTestDefault {
934 public:
NewMethodThatReturns10(int32_t * _aidl_return)935 ::ndk::ScopedAStatus NewMethodThatReturns10(int32_t* _aidl_return) override {
936 *_aidl_return = 100; // default impl returns different value
937 return ::ndk::ScopedAStatus(AStatus_newOk());
938 }
939 };
940
TEST_P(NdkBinderTest_Aidl,NewMethod)941 TEST_P(NdkBinderTest_Aidl, NewMethod) {
942 std::shared_ptr<ICompatTest> default_impl = SharedRefBase::make<DefaultImpl>();
943 ::aidl::test_package::ICompatTest::setDefaultImpl(default_impl);
944
945 auto compat_test = getCompatTest(iface);
946 int32_t res;
947 EXPECT_OK(compat_test->NewMethodThatReturns10(&res));
948 if (GetParam().shouldBeOld) {
949 // Remote was built with version 1 interface which does not have
950 // "NewMethodThatReturns10". In this case the default method
951 // which returns 100 is called.
952 EXPECT_EQ(100, res);
953 } else {
954 // Remote is built with the current version of the interface.
955 // The method returns 10.
956 EXPECT_EQ(10, res);
957 }
958 }
959
TEST_P(NdkBinderTest_Aidl,RepeatStringNullableLater)960 TEST_P(NdkBinderTest_Aidl, RepeatStringNullableLater) {
961 std::optional<std::string> res;
962
963 std::string name;
964 EXPECT_OK(iface->GetName(&name));
965
966 // Java considers every type to be nullable, but this is okay, since it will
967 // pass back NullPointerException to the client if it does not handle a null
968 // type, similar to how a C++ server would refuse to unparcel a null
969 // non-nullable type. Of course, this is not ideal, but the problem runs very
970 // deep.
971 const bool supports_nullable = !GetParam().shouldBeOld || name == "Java";
972 auto compat_test = getCompatTest(iface);
973 if (supports_nullable) {
974 EXPECT_OK(compat_test->RepeatStringNullableLater(std::nullopt, &res));
975 EXPECT_EQ(std::nullopt, res);
976 } else {
977 ndk::ScopedAStatus status = compat_test->RepeatStringNullableLater(std::nullopt, &res);
978 ASSERT_EQ(STATUS_UNEXPECTED_NULL, AStatus_getStatus(status.get()));
979 }
980
981 EXPECT_OK(compat_test->RepeatStringNullableLater("", &res));
982 EXPECT_EQ("", res);
983
984 EXPECT_OK(compat_test->RepeatStringNullableLater("a", &res));
985 EXPECT_EQ("a", res);
986
987 EXPECT_OK(compat_test->RepeatStringNullableLater("say what?", &res));
988 EXPECT_EQ("say what?", res);
989 }
990
TEST_P(NdkBinderTest_Aidl,GetInterfaceVersion)991 TEST_P(NdkBinderTest_Aidl, GetInterfaceVersion) {
992 int32_t res;
993 auto compat_test = getCompatTest(iface);
994 EXPECT_OK(compat_test->getInterfaceVersion(&res));
995 if (GetParam().shouldBeOld) {
996 EXPECT_EQ(1, res);
997 } else {
998 // 3 is the not-yet-frozen version
999 EXPECT_EQ(3, res);
1000 }
1001 }
1002
TEST_P(NdkBinderTest_Aidl,GetInterfaceHash)1003 TEST_P(NdkBinderTest_Aidl, GetInterfaceHash) {
1004 std::string res;
1005 auto compat_test = getCompatTest(iface);
1006 EXPECT_OK(compat_test->getInterfaceHash(&res));
1007 if (GetParam().shouldBeOld) {
1008 // aidl_api/libbinder_ndk_test_interface/1/.hash
1009 EXPECT_EQ("b663b681b3e0d66f9b5428c2f23365031b7d4ba0", res);
1010 } else {
1011 EXPECT_EQ("notfrozen", res);
1012 }
1013 }
1014
TEST_P(NdkBinderTest_Aidl,LegacyBinder)1015 TEST_P(NdkBinderTest_Aidl, LegacyBinder) {
1016 SpAIBinder binder;
1017 iface->getLegacyBinderTest(&binder);
1018 ASSERT_NE(nullptr, binder.get());
1019
1020 ASSERT_TRUE(AIBinder_associateClass(binder.get(), kLegacyBinderClass));
1021
1022 constexpr int32_t kVal = 42;
1023
1024 ::ndk::ScopedAParcel in;
1025 ::ndk::ScopedAParcel out;
1026 ASSERT_EQ(STATUS_OK, AIBinder_prepareTransaction(binder.get(), in.getR()));
1027 ASSERT_EQ(STATUS_OK, AParcel_writeInt32(in.get(), kVal));
1028 ASSERT_EQ(STATUS_OK,
1029 AIBinder_transact(binder.get(), FIRST_CALL_TRANSACTION, in.getR(), out.getR(), 0));
1030
1031 int32_t output;
1032 ASSERT_EQ(STATUS_OK, AParcel_readInt32(out.get(), &output));
1033 EXPECT_EQ(kVal, output);
1034 }
1035
TEST_P(NdkBinderTest_Aidl,ParcelableHolderTest)1036 TEST_P(NdkBinderTest_Aidl, ParcelableHolderTest) {
1037 ExtendableParcelable ep;
1038 MyExt myext1;
1039 myext1.a = 42;
1040 myext1.b = "mystr";
1041 ep.ext.setParcelable(myext1);
1042 std::optional<MyExt> myext2;
1043 ep.ext.getParcelable(&myext2);
1044 EXPECT_TRUE(myext2);
1045 EXPECT_EQ(42, myext2->a);
1046 EXPECT_EQ("mystr", myext2->b);
1047
1048 AParcel* parcel = AParcel_create();
1049 ep.writeToParcel(parcel);
1050 AParcel_setDataPosition(parcel, 0);
1051 ExtendableParcelable ep2;
1052 ep2.readFromParcel(parcel);
1053 std::optional<MyExt> myext3;
1054 ep2.ext.getParcelable(&myext3);
1055 EXPECT_TRUE(myext3);
1056 EXPECT_EQ(42, myext3->a);
1057 EXPECT_EQ("mystr", myext3->b);
1058 AParcel_delete(parcel);
1059 }
1060
TEST_P(NdkBinderTest_Aidl,ParcelableHolderCopyTest)1061 TEST_P(NdkBinderTest_Aidl, ParcelableHolderCopyTest) {
1062 ndk::AParcelableHolder ph1{ndk::STABILITY_LOCAL};
1063 MyExt myext1;
1064 myext1.a = 42;
1065 myext1.b = "mystr";
1066 ph1.setParcelable(myext1);
1067
1068 ndk::AParcelableHolder ph2{ph1};
1069 std::optional<MyExt> myext2;
1070 ph2.getParcelable(&myext2);
1071 EXPECT_TRUE(myext2);
1072 EXPECT_EQ(42, myext2->a);
1073 EXPECT_EQ("mystr", myext2->b);
1074
1075 std::optional<MyExt> myext3;
1076 ph1.getParcelable(&myext3);
1077 EXPECT_TRUE(myext3);
1078 EXPECT_EQ(42, myext3->a);
1079 EXPECT_EQ("mystr", myext3->b);
1080 }
1081
TEST_P(NdkBinderTest_Aidl,ParcelableHolderCommunicationTest)1082 TEST_P(NdkBinderTest_Aidl, ParcelableHolderCommunicationTest) {
1083 ExtendableParcelable ep;
1084 ep.c = 42L;
1085 MyExt myext1;
1086 myext1.a = 42;
1087 myext1.b = "mystr";
1088 ep.ext.setParcelable(myext1);
1089
1090 ExtendableParcelable ep2;
1091 EXPECT_OK(iface->RepeatExtendableParcelable(ep, &ep2));
1092 std::optional<MyExt> myext2;
1093 ep2.ext.getParcelable(&myext2);
1094 EXPECT_EQ(42L, ep2.c);
1095 EXPECT_TRUE(myext2);
1096 EXPECT_EQ(42, myext2->a);
1097 EXPECT_EQ("mystr", myext2->b);
1098 }
1099
TEST_P(NdkBinderTest_Aidl,EmptyParcelableHolderCommunicationTest)1100 TEST_P(NdkBinderTest_Aidl, EmptyParcelableHolderCommunicationTest) {
1101 ExtendableParcelable ep;
1102 ExtendableParcelable ep2;
1103 ep.c = 42L;
1104 EXPECT_OK(iface->RepeatExtendableParcelableWithoutExtension(ep, &ep2));
1105
1106 EXPECT_EQ(42L, ep2.c);
1107 }
1108
getProxyLocalService()1109 std::shared_ptr<ITest> getProxyLocalService() {
1110 std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
1111 SpAIBinder binder = test->asBinder();
1112
1113 // adding an arbitrary class as the extension
1114 std::shared_ptr<MyTest> ext = SharedRefBase::make<MyTest>();
1115 SpAIBinder extBinder = ext->asBinder();
1116
1117 binder_status_t ret = AIBinder_setExtension(binder.get(), extBinder.get());
1118 if (ret != STATUS_OK) {
1119 __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, "Could not set local extension");
1120 }
1121
1122 // BpTest -> AIBinder -> test
1123 //
1124 // Warning: for testing purposes only. This parcels things within the same process for testing
1125 // purposes. In normal usage, this should just return SharedRefBase::make<MyTest> directly.
1126 return SharedRefBase::make<BpTest>(binder);
1127 }
1128
getNdkBinderTestJavaService(const std::string & method)1129 std::shared_ptr<ITest> getNdkBinderTestJavaService(const std::string& method) {
1130 JNIEnv* env = GetEnv();
1131 if (env == nullptr) {
1132 __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, "No environment");
1133 return nullptr;
1134 }
1135
1136 jobject object = callStaticJavaMethodForObject(env, "android/binder/cts/NdkBinderTest", method,
1137 "()Landroid/os/IBinder;");
1138
1139 SpAIBinder binder = SpAIBinder(AIBinder_fromJavaBinder(env, object));
1140
1141 return ITest::fromBinder(binder);
1142 }
1143
1144 INSTANTIATE_TEST_CASE_P(LocalProxyToNative, NdkBinderTest_Aidl,
1145 ::testing::Values(Params{getProxyLocalService(), false /*shouldBeRemote*/,
1146 true /*shouldBeWrapped*/, "CPP",
1147 false /*shouldBeOld*/}));
1148 INSTANTIATE_TEST_CASE_P(LocalNativeFromJava, NdkBinderTest_Aidl,
1149 ::testing::Values(Params{
1150 getNdkBinderTestJavaService("getLocalNativeService"),
1151 false /*shouldBeRemote*/, false /*shouldBeWrapped*/, "CPP",
1152 false /*shouldBeOld*/}));
1153 INSTANTIATE_TEST_CASE_P(LocalJava, NdkBinderTest_Aidl,
1154 ::testing::Values(Params{getNdkBinderTestJavaService("getLocalJavaService"),
1155 false /*shouldBeRemote*/, true /*shouldBeWrapped*/,
1156 "JAVA", false /*shouldBeOld*/}));
1157 INSTANTIATE_TEST_CASE_P(RemoteNative, NdkBinderTest_Aidl,
1158 ::testing::Values(Params{
1159 getNdkBinderTestJavaService("getRemoteNativeService"),
1160 true /*shouldBeRemote*/, true /*shouldBeWrapped*/, "CPP",
1161 false /*shouldBeOld*/}));
1162 INSTANTIATE_TEST_CASE_P(RemoteJava, NdkBinderTest_Aidl,
1163 ::testing::Values(Params{
1164 getNdkBinderTestJavaService("getRemoteJavaService"),
1165 true /*shouldBeRemote*/, true /*shouldBeWrapped*/, "JAVA",
1166 false /*shouldBeOld*/}));
1167
1168 INSTANTIATE_TEST_CASE_P(RemoteNativeOld, NdkBinderTest_Aidl,
1169 ::testing::Values(Params{
1170 getNdkBinderTestJavaService("getRemoteOldNativeService"),
1171 true /*shouldBeRemote*/, true /*shouldBeWrapped*/, "CPP",
1172 true /*shouldBeOld*/}));
1173