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/BpTest.h>
20 #include <aidl/test_package/ByteEnum.h>
21 #include <aidl/test_package/Foo.h>
22 #include <aidl/test_package/IntEnum.h>
23 #include <aidl/test_package/LongEnum.h>
24 #include <aidl/test_package/RegularPolygon.h>
25 #include <android/binder_ibinder_jni.h>
26 #include <android/log.h>
27 #include <gtest/gtest.h>
28
29 #include "itest_impl.h"
30 #include "utilities.h"
31
32 #include <stdio.h>
33 #include <sys/socket.h>
34 #include <sys/types.h>
35
36 using ::aidl::test_package::Bar;
37 using ::aidl::test_package::BpTest;
38 using ::aidl::test_package::ByteEnum;
39 using ::aidl::test_package::Foo;
40 using ::aidl::test_package::IntEnum;
41 using ::aidl::test_package::ITest;
42 using ::aidl::test_package::LongEnum;
43 using ::aidl::test_package::RegularPolygon;
44 using ::ndk::ScopedAStatus;
45 using ::ndk::ScopedFileDescriptor;
46 using ::ndk::SharedRefBase;
47 using ::ndk::SpAIBinder;
48
49 // AIDL tests which are independent of the service
50 class NdkBinderTest_AidlLocal : public NdkBinderTest {};
51
TEST_F(NdkBinderTest_AidlLocal,FromBinder)52 TEST_F(NdkBinderTest_AidlLocal, FromBinder) {
53 std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
54 SpAIBinder binder = test->asBinder();
55 EXPECT_EQ(test, ITest::fromBinder(binder));
56
57 EXPECT_FALSE(test->isRemote());
58 }
59
60 struct Params {
61 std::shared_ptr<ITest> iface;
62 bool shouldBeRemote;
63 bool shouldBeWrapped;
64 std::string expectedName;
65 bool shouldBeOld;
66 };
67
68 #define iface GetParam().iface
69 #define shouldBeRemote GetParam().shouldBeRemote
70 #define shouldBeWrapped GetParam().shouldBeWrapped
71
72 // AIDL tests which run on each type of service (local C++, local Java, remote C++, remote Java,
73 // etc..)
74 class NdkBinderTest_Aidl : public NdkBinderTest,
75 public ::testing::WithParamInterface<Params> {};
76
TEST_P(NdkBinderTest_Aidl,GotTest)77 TEST_P(NdkBinderTest_Aidl, GotTest) { ASSERT_NE(nullptr, iface); }
78
TEST_P(NdkBinderTest_Aidl,SanityCheckSource)79 TEST_P(NdkBinderTest_Aidl, SanityCheckSource) {
80 std::string name;
81 ASSERT_OK(iface->GetName(&name));
82 EXPECT_EQ(GetParam().expectedName, name);
83 }
84
TEST_P(NdkBinderTest_Aidl,Remoteness)85 TEST_P(NdkBinderTest_Aidl, Remoteness) {
86 ASSERT_EQ(shouldBeRemote, iface->isRemote());
87 }
88
TEST_P(NdkBinderTest_Aidl,UseBinder)89 TEST_P(NdkBinderTest_Aidl, UseBinder) {
90 ASSERT_EQ(STATUS_OK, AIBinder_ping(iface->asBinder().get()));
91 }
92
TEST_P(NdkBinderTest_Aidl,GetExtension)93 TEST_P(NdkBinderTest_Aidl, GetExtension) {
94 SpAIBinder ext;
95 ASSERT_EQ(STATUS_OK, AIBinder_getExtension(iface->asBinder().get(), ext.getR()));
96
97 // TODO(b/139325468): add support in Java as well
98 if (GetParam().expectedName == "CPP") {
99 EXPECT_EQ(STATUS_OK, AIBinder_ping(ext.get()));
100 } else {
101 ASSERT_EQ(nullptr, ext.get());
102 }
103 }
104
ReadFdToString(int fd,std::string * content)105 bool ReadFdToString(int fd, std::string* content) {
106 char buf[64];
107 ssize_t n;
108 while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
109 content->append(buf, n);
110 }
111 return (n == 0) ? true : false;
112 }
113
dumpToString(std::shared_ptr<ITest> itest,std::vector<const char * > args)114 std::string dumpToString(std::shared_ptr<ITest> itest, std::vector<const char*> args) {
115 int fd[2] = {-1, -1};
116 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, fd));
117
118 EXPECT_OK(itest->dump(fd[0], args.data(), args.size()));
119 close(fd[0]);
120
121 std::string ret;
122 EXPECT_TRUE(ReadFdToString(fd[1], &ret));
123
124 close(fd[1]);
125 return ret;
126 }
127
TEST_P(NdkBinderTest_Aidl,UseDump)128 TEST_P(NdkBinderTest_Aidl, UseDump) {
129 std::string name;
130 EXPECT_OK(iface->GetName(&name));
131 if (name == "JAVA" && !iface->isRemote()) {
132 // TODO(b/127361166): GTEST_SKIP is considered a failure, would prefer to use that here
133 // TODO(b/127339049): JavaBBinder doesn't implement dump
134 return;
135 }
136
137 EXPECT_EQ("", dumpToString(iface, {}));
138 EXPECT_EQ("", dumpToString(iface, {"", ""}));
139 EXPECT_EQ("Hello World!", dumpToString(iface, {"Hello ", "World!"}));
140 EXPECT_EQ("ABC", dumpToString(iface, {"A", "B", "C"}));
141 }
142
TEST_P(NdkBinderTest_Aidl,Trivial)143 TEST_P(NdkBinderTest_Aidl, Trivial) {
144 ASSERT_OK(iface->TestVoidReturn());
145
146 if (shouldBeWrapped) {
147 ASSERT_OK(iface->TestOneway());
148 } else {
149 ASSERT_EQ(STATUS_UNKNOWN_ERROR, AStatus_getStatus(iface->TestOneway().get()));
150 }
151 }
152
TEST_P(NdkBinderTest_Aidl,CallingInfo)153 TEST_P(NdkBinderTest_Aidl, CallingInfo) {
154 EXPECT_OK(iface->CacheCallingInfoFromOneway());
155 int32_t res;
156
157 EXPECT_OK(iface->GiveMeMyCallingPid(&res));
158 EXPECT_EQ(getpid(), res);
159
160 EXPECT_OK(iface->GiveMeMyCallingUid(&res));
161 EXPECT_EQ(getuid(), res);
162
163 EXPECT_OK(iface->GiveMeMyCallingPidFromOneway(&res));
164 if (shouldBeRemote) {
165 // PID is hidden from oneway calls
166 EXPECT_EQ(0, res);
167 } else {
168 EXPECT_EQ(getpid(), res);
169 }
170
171 EXPECT_OK(iface->GiveMeMyCallingUidFromOneway(&res));
172 EXPECT_EQ(getuid(), res);
173 }
174
TEST_P(NdkBinderTest_Aidl,Constants)175 TEST_P(NdkBinderTest_Aidl, Constants) {
176 ASSERT_EQ(0, ITest::kZero);
177 ASSERT_EQ(1, ITest::kOne);
178 ASSERT_EQ(0xffffffff, ITest::kOnes);
179 ASSERT_EQ(std::string(""), ITest::kEmpty);
180 ASSERT_EQ(std::string("foo"), ITest::kFoo);
181 }
182
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveInt)183 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveInt) {
184 int32_t out;
185 ASSERT_OK(iface->RepeatInt(3, &out));
186 EXPECT_EQ(3, out);
187 }
188
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveLong)189 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveLong) {
190 int64_t out;
191 ASSERT_OK(iface->RepeatLong(3, &out));
192 EXPECT_EQ(3, out);
193 }
194
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveFloat)195 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveFloat) {
196 float out;
197 ASSERT_OK(iface->RepeatFloat(2.0f, &out));
198 EXPECT_EQ(2.0f, out);
199 }
200
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveDouble)201 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveDouble) {
202 double out;
203 ASSERT_OK(iface->RepeatDouble(3.0, &out));
204 EXPECT_EQ(3.0, out);
205 }
206
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveBoolean)207 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveBoolean) {
208 bool out;
209 ASSERT_OK(iface->RepeatBoolean(true, &out));
210 EXPECT_EQ(true, out);
211 }
212
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveChar)213 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveChar) {
214 char16_t out;
215 ASSERT_OK(iface->RepeatChar(L'@', &out));
216 EXPECT_EQ(L'@', out);
217 }
218
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveByte)219 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveByte) {
220 int8_t out;
221 ASSERT_OK(iface->RepeatByte(3, &out));
222 EXPECT_EQ(3, out);
223 }
224
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveByteEnum)225 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveByteEnum) {
226 ByteEnum out;
227 ASSERT_OK(iface->RepeatByteEnum(ByteEnum::FOO, &out));
228 EXPECT_EQ(ByteEnum::FOO, out);
229 }
230
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveIntEnum)231 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveIntEnum) {
232 IntEnum out;
233 ASSERT_OK(iface->RepeatIntEnum(IntEnum::FOO, &out));
234 EXPECT_EQ(IntEnum::FOO, out);
235 }
236
TEST_P(NdkBinderTest_Aidl,RepeatPrimitiveLongEnum)237 TEST_P(NdkBinderTest_Aidl, RepeatPrimitiveLongEnum) {
238 LongEnum out;
239 ASSERT_OK(iface->RepeatLongEnum(LongEnum::FOO, &out));
240 EXPECT_EQ(LongEnum::FOO, out);
241 }
242
TEST_P(NdkBinderTest_Aidl,EnumToString)243 TEST_P(NdkBinderTest_Aidl, EnumToString) {
244 EXPECT_EQ(toString(ByteEnum::FOO), "FOO");
245 EXPECT_EQ(toString(IntEnum::BAR), "BAR");
246 EXPECT_EQ(toString(LongEnum::FOO), "FOO");
247
248 EXPECT_EQ(toString(static_cast<IntEnum>(-1)), "-1");
249 }
250
TEST_P(NdkBinderTest_Aidl,EnumValues)251 TEST_P(NdkBinderTest_Aidl, EnumValues) {
252 auto range = ::ndk::enum_range<ByteEnum>();
253 auto iter = range.begin();
254 EXPECT_EQ(ByteEnum::FOO, *iter++);
255 EXPECT_EQ(ByteEnum::BAR, *iter++);
256 EXPECT_EQ(range.end(), iter);
257 }
258
TEST_P(NdkBinderTest_Aidl,RepeatBinder)259 TEST_P(NdkBinderTest_Aidl, RepeatBinder) {
260 SpAIBinder binder = iface->asBinder();
261 SpAIBinder ret;
262
263 ASSERT_OK(iface->RepeatBinder(binder, &ret));
264 EXPECT_EQ(binder.get(), ret.get());
265
266 ASSERT_OK(iface->RepeatNullableBinder(binder, &ret));
267 EXPECT_EQ(binder.get(), ret.get());
268
269 ASSERT_OK(iface->RepeatNullableBinder(nullptr, &ret));
270 EXPECT_EQ(nullptr, ret.get());
271 }
272
TEST_P(NdkBinderTest_Aidl,RepeatInterface)273 TEST_P(NdkBinderTest_Aidl, RepeatInterface) {
274 class MyEmpty : public ::aidl::test_package::BnEmpty {};
275
276 std::shared_ptr<IEmpty> empty = SharedRefBase::make<MyEmpty>();
277
278 std::shared_ptr<IEmpty> ret;
279 ASSERT_OK(iface->RepeatInterface(empty, &ret));
280 EXPECT_EQ(empty.get(), ret.get());
281
282 ASSERT_OK(iface->RepeatNullableInterface(empty, &ret));
283 EXPECT_EQ(empty.get(), ret.get());
284
285 ASSERT_OK(iface->RepeatNullableInterface(nullptr, &ret));
286 EXPECT_EQ(nullptr, ret.get());
287 }
288
checkInOut(const ScopedFileDescriptor & inFd,const ScopedFileDescriptor & outFd)289 static void checkInOut(const ScopedFileDescriptor& inFd,
290 const ScopedFileDescriptor& outFd) {
291 static const std::string kContent = "asdf";
292
293 ASSERT_EQ(static_cast<int>(kContent.size()),
294 write(inFd.get(), kContent.data(), kContent.size()));
295
296 std::string out;
297 out.resize(kContent.size());
298 ASSERT_EQ(static_cast<int>(kContent.size()),
299 read(outFd.get(), &out[0], kContent.size()));
300
301 EXPECT_EQ(kContent, out);
302 }
303
checkFdRepeat(const std::shared_ptr<ITest> & test,ScopedAStatus (ITest::* repeatFd)(const ScopedFileDescriptor &,ScopedFileDescriptor *))304 static void checkFdRepeat(
305 const std::shared_ptr<ITest>& test,
306 ScopedAStatus (ITest::*repeatFd)(const ScopedFileDescriptor&,
307 ScopedFileDescriptor*)) {
308 int fds[2];
309
310 while (pipe(fds) == -1 && errno == EAGAIN)
311 ;
312
313 ScopedFileDescriptor readFd(fds[0]);
314 ScopedFileDescriptor writeFd(fds[1]);
315
316 ScopedFileDescriptor readOutFd;
317 ASSERT_OK((test.get()->*repeatFd)(readFd, &readOutFd));
318
319 checkInOut(writeFd, readOutFd);
320 }
321
TEST_P(NdkBinderTest_Aidl,RepeatFdArray)322 TEST_P(NdkBinderTest_Aidl, RepeatFdArray) {
323 int fds[2];
324
325 while (pipe(fds) == -1 && errno == EAGAIN)
326 ;
327 std::vector<ScopedFileDescriptor> sfds;
328 sfds.emplace_back(fds[0]);
329 sfds.emplace_back(fds[1]);
330
331 std::vector<ScopedFileDescriptor> sfds_out1;
332 sfds_out1.resize(sfds.size());
333 std::vector<ScopedFileDescriptor> sfds_out2;
334
335 ASSERT_OK((iface->RepeatFdArray(sfds, &sfds_out1, &sfds_out2)));
336
337 // sfds <-> sfds_out1
338 checkInOut(sfds[1], sfds_out1[0]);
339 checkInOut(sfds_out1[1], sfds[0]);
340
341 // sfds_out1 <-> sfds_out2
342 checkInOut(sfds_out1[1], sfds_out2[0]);
343 checkInOut(sfds_out2[1], sfds_out1[0]);
344
345 // sfds <-> sfds_out2
346 checkInOut(sfds[1], sfds_out2[0]);
347 checkInOut(sfds_out2[1], sfds[0]);
348 }
349
TEST_P(NdkBinderTest_Aidl,RepeatFd)350 TEST_P(NdkBinderTest_Aidl, RepeatFd) { checkFdRepeat(iface, &ITest::RepeatFd); }
351
TEST_P(NdkBinderTest_Aidl,RepeatNullableFd)352 TEST_P(NdkBinderTest_Aidl, RepeatNullableFd) {
353 checkFdRepeat(iface, &ITest::RepeatNullableFd);
354
355 ScopedFileDescriptor in;
356 EXPECT_EQ(-1, in.get());
357
358 ScopedFileDescriptor out;
359 ASSERT_OK(iface->RepeatNullableFd(in, &out));
360
361 EXPECT_EQ(-1, out.get());
362 }
363
TEST_P(NdkBinderTest_Aidl,RepeatString)364 TEST_P(NdkBinderTest_Aidl, RepeatString) {
365 std::string res;
366
367 EXPECT_OK(iface->RepeatString("", &res));
368 EXPECT_EQ("", res);
369
370 EXPECT_OK(iface->RepeatString("a", &res));
371 EXPECT_EQ("a", res);
372
373 EXPECT_OK(iface->RepeatString("say what?", &res));
374 EXPECT_EQ("say what?", res);
375 }
376
TEST_P(NdkBinderTest_Aidl,RepeatNullableString)377 TEST_P(NdkBinderTest_Aidl, RepeatNullableString) {
378 std::optional<std::string> res;
379
380 EXPECT_OK(iface->RepeatNullableString(std::nullopt, &res));
381 EXPECT_EQ(std::nullopt, res);
382
383 EXPECT_OK(iface->RepeatNullableString("", &res));
384 EXPECT_EQ("", *res);
385
386 EXPECT_OK(iface->RepeatNullableString("a", &res));
387 EXPECT_EQ("a", *res);
388
389 EXPECT_OK(iface->RepeatNullableString("say what?", &res));
390 EXPECT_EQ("say what?", *res);
391 }
392
TEST_P(NdkBinderTest_Aidl,ParcelableDefaults)393 TEST_P(NdkBinderTest_Aidl, ParcelableDefaults) {
394 RegularPolygon polygon;
395
396 EXPECT_EQ("square", polygon.name);
397 EXPECT_EQ(4, polygon.numSides);
398 EXPECT_EQ(1.0f, polygon.sideLength);
399 }
400
TEST_P(NdkBinderTest_Aidl,RepeatPolygon)401 TEST_P(NdkBinderTest_Aidl, RepeatPolygon) {
402 RegularPolygon defaultPolygon = {"hexagon", 6, 2.0f};
403 RegularPolygon outputPolygon;
404 ASSERT_OK(iface->RepeatPolygon(defaultPolygon, &outputPolygon));
405 EXPECT_EQ(defaultPolygon, outputPolygon);
406 }
407
TEST_P(NdkBinderTest_Aidl,RepeatNullNullablePolygon)408 TEST_P(NdkBinderTest_Aidl, RepeatNullNullablePolygon) {
409 std::optional<RegularPolygon> defaultPolygon;
410 std::optional<RegularPolygon> outputPolygon;
411 ASSERT_OK(iface->RepeatNullablePolygon(defaultPolygon, &outputPolygon));
412 EXPECT_EQ(defaultPolygon, outputPolygon);
413 }
414
TEST_P(NdkBinderTest_Aidl,RepeatPresentNullablePolygon)415 TEST_P(NdkBinderTest_Aidl, RepeatPresentNullablePolygon) {
416 std::optional<RegularPolygon> defaultPolygon =
417 std::optional<RegularPolygon>({"septagon", 7, 3.0f});
418 std::optional<RegularPolygon> outputPolygon;
419 ASSERT_OK(iface->RepeatNullablePolygon(defaultPolygon, &outputPolygon));
420 EXPECT_EQ(defaultPolygon, outputPolygon);
421 }
422
TEST_P(NdkBinderTest_Aidl,InsAndOuts)423 TEST_P(NdkBinderTest_Aidl, InsAndOuts) {
424 RegularPolygon defaultPolygon;
425 ASSERT_OK(iface->RenamePolygon(&defaultPolygon, "Jerry"));
426 EXPECT_EQ("Jerry", defaultPolygon.name);
427 }
428
TEST_P(NdkBinderTest_Aidl,NewField)429 TEST_P(NdkBinderTest_Aidl, NewField) {
430 Foo foo;
431 foo.g = {"a", "b", "c"};
432
433 Foo outFoo;
434 ASSERT_OK(iface->repeatFoo(foo, &outFoo));
435
436 if (GetParam().shouldBeOld) {
437 EXPECT_EQ(std::nullopt, outFoo.g);
438 } else {
439 EXPECT_EQ(foo.g, outFoo.g);
440 }
441 }
442
TEST_P(NdkBinderTest_Aidl,RenameFoo)443 TEST_P(NdkBinderTest_Aidl, RenameFoo) {
444 Foo foo;
445 Foo outputFoo;
446 ASSERT_OK(iface->renameFoo(&foo, "MYFOO"));
447
448 EXPECT_EQ("MYFOO", foo.a);
449 }
450
TEST_P(NdkBinderTest_Aidl,RenameBar)451 TEST_P(NdkBinderTest_Aidl, RenameBar) {
452 Foo foo;
453 Foo outputFoo;
454 ASSERT_OK(iface->renameBar(&foo, "MYBAR"));
455
456 EXPECT_EQ("MYBAR", foo.d.a);
457 }
458
TEST_P(NdkBinderTest_Aidl,GetLastItem)459 TEST_P(NdkBinderTest_Aidl, GetLastItem) {
460 Foo foo;
461 foo.f = 15;
462 int retF;
463 ASSERT_OK(iface->getF(foo, &retF));
464 EXPECT_EQ(15, retF);
465 }
466
TEST_P(NdkBinderTest_Aidl,RepeatFoo)467 TEST_P(NdkBinderTest_Aidl, RepeatFoo) {
468 Foo foo;
469 foo.a = "NEW FOO";
470 foo.b = 57;
471 foo.d.b = "a";
472 foo.e.d = 99;
473 foo.shouldBeByteBar = ByteEnum::BAR;
474 foo.shouldBeIntBar = IntEnum::BAR;
475 foo.shouldBeLongBar = LongEnum::BAR;
476 foo.shouldContainTwoByteFoos = {ByteEnum::FOO, ByteEnum::FOO};
477 foo.shouldContainTwoIntFoos = {IntEnum::FOO, IntEnum::FOO};
478 foo.shouldContainTwoLongFoos = {LongEnum::FOO, LongEnum::FOO};
479 Foo retFoo;
480
481 ASSERT_OK(iface->repeatFoo(foo, &retFoo));
482
483 EXPECT_EQ(foo.a, retFoo.a);
484 EXPECT_EQ(foo.b, retFoo.b);
485 EXPECT_EQ(foo.d.b, retFoo.d.b);
486 EXPECT_EQ(foo.e.d, retFoo.e.d);
487 EXPECT_EQ(foo.shouldBeByteBar, retFoo.shouldBeByteBar);
488 EXPECT_EQ(foo.shouldBeIntBar, retFoo.shouldBeIntBar);
489 EXPECT_EQ(foo.shouldBeLongBar, retFoo.shouldBeLongBar);
490 EXPECT_EQ(foo.shouldContainTwoByteFoos, retFoo.shouldContainTwoByteFoos);
491 EXPECT_EQ(foo.shouldContainTwoIntFoos, retFoo.shouldContainTwoIntFoos);
492 EXPECT_EQ(foo.shouldContainTwoLongFoos, retFoo.shouldContainTwoLongFoos);
493 }
494
495 template <typename T>
496 using RepeatMethod = ScopedAStatus (ITest::*)(const std::vector<T>&,
497 std::vector<T>*, std::vector<T>*);
498
499 namespace aidl {
500 namespace test_package {
operator ==(const RegularPolygon & lhs,const RegularPolygon & rhs)501 inline bool operator==(const RegularPolygon& lhs, const RegularPolygon& rhs) {
502 return lhs.name == rhs.name && lhs.numSides == rhs.numSides && lhs.sideLength == rhs.sideLength;
503 }
operator ==(const std::vector<RegularPolygon> & lhs,const std::vector<RegularPolygon> & rhs)504 inline bool operator==(const std::vector<RegularPolygon>& lhs,
505 const std::vector<RegularPolygon>& rhs) {
506 if (lhs.size() != rhs.size()) return false;
507 for (size_t i = 0; i < lhs.size(); i++) {
508 if (!(lhs[i] == rhs[i])) return false;
509 }
510 return true;
511 }
512 } // namespace test_package
513 } // namespace aidl
514
515 template <typename T>
testRepeat(const std::shared_ptr<ITest> & i,RepeatMethod<T> repeatMethod,std::vector<std::vector<T>> tests)516 void testRepeat(const std::shared_ptr<ITest>& i, RepeatMethod<T> repeatMethod,
517 std::vector<std::vector<T>> tests) {
518 for (const auto& input : tests) {
519 std::vector<T> out1;
520 out1.resize(input.size());
521 std::vector<T> out2;
522
523 ASSERT_OK((i.get()->*repeatMethod)(input, &out1, &out2)) << input.size();
524 EXPECT_EQ(input, out1);
525 EXPECT_EQ(input, out2);
526 }
527 }
528
529 template <typename T>
testRepeat2List(const std::shared_ptr<ITest> & i,RepeatMethod<T> repeatMethod,std::vector<std::vector<T>> tests)530 void testRepeat2List(const std::shared_ptr<ITest>& i, RepeatMethod<T> repeatMethod,
531 std::vector<std::vector<T>> tests) {
532 for (const auto& input : tests) {
533 std::vector<T> out1;
534 std::vector<T> out2;
535 std::vector<T> expected;
536
537 expected.insert(expected.end(), input.begin(), input.end());
538 expected.insert(expected.end(), input.begin(), input.end());
539
540 ASSERT_OK((i.get()->*repeatMethod)(input, &out1, &out2)) << expected.size();
541 EXPECT_EQ(expected, out1);
542 EXPECT_EQ(expected, out2);
543 }
544 }
545
TEST_P(NdkBinderTest_Aidl,Arrays)546 TEST_P(NdkBinderTest_Aidl, Arrays) {
547 testRepeat<bool>(iface, &ITest::RepeatBooleanArray,
548 {
549 {},
550 {true},
551 {false, true, false},
552 });
553 testRepeat<uint8_t>(iface, &ITest::RepeatByteArray,
554 {
555 {},
556 {1},
557 {1, 2, 3},
558 });
559 testRepeat<char16_t>(iface, &ITest::RepeatCharArray,
560 {
561 {},
562 {L'@'},
563 {L'@', L'!', L'A'},
564 });
565 testRepeat<int32_t>(iface, &ITest::RepeatIntArray,
566 {
567 {},
568 {1},
569 {1, 2, 3},
570 });
571 testRepeat<int64_t>(iface, &ITest::RepeatLongArray,
572 {
573 {},
574 {1},
575 {1, 2, 3},
576 });
577 testRepeat<float>(iface, &ITest::RepeatFloatArray,
578 {
579 {},
580 {1.0f},
581 {1.0f, 2.0f, 3.0f},
582 });
583 testRepeat<double>(iface, &ITest::RepeatDoubleArray,
584 {
585 {},
586 {1.0},
587 {1.0, 2.0, 3.0},
588 });
589 testRepeat<ByteEnum>(iface, &ITest::RepeatByteEnumArray,
590 {
591 {},
592 {ByteEnum::FOO},
593 {ByteEnum::FOO, ByteEnum::BAR},
594 });
595 testRepeat<IntEnum>(iface, &ITest::RepeatIntEnumArray,
596 {
597 {},
598 {IntEnum::FOO},
599 {IntEnum::FOO, IntEnum::BAR},
600 });
601 testRepeat<LongEnum>(iface, &ITest::RepeatLongEnumArray,
602 {
603 {},
604 {LongEnum::FOO},
605 {LongEnum::FOO, LongEnum::BAR},
606 });
607 testRepeat<std::string>(iface, &ITest::RepeatStringArray,
608 {
609 {},
610 {"asdf"},
611 {"", "aoeu", "lol", "brb"},
612 });
613 testRepeat<RegularPolygon>(iface, &ITest::RepeatRegularPolygonArray,
614 {
615 {},
616 {{"hexagon", 6, 2.0f}},
617 {{"hexagon", 6, 2.0f}, {"square", 4, 7.0f}, {"pentagon", 5, 4.2f}},
618 });
619 }
620
TEST_P(NdkBinderTest_Aidl,Lists)621 TEST_P(NdkBinderTest_Aidl, Lists) {
622 testRepeat2List<std::string>(iface, &ITest::Repeat2StringList,
623 {
624 {},
625 {"asdf"},
626 {"", "aoeu", "lol", "brb"},
627 });
628 testRepeat2List<RegularPolygon>(
629 iface, &ITest::Repeat2RegularPolygonList,
630 {
631 {},
632 {{"hexagon", 6, 2.0f}},
633 {{"hexagon", 6, 2.0f}, {"square", 4, 7.0f}, {"pentagon", 5, 4.2f}},
634 });
635 }
636
637 template <typename T>
638 using RepeatNullableMethod = ScopedAStatus (ITest::*)(
639 const std::optional<std::vector<std::optional<T>>>&,
640 std::optional<std::vector<std::optional<T>>>*,
641 std::optional<std::vector<std::optional<T>>>*);
642
643 template <typename T>
testRepeat(const std::shared_ptr<ITest> & i,RepeatNullableMethod<T> repeatMethod,std::vector<std::optional<std::vector<std::optional<T>>>> tests)644 void testRepeat(
645 const std::shared_ptr<ITest>& i, RepeatNullableMethod<T> repeatMethod,
646 std::vector<std::optional<std::vector<std::optional<T>>>> tests) {
647 for (const auto& input : tests) {
648 std::optional<std::vector<std::optional<T>>> out1;
649 if (input) {
650 out1 = std::vector<std::optional<T>>{};
651 out1->resize(input->size());
652 }
653 std::optional<std::vector<std::optional<T>>> out2;
654
655 ASSERT_OK((i.get()->*repeatMethod)(input, &out1, &out2))
656 << (input ? input->size() : -1);
657 EXPECT_EQ(input, out1);
658 EXPECT_EQ(input, out2);
659 }
660 }
661
662 template <typename T>
663 using SingleRepeatNullableMethod = ScopedAStatus (ITest::*)(
664 const std::optional<std::vector<T>>&, std::optional<std::vector<T>>*);
665
666 template <typename T>
testRepeat(const std::shared_ptr<ITest> & i,SingleRepeatNullableMethod<T> repeatMethod,std::vector<std::optional<std::vector<T>>> tests)667 void testRepeat(const std::shared_ptr<ITest>& i,
668 SingleRepeatNullableMethod<T> repeatMethod,
669 std::vector<std::optional<std::vector<T>>> tests) {
670 for (const auto& input : tests) {
671 std::optional<std::vector<T>> ret;
672 ASSERT_OK((i.get()->*repeatMethod)(input, &ret))
673 << (input ? input->size() : -1);
674 EXPECT_EQ(input, ret);
675 }
676 }
677
TEST_P(NdkBinderTest_Aidl,NullableArrays)678 TEST_P(NdkBinderTest_Aidl, NullableArrays) {
679 testRepeat<bool>(iface, &ITest::RepeatNullableBooleanArray,
680 {
681 std::nullopt,
682 {{}},
683 {{true}},
684 {{false, true, false}},
685 });
686 testRepeat<uint8_t>(iface, &ITest::RepeatNullableByteArray,
687 {
688 std::nullopt,
689 {{}},
690 {{1}},
691 {{1, 2, 3}},
692 });
693 testRepeat<char16_t>(iface, &ITest::RepeatNullableCharArray,
694 {
695 std::nullopt,
696 {{}},
697 {{L'@'}},
698 {{L'@', L'!', L'A'}},
699 });
700 testRepeat<int32_t>(iface, &ITest::RepeatNullableIntArray,
701 {
702 std::nullopt,
703 {{}},
704 {{1}},
705 {{1, 2, 3}},
706 });
707 testRepeat<int64_t>(iface, &ITest::RepeatNullableLongArray,
708 {
709 std::nullopt,
710 {{}},
711 {{1}},
712 {{1, 2, 3}},
713 });
714 testRepeat<float>(iface, &ITest::RepeatNullableFloatArray,
715 {
716 std::nullopt,
717 {{}},
718 {{1.0f}},
719 {{1.0f, 2.0f, 3.0f}},
720 });
721 testRepeat<double>(iface, &ITest::RepeatNullableDoubleArray,
722 {
723 std::nullopt,
724 {{}},
725 {{1.0}},
726 {{1.0, 2.0, 3.0}},
727 });
728 testRepeat<ByteEnum>(iface, &ITest::RepeatNullableByteEnumArray,
729 {
730 std::nullopt,
731 {{}},
732 {{ByteEnum::FOO}},
733 {{ByteEnum::FOO, ByteEnum::BAR}},
734 });
735 testRepeat<IntEnum>(iface, &ITest::RepeatNullableIntEnumArray,
736 {
737 std::nullopt,
738 {{}},
739 {{IntEnum::FOO}},
740 {{IntEnum::FOO, IntEnum::BAR}},
741 });
742 testRepeat<LongEnum>(iface, &ITest::RepeatNullableLongEnumArray,
743 {
744 std::nullopt,
745 {{}},
746 {{LongEnum::FOO}},
747 {{LongEnum::FOO, LongEnum::BAR}},
748 });
749 testRepeat<std::optional<std::string>>(
750 iface, &ITest::RepeatNullableStringArray,
751 {
752 std::nullopt,
753 {{}},
754 {{"asdf"}},
755 {{std::nullopt}},
756 {{"aoeu", "lol", "brb"}},
757 {{"", "aoeu", std::nullopt, "brb"}},
758 });
759 testRepeat<std::string>(iface, &ITest::DoubleRepeatNullableStringArray,
760 {
761 {{}},
762 {{"asdf"}},
763 {{std::nullopt}},
764 {{"aoeu", "lol", "brb"}},
765 {{"", "aoeu", std::nullopt, "brb"}},
766 });
767 }
768
769 class DefaultImpl : public ::aidl::test_package::ITestDefault {
770 public:
NewMethodThatReturns10(int32_t * _aidl_return)771 ::ndk::ScopedAStatus NewMethodThatReturns10(int32_t* _aidl_return) override {
772 *_aidl_return = 100; // default impl returns different value
773 return ::ndk::ScopedAStatus(AStatus_newOk());
774 }
775 };
776
TEST_P(NdkBinderTest_Aidl,NewMethod)777 TEST_P(NdkBinderTest_Aidl, NewMethod) {
778 std::shared_ptr<ITest> default_impl = SharedRefBase::make<DefaultImpl>();
779 ::aidl::test_package::ITest::setDefaultImpl(default_impl);
780
781 int32_t res;
782 EXPECT_OK(iface->NewMethodThatReturns10(&res));
783 if (GetParam().shouldBeOld) {
784 // Remote was built with version 1 interface which does not have
785 // "NewMethodThatReturns10". In this case the default method
786 // which returns 100 is called.
787 EXPECT_EQ(100, res);
788 } else {
789 // Remote is built with the current version of the interface.
790 // The method returns 10.
791 EXPECT_EQ(10, res);
792 }
793 }
794
TEST_P(NdkBinderTest_Aidl,RepeatStringNullableLater)795 TEST_P(NdkBinderTest_Aidl, RepeatStringNullableLater) {
796 std::optional<std::string> res;
797
798 std::string name;
799 EXPECT_OK(iface->GetName(&name));
800
801 // Java considers every type to be nullable, but this is okay, since it will
802 // pass back NullPointerException to the client if it does not handle a null
803 // type, similar to how a C++ server would refuse to unparcel a null
804 // non-nullable type. Of course, this is not ideal, but the problem runs very
805 // deep.
806 const bool supports_nullable = !GetParam().shouldBeOld || name == "Java";
807 if (supports_nullable) {
808 EXPECT_OK(iface->RepeatStringNullableLater(std::nullopt, &res));
809 EXPECT_EQ(std::nullopt, res);
810 } else {
811 ndk::ScopedAStatus status = iface->RepeatStringNullableLater(std::nullopt, &res);
812 ASSERT_EQ(STATUS_UNEXPECTED_NULL, AStatus_getStatus(status.get()));
813 }
814
815 EXPECT_OK(iface->RepeatStringNullableLater("", &res));
816 EXPECT_EQ("", res);
817
818 EXPECT_OK(iface->RepeatStringNullableLater("a", &res));
819 EXPECT_EQ("a", res);
820
821 EXPECT_OK(iface->RepeatStringNullableLater("say what?", &res));
822 EXPECT_EQ("say what?", res);
823 }
824
TEST_P(NdkBinderTest_Aidl,GetInterfaceVersion)825 TEST_P(NdkBinderTest_Aidl, GetInterfaceVersion) {
826 int32_t res;
827 EXPECT_OK(iface->getInterfaceVersion(&res));
828 if (GetParam().shouldBeOld) {
829 EXPECT_EQ(1, res);
830 } else {
831 // 3 is the not-yet-frozen version
832 EXPECT_EQ(3, res);
833 }
834 }
835
TEST_P(NdkBinderTest_Aidl,GetInterfaceHash)836 TEST_P(NdkBinderTest_Aidl, GetInterfaceHash) {
837 std::string res;
838 EXPECT_OK(iface->getInterfaceHash(&res));
839 if (GetParam().shouldBeOld) {
840 // aidl_api/libbinder_ndk_test_interface/1/.hash
841 EXPECT_EQ("8e163a1b4a6f366aa0c00b6da7fc13a970ee55d8", res);
842 } else {
843 EXPECT_EQ("notfrozen", res);
844 }
845 }
846
getProxyLocalService()847 std::shared_ptr<ITest> getProxyLocalService() {
848 std::shared_ptr<MyTest> test = SharedRefBase::make<MyTest>();
849 SpAIBinder binder = test->asBinder();
850
851 // adding an arbitrary class as the extension
852 std::shared_ptr<MyTest> ext = SharedRefBase::make<MyTest>();
853 SpAIBinder extBinder = ext->asBinder();
854
855 binder_status_t ret = AIBinder_setExtension(binder.get(), extBinder.get());
856 if (ret != STATUS_OK) {
857 __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, "Could not set local extension");
858 }
859
860 // BpTest -> AIBinder -> test
861 //
862 // Warning: for testing purposes only. This parcels things within the same process for testing
863 // purposes. In normal usage, this should just return SharedRefBase::make<MyTest> directly.
864 return SharedRefBase::make<BpTest>(binder);
865 }
866
getNdkBinderTestJavaService(const std::string & method)867 std::shared_ptr<ITest> getNdkBinderTestJavaService(const std::string& method) {
868 JNIEnv* env = GetEnv();
869 if (env == nullptr) {
870 __android_log_write(ANDROID_LOG_ERROR, LOG_TAG, "No environment");
871 return nullptr;
872 }
873
874 jobject object = callStaticJavaMethodForObject(env, "android/binder/cts/NdkBinderTest", method,
875 "()Landroid/os/IBinder;");
876
877 SpAIBinder binder = SpAIBinder(AIBinder_fromJavaBinder(env, object));
878
879 return ITest::fromBinder(binder);
880 }
881
882 INSTANTIATE_TEST_CASE_P(LocalProxyToNative, NdkBinderTest_Aidl,
883 ::testing::Values(Params{getProxyLocalService(), false /*shouldBeRemote*/,
884 true /*shouldBeWrapped*/, "CPP",
885 false /*shouldBeOld*/}));
886 INSTANTIATE_TEST_CASE_P(LocalNativeFromJava, NdkBinderTest_Aidl,
887 ::testing::Values(Params{
888 getNdkBinderTestJavaService("getLocalNativeService"),
889 false /*shouldBeRemote*/, false /*shouldBeWrapped*/, "CPP",
890 false /*shouldBeOld*/}));
891 INSTANTIATE_TEST_CASE_P(LocalJava, NdkBinderTest_Aidl,
892 ::testing::Values(Params{getNdkBinderTestJavaService("getLocalJavaService"),
893 false /*shouldBeRemote*/, true /*shouldBeWrapped*/,
894 "JAVA", false /*shouldBeOld*/}));
895 INSTANTIATE_TEST_CASE_P(RemoteNative, NdkBinderTest_Aidl,
896 ::testing::Values(Params{
897 getNdkBinderTestJavaService("getRemoteNativeService"),
898 true /*shouldBeRemote*/, true /*shouldBeWrapped*/, "CPP",
899 false /*shouldBeOld*/}));
900 INSTANTIATE_TEST_CASE_P(RemoteJava, NdkBinderTest_Aidl,
901 ::testing::Values(Params{
902 getNdkBinderTestJavaService("getRemoteJavaService"),
903 true /*shouldBeRemote*/, true /*shouldBeWrapped*/, "JAVA",
904 false /*shouldBeOld*/}));
905
906 INSTANTIATE_TEST_CASE_P(RemoteNativeOld, NdkBinderTest_Aidl,
907 ::testing::Values(Params{
908 getNdkBinderTestJavaService("getRemoteOldNativeService"),
909 true /*shouldBeRemote*/, true /*shouldBeWrapped*/, "CPP",
910 true /*shouldBeOld*/}));
911