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
17 #include <IBinderNdkUnitTest.h>
18 #include <aidl/BnBinderNdkUnitTest.h>
19 #include <aidl/BnEmpty.h>
20 #include <android-base/logging.h>
21 #include <android/binder_ibinder_jni.h>
22 #include <android/binder_ibinder_platform.h>
23 #include <android/binder_libbinder.h>
24 #include <android/binder_manager.h>
25 #include <android/binder_process.h>
26 #include <gtest/gtest.h>
27 #include <iface/iface.h>
28 #include <utils/Looper.h>
29
30 // warning: this is assuming that libbinder_ndk is using the same copy
31 // of libbinder that we are.
32 #include <binder/IPCThreadState.h>
33 #include <binder/IResultReceiver.h>
34 #include <binder/IServiceManager.h>
35 #include <binder/IShellCallback.h>
36 #include <sys/prctl.h>
37
38 #include <chrono>
39 #include <condition_variable>
40 #include <iostream>
41 #include <mutex>
42 #include <optional>
43 #include <thread>
44
45 #include "android/binder_ibinder.h"
46
47 using namespace android;
48
49 constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
50 constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
51 constexpr char kLazyBinderNdkUnitTestService[] = "LazyBinderNdkUnitTest";
52 constexpr char kForcePersistNdkUnitTestService[] = "ForcePersistNdkUnitTestService";
53 constexpr char kActiveServicesNdkUnitTestService[] = "ActiveServicesNdkUnitTestService";
54 constexpr char kBinderNdkUnitTestServiceFlagged[] = "BinderNdkUnitTestFlagged";
55
56 constexpr unsigned int kShutdownWaitTime = 11;
57 constexpr uint64_t kContextTestValue = 0xb4e42fb4d9a1d715;
58
59 class MyTestFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)60 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
61 *out = 2 * in;
62 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
63 return STATUS_OK;
64 }
die()65 binder_status_t die() override {
66 ADD_FAILURE() << "die called on local instance";
67 return STATUS_OK;
68 }
69 };
70
71 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
repeatInt(int32_t in,int32_t * out)72 ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
73 *out = in;
74 return ndk::ScopedAStatus::ok();
75 }
takeInterface(const std::shared_ptr<aidl::IEmpty> & empty)76 ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
77 (void)empty;
78 return ndk::ScopedAStatus::ok();
79 }
forceFlushCommands()80 ndk::ScopedAStatus forceFlushCommands() {
81 // warning: this is assuming that libbinder_ndk is using the same copy
82 // of libbinder that we are.
83 android::IPCThreadState::self()->flushCommands();
84 return ndk::ScopedAStatus::ok();
85 }
getsRequestedSid(bool * out)86 ndk::ScopedAStatus getsRequestedSid(bool* out) {
87 const char* sid = AIBinder_getCallingSid();
88 std::cout << "Got security context: " << (sid ?: "null") << std::endl;
89 *out = sid != nullptr;
90 return ndk::ScopedAStatus::ok();
91 }
handleShellCommand(int,int out,int,const char ** args,uint32_t numArgs)92 binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
93 uint32_t numArgs) override {
94 for (uint32_t i = 0; i < numArgs; i++) {
95 dprintf(out, "%s", args[i]);
96 }
97 fsync(out);
98 return STATUS_OK;
99 }
forcePersist(bool persist)100 ndk::ScopedAStatus forcePersist(bool persist) {
101 AServiceManager_forceLazyServicesPersist(persist);
102 return ndk::ScopedAStatus::ok();
103 }
setCustomActiveServicesCallback()104 ndk::ScopedAStatus setCustomActiveServicesCallback() {
105 AServiceManager_setActiveServicesCallback(activeServicesCallback, this);
106 return ndk::ScopedAStatus::ok();
107 }
activeServicesCallback(bool hasClients,void * context)108 static bool activeServicesCallback(bool hasClients, void* context) {
109 if (hasClients) {
110 return false;
111 }
112
113 // Unregister all services
114 if (!AServiceManager_tryUnregister()) {
115 // Prevent shutdown (test will fail)
116 return false;
117 }
118
119 // Re-register all services
120 AServiceManager_reRegister();
121
122 // Unregister again before shutdown
123 if (!AServiceManager_tryUnregister()) {
124 // Prevent shutdown (test will fail)
125 return false;
126 }
127
128 // Check if the context was passed correctly
129 MyBinderNdkUnitTest* service = static_cast<MyBinderNdkUnitTest*>(context);
130 if (service->contextTestValue != kContextTestValue) {
131 // Prevent shutdown (test will fail)
132 return false;
133 }
134
135 exit(EXIT_SUCCESS);
136 // Unreachable
137 }
138
139 uint64_t contextTestValue = kContextTestValue;
140 };
141
generatedService()142 int generatedService() {
143 ABinderProcess_setThreadPoolMaxThreadCount(0);
144
145 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
146 auto binder = service->asBinder();
147
148 AIBinder_setRequestingSid(binder.get(), true);
149
150 binder_exception_t exception =
151 AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
152
153 if (exception != EX_NONE) {
154 LOG(FATAL) << "Could not register: " << exception << " " << kBinderNdkUnitTestService;
155 }
156
157 ABinderProcess_joinThreadPool();
158
159 return 1; // should not return
160 }
161
generatedFlaggedService(const AServiceManager_AddServiceFlag flags,const char * instance)162 int generatedFlaggedService(const AServiceManager_AddServiceFlag flags, const char* instance) {
163 ABinderProcess_setThreadPoolMaxThreadCount(0);
164
165 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
166 auto binder = service->asBinder();
167
168 binder_exception_t exception =
169 AServiceManager_addServiceWithFlags(binder.get(), instance, flags);
170
171 if (exception != EX_NONE) {
172 LOG(FATAL) << "Could not register: " << exception << " " << instance;
173 }
174
175 ABinderProcess_joinThreadPool();
176
177 return 1; // should not return
178 }
179
180 // manually-written parceling class considered bad practice
181 class MyFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)182 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
183 *out = 2 * in;
184 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
185 return STATUS_OK;
186 }
187
die()188 binder_status_t die() override {
189 LOG(FATAL) << "IFoo::die called!";
190 return STATUS_UNKNOWN_ERROR;
191 }
192 };
193
manualService(const char * instance)194 void manualService(const char* instance) {
195 // Strong reference to MyFoo kept by service manager.
196 binder_exception_t exception = (new MyFoo)->addService(instance);
197
198 if (exception != EX_NONE) {
199 LOG(FATAL) << "Could not register: " << exception << " " << instance;
200 }
201 }
manualPollingService(const char * instance)202 int manualPollingService(const char* instance) {
203 int fd;
204 CHECK(STATUS_OK == ABinderProcess_setupPolling(&fd));
205 manualService(instance);
206
207 class Handler : public LooperCallback {
208 int handleEvent(int /*fd*/, int /*events*/, void* /*data*/) override {
209 ABinderProcess_handlePolledCommands();
210 return 1; // Continue receiving callbacks.
211 }
212 };
213
214 sp<Looper> looper = Looper::prepare(0 /* opts */);
215 looper->addFd(fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, new Handler(), nullptr /*data*/);
216 // normally, would add additional fds
217 while (true) {
218 looper->pollAll(-1 /* timeoutMillis */);
219 }
220 return 1; // should not reach
221 }
manualThreadPoolService(const char * instance)222 int manualThreadPoolService(const char* instance) {
223 ABinderProcess_setThreadPoolMaxThreadCount(0);
224 manualService(instance);
225 ABinderProcess_joinThreadPool();
226 return 1;
227 }
228
lazyService(const char * instance)229 int lazyService(const char* instance) {
230 ABinderProcess_setThreadPoolMaxThreadCount(0);
231 // Wait to register this service to make sure the main test process will
232 // actually wait for the service to be available. Tested with sleep(60),
233 // and reduced for sake of time.
234 sleep(1);
235 // Strong reference to MyBinderNdkUnitTest kept by service manager.
236 // This is just for testing, it has no corresponding init behavior.
237 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
238 auto binder = service->asBinder();
239
240 binder_status_t status = AServiceManager_registerLazyService(binder.get(), instance);
241 if (status != STATUS_OK) {
242 LOG(FATAL) << "Could not register: " << status << " " << instance;
243 }
244
245 ABinderProcess_joinThreadPool();
246
247 return 1; // should not return
248 }
249
isServiceRunning(const char * serviceName)250 bool isServiceRunning(const char* serviceName) {
251 AIBinder* binder = AServiceManager_checkService(serviceName);
252 if (binder == nullptr) {
253 return false;
254 }
255 AIBinder_decStrong(binder);
256
257 return true;
258 }
259
TEST(NdkBinder,DetectDoubleOwn)260 TEST(NdkBinder, DetectDoubleOwn) {
261 auto badService = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
262 EXPECT_DEATH(std::shared_ptr<MyBinderNdkUnitTest>(badService.get()),
263 "Is this object double-owned?");
264 }
265
TEST(NdkBinder,DetectNoSharedRefBaseCreated)266 TEST(NdkBinder, DetectNoSharedRefBaseCreated) {
267 EXPECT_DEATH(MyBinderNdkUnitTest(), "SharedRefBase: no ref created during lifetime");
268 }
269
TEST(NdkBinder,GetServiceThatDoesntExist)270 TEST(NdkBinder, GetServiceThatDoesntExist) {
271 sp<IFoo> foo = IFoo::getService("asdfghkl;");
272 EXPECT_EQ(nullptr, foo.get());
273 }
274
TEST(NdkBinder,CheckServiceThatDoesntExist)275 TEST(NdkBinder, CheckServiceThatDoesntExist) {
276 AIBinder* binder = AServiceManager_checkService("asdfghkl;");
277 ASSERT_EQ(nullptr, binder);
278 }
279
TEST(NdkBinder,CheckServiceThatDoesExist)280 TEST(NdkBinder, CheckServiceThatDoesExist) {
281 AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
282 EXPECT_NE(nullptr, binder);
283 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
284
285 AIBinder_decStrong(binder);
286 }
287
288 struct ServiceData {
289 std::string instance;
290 ndk::SpAIBinder binder;
291
fillOnRegisterServiceData292 static void fillOnRegister(const char* instance, AIBinder* binder, void* cookie) {
293 ServiceData* d = reinterpret_cast<ServiceData*>(cookie);
294 d->instance = instance;
295 d->binder = ndk::SpAIBinder(binder);
296 }
297 };
298
TEST(NdkBinder,RegisterForServiceNotificationsNonExisting)299 TEST(NdkBinder, RegisterForServiceNotificationsNonExisting) {
300 ServiceData data;
301 auto* notif = AServiceManager_registerForServiceNotifications(
302 "DOES_NOT_EXIST", ServiceData::fillOnRegister, (void*)&data);
303 ASSERT_NE(notif, nullptr);
304
305 sleep(1); // give us a chance to fail
306 AServiceManager_NotificationRegistration_delete(notif);
307
308 // checking after deleting to avoid needing a mutex over the data - otherwise
309 // in an environment w/ multiple threads, you would need to guard access
310 EXPECT_EQ(data.instance, "");
311 EXPECT_EQ(data.binder, nullptr);
312 }
313
TEST(NdkBinder,RegisterForServiceNotificationsExisting)314 TEST(NdkBinder, RegisterForServiceNotificationsExisting) {
315 ServiceData data;
316 auto* notif = AServiceManager_registerForServiceNotifications(
317 kExistingNonNdkService, ServiceData::fillOnRegister, (void*)&data);
318 ASSERT_NE(notif, nullptr);
319
320 sleep(1); // give us a chance to fail
321 AServiceManager_NotificationRegistration_delete(notif);
322
323 // checking after deleting to avoid needing a mutex over the data - otherwise
324 // in an environment w/ multiple threads, you would need to guard access
325 EXPECT_EQ(data.instance, kExistingNonNdkService);
326 EXPECT_EQ(data.binder, ndk::SpAIBinder(AServiceManager_checkService(kExistingNonNdkService)));
327 }
328
TEST(NdkBinder,UnimplementedDump)329 TEST(NdkBinder, UnimplementedDump) {
330 ndk::SpAIBinder binder;
331 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName, binder.getR());
332 ASSERT_NE(foo, nullptr);
333 EXPECT_EQ(OK, AIBinder_dump(binder.get(), STDOUT_FILENO, nullptr, 0));
334 }
335
TEST(NdkBinder,UnimplementedShell)336 TEST(NdkBinder, UnimplementedShell) {
337 // libbinder_ndk doesn't support calling shell, so we are calling from the
338 // libbinder across processes to the NDK service which doesn't implement
339 // shell
340 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
341 sp<IBinder> testService = sm->getService(String16(IFoo::kSomeInstanceName));
342
343 Vector<String16> argsVec;
344 EXPECT_EQ(OK, IBinder::shellCommand(testService, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
345 argsVec, nullptr, nullptr));
346 }
347
TEST(NdkBinder,DoubleNumber)348 TEST(NdkBinder, DoubleNumber) {
349 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
350 ASSERT_NE(foo, nullptr);
351
352 int32_t out;
353 EXPECT_EQ(STATUS_OK, foo->doubleNumber(1, &out));
354 EXPECT_EQ(2, out);
355 }
356
TEST(NdkBinder,ReassociateBpBinderWithSameDescriptor)357 TEST(NdkBinder, ReassociateBpBinderWithSameDescriptor) {
358 ndk::SpAIBinder binder;
359 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName, binder.getR());
360
361 EXPECT_TRUE(AIBinder_isRemote(binder.get()));
362
363 EXPECT_TRUE(AIBinder_associateClass(binder.get(), IFoo::kClassDupe));
364 }
365
TEST(NdkBinder,CantHaveTwoLocalBinderClassesWithSameDescriptor)366 TEST(NdkBinder, CantHaveTwoLocalBinderClassesWithSameDescriptor) {
367 sp<IFoo> foo = sp<MyTestFoo>::make();
368 ndk::SpAIBinder binder(foo->getBinder());
369
370 EXPECT_FALSE(AIBinder_isRemote(binder.get()));
371
372 EXPECT_FALSE(AIBinder_associateClass(binder.get(), IFoo::kClassDupe));
373 }
374
TEST(NdkBinder,GetTestServiceStressTest)375 TEST(NdkBinder, GetTestServiceStressTest) {
376 // libbinder has some complicated logic to make sure only one instance of
377 // ABpBinder is associated with each binder.
378
379 constexpr size_t kNumThreads = 10;
380 constexpr size_t kNumCalls = 1000;
381 std::vector<std::thread> threads;
382
383 for (size_t i = 0; i < kNumThreads; i++) {
384 threads.push_back(std::thread([&]() {
385 for (size_t j = 0; j < kNumCalls; j++) {
386 auto binder =
387 ndk::SpAIBinder(AServiceManager_checkService(IFoo::kSomeInstanceName));
388 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
389 }
390 }));
391 }
392
393 for (auto& thread : threads) thread.join();
394 }
395
defaultInstanceCounter(const char * instance,void * context)396 void defaultInstanceCounter(const char* instance, void* context) {
397 if (strcmp(instance, "default") == 0) {
398 ++*(size_t*)(context);
399 }
400 }
401
TEST(NdkBinder,GetDeclaredInstances)402 TEST(NdkBinder, GetDeclaredInstances) {
403 bool hasLight = AServiceManager_isDeclared("android.hardware.light.ILights/default");
404
405 size_t count;
406 AServiceManager_forEachDeclaredInstance("android.hardware.light.ILights", &count,
407 defaultInstanceCounter);
408
409 // At the time of writing this test, there is no good interface guaranteed
410 // to be on all devices. Cuttlefish has light, so this will generally test
411 // things.
412 EXPECT_EQ(count, hasLight ? 1 : 0);
413 }
414
TEST(NdkBinder,GetLazyService)415 TEST(NdkBinder, GetLazyService) {
416 // Not declared in the vintf manifest
417 ASSERT_FALSE(AServiceManager_isDeclared(kLazyBinderNdkUnitTestService));
418 ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
419 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
420 aidl::IBinderNdkUnitTest::fromBinder(binder);
421 ASSERT_NE(service, nullptr);
422
423 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
424 }
425
TEST(NdkBinder,IsUpdatable)426 TEST(NdkBinder, IsUpdatable) {
427 bool isUpdatable = AServiceManager_isUpdatableViaApex("android.hardware.light.ILights/default");
428 EXPECT_EQ(isUpdatable, false);
429 }
430
TEST(NdkBinder,GetUpdatableViaApex)431 TEST(NdkBinder, GetUpdatableViaApex) {
432 std::optional<std::string> updatableViaApex;
433 AServiceManager_getUpdatableApexName(
434 "android.hardware.light.ILights/default", &updatableViaApex,
435 [](const char* apexName, void* context) {
436 *static_cast<std::optional<std::string>*>(context) = apexName;
437 });
438 EXPECT_EQ(updatableViaApex, std::nullopt) << *updatableViaApex;
439 }
440
441 // This is too slow
TEST(NdkBinder,CheckLazyServiceShutDown)442 TEST(NdkBinder, CheckLazyServiceShutDown) {
443 ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
444 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
445 aidl::IBinderNdkUnitTest::fromBinder(binder);
446 ASSERT_NE(service, nullptr);
447
448 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
449 binder = nullptr;
450 service = nullptr;
451 IPCThreadState::self()->flushCommands();
452 // Make sure the service is dead after some time of no use
453 sleep(kShutdownWaitTime);
454 ASSERT_EQ(nullptr, AServiceManager_checkService(kLazyBinderNdkUnitTestService));
455 }
456
TEST(NdkBinder,ForcedPersistenceTest)457 TEST(NdkBinder, ForcedPersistenceTest) {
458 for (int i = 0; i < 2; i++) {
459 ndk::SpAIBinder binder(AServiceManager_waitForService(kForcePersistNdkUnitTestService));
460 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
461 aidl::IBinderNdkUnitTest::fromBinder(binder);
462 ASSERT_NE(service, nullptr);
463 ASSERT_TRUE(service->forcePersist(i == 0).isOk());
464
465 binder = nullptr;
466 service = nullptr;
467 IPCThreadState::self()->flushCommands();
468
469 sleep(kShutdownWaitTime);
470
471 bool isRunning = isServiceRunning(kForcePersistNdkUnitTestService);
472
473 if (i == 0) {
474 ASSERT_TRUE(isRunning) << "Service shut down when it shouldn't have.";
475 } else {
476 ASSERT_FALSE(isRunning) << "Service failed to shut down.";
477 }
478 }
479 }
480
TEST(NdkBinder,ActiveServicesCallbackTest)481 TEST(NdkBinder, ActiveServicesCallbackTest) {
482 ndk::SpAIBinder binder(AServiceManager_waitForService(kActiveServicesNdkUnitTestService));
483 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
484 aidl::IBinderNdkUnitTest::fromBinder(binder);
485 ASSERT_NE(service, nullptr);
486 ASSERT_TRUE(service->setCustomActiveServicesCallback().isOk());
487
488 binder = nullptr;
489 service = nullptr;
490 IPCThreadState::self()->flushCommands();
491
492 sleep(kShutdownWaitTime);
493
494 ASSERT_FALSE(isServiceRunning(kActiveServicesNdkUnitTestService))
495 << "Service failed to shut down.";
496 }
497
498 struct DeathRecipientCookie {
499 std::function<void(void)>*onDeath, *onUnlink;
500 };
LambdaOnDeath(void * cookie)501 void LambdaOnDeath(void* cookie) {
502 auto funcs = static_cast<DeathRecipientCookie*>(cookie);
503 (*funcs->onDeath)();
504 };
LambdaOnUnlink(void * cookie)505 void LambdaOnUnlink(void* cookie) {
506 auto funcs = static_cast<DeathRecipientCookie*>(cookie);
507 (*funcs->onUnlink)();
508 };
TEST(NdkBinder,DeathRecipient)509 TEST(NdkBinder, DeathRecipient) {
510 using namespace std::chrono_literals;
511
512 AIBinder* binder;
513 sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor, &binder);
514 ASSERT_NE(nullptr, foo.get());
515 ASSERT_NE(nullptr, binder);
516
517 std::mutex deathMutex;
518 std::condition_variable deathCv;
519 bool deathReceived = false;
520
521 std::function<void(void)> onDeath = [&] {
522 std::cerr << "Binder died (as requested)." << std::endl;
523 deathReceived = true;
524 deathCv.notify_one();
525 };
526
527 std::mutex unlinkMutex;
528 std::condition_variable unlinkCv;
529 bool unlinkReceived = false;
530 bool wasDeathReceivedFirst = false;
531
532 std::function<void(void)> onUnlink = [&] {
533 std::cerr << "Binder unlinked (as requested)." << std::endl;
534 wasDeathReceivedFirst = deathReceived;
535 unlinkReceived = true;
536 unlinkCv.notify_one();
537 };
538
539 DeathRecipientCookie cookie = {&onDeath, &onUnlink};
540
541 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
542 AIBinder_DeathRecipient_setOnUnlinked(recipient, LambdaOnUnlink);
543
544 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&cookie)));
545
546 // the binder driver should return this if the service dies during the transaction
547 EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
548
549 foo = nullptr;
550
551 std::unique_lock<std::mutex> lockDeath(deathMutex);
552 EXPECT_TRUE(deathCv.wait_for(lockDeath, 1s, [&] { return deathReceived; }));
553 EXPECT_TRUE(deathReceived);
554
555 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
556 EXPECT_TRUE(deathCv.wait_for(lockUnlink, 1s, [&] { return unlinkReceived; }));
557 EXPECT_TRUE(unlinkReceived);
558 EXPECT_TRUE(wasDeathReceivedFirst);
559
560 AIBinder_DeathRecipient_delete(recipient);
561 AIBinder_decStrong(binder);
562 binder = nullptr;
563 }
564
TEST(NdkBinder,RetrieveNonNdkService)565 TEST(NdkBinder, RetrieveNonNdkService) {
566 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
567 ASSERT_NE(nullptr, binder);
568 EXPECT_TRUE(AIBinder_isRemote(binder));
569 EXPECT_TRUE(AIBinder_isAlive(binder));
570 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
571
572 AIBinder_decStrong(binder);
573 }
574
OnBinderDeath(void * cookie)575 void OnBinderDeath(void* cookie) {
576 LOG(ERROR) << "BINDER DIED. COOKIE: " << cookie;
577 }
578
TEST(NdkBinder,LinkToDeath)579 TEST(NdkBinder, LinkToDeath) {
580 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
581 ASSERT_NE(nullptr, binder);
582
583 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
584 ASSERT_NE(nullptr, recipient);
585
586 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
587 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
588 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
589 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
590 EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
591
592 AIBinder_DeathRecipient_delete(recipient);
593 AIBinder_decStrong(binder);
594 }
595
TEST(NdkBinder,SetInheritRt)596 TEST(NdkBinder, SetInheritRt) {
597 // functional test in binderLibTest
598 sp<IFoo> foo = sp<MyTestFoo>::make();
599 AIBinder* binder = foo->getBinder();
600
601 // does not abort
602 AIBinder_setInheritRt(binder, true);
603 AIBinder_setInheritRt(binder, false);
604 AIBinder_setInheritRt(binder, true);
605
606 AIBinder_decStrong(binder);
607 }
608
TEST(NdkBinder,SetInheritRtNonLocal)609 TEST(NdkBinder, SetInheritRtNonLocal) {
610 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
611 ASSERT_NE(binder, nullptr);
612
613 ASSERT_TRUE(AIBinder_isRemote(binder));
614
615 EXPECT_DEATH(AIBinder_setInheritRt(binder, true), "");
616 EXPECT_DEATH(AIBinder_setInheritRt(binder, false), "");
617
618 AIBinder_decStrong(binder);
619 }
620
TEST(NdkBinder,AddNullService)621 TEST(NdkBinder, AddNullService) {
622 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, AServiceManager_addService(nullptr, "any-service-name"));
623 }
624
TEST(NdkBinder,AddInvalidServiceName)625 TEST(NdkBinder, AddInvalidServiceName) {
626 sp<IFoo> foo = new MyTestFoo;
627 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, foo->addService("!@#$%^&"));
628 }
629
TEST(NdkBinder,GetServiceInProcess)630 TEST(NdkBinder, GetServiceInProcess) {
631 static const char* kInstanceName = "test-get-service-in-process";
632
633 sp<IFoo> foo = new MyTestFoo;
634 EXPECT_EQ(EX_NONE, foo->addService(kInstanceName));
635
636 ndk::SpAIBinder binder;
637 sp<IFoo> getFoo = IFoo::getService(kInstanceName, binder.getR());
638 EXPECT_EQ(foo.get(), getFoo.get());
639
640 int32_t out;
641 EXPECT_EQ(STATUS_OK, getFoo->doubleNumber(1, &out));
642 EXPECT_EQ(2, out);
643 }
644
TEST(NdkBinder,EqualityOfRemoteBinderPointer)645 TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
646 AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
647 ASSERT_NE(nullptr, binderA);
648
649 AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
650 ASSERT_NE(nullptr, binderB);
651
652 EXPECT_EQ(binderA, binderB);
653
654 AIBinder_decStrong(binderA);
655 AIBinder_decStrong(binderB);
656 }
657
TEST(NdkBinder,ToFromJavaNullptr)658 TEST(NdkBinder, ToFromJavaNullptr) {
659 EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
660 EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
661 }
662
TEST(NdkBinder,ABpBinderRefCount)663 TEST(NdkBinder, ABpBinderRefCount) {
664 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
665 AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
666
667 ASSERT_NE(nullptr, binder);
668 EXPECT_EQ(1, AIBinder_debugGetRefCount(binder));
669
670 AIBinder_decStrong(binder);
671
672 ASSERT_EQ(nullptr, AIBinder_Weak_promote(wBinder));
673
674 AIBinder_Weak_delete(wBinder);
675 }
676
TEST(NdkBinder,AddServiceMultipleTimes)677 TEST(NdkBinder, AddServiceMultipleTimes) {
678 static const char* kInstanceName1 = "test-multi-1";
679 static const char* kInstanceName2 = "test-multi-2";
680 sp<IFoo> foo = new MyTestFoo;
681 EXPECT_EQ(EX_NONE, foo->addService(kInstanceName1));
682 EXPECT_EQ(EX_NONE, foo->addService(kInstanceName2));
683 EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
684 }
685
TEST(NdkBinder,RequestedSidWorks)686 TEST(NdkBinder, RequestedSidWorks) {
687 ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
688 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
689 aidl::IBinderNdkUnitTest::fromBinder(binder);
690
691 bool gotSid = false;
692 EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk());
693 EXPECT_TRUE(gotSid);
694 }
695
TEST(NdkBinder,SentAidlBinderCanBeDestroyed)696 TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
697 static volatile bool destroyed = false;
698 static std::mutex dMutex;
699 static std::condition_variable cv;
700
701 class MyEmpty : public aidl::BnEmpty {
702 virtual ~MyEmpty() {
703 destroyed = true;
704 cv.notify_one();
705 }
706 };
707
708 std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
709
710 ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
711 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
712 aidl::IBinderNdkUnitTest::fromBinder(binder);
713
714 EXPECT_FALSE(destroyed);
715
716 service->takeInterface(empty);
717 service->forceFlushCommands();
718 empty = nullptr;
719
720 // give other binder thread time to process commands
721 {
722 using namespace std::chrono_literals;
723 std::unique_lock<std::mutex> lk(dMutex);
724 cv.wait_for(lk, 1s, [] { return destroyed; });
725 }
726
727 EXPECT_TRUE(destroyed);
728 }
729
TEST(NdkBinder,ConvertToPlatformBinder)730 TEST(NdkBinder, ConvertToPlatformBinder) {
731 for (const ndk::SpAIBinder& binder :
732 {// remote
733 ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
734 // local
735 ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
736 // convert to platform binder
737 EXPECT_NE(binder.get(), nullptr);
738 sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
739 EXPECT_NE(platformBinder.get(), nullptr);
740 auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
741 EXPECT_NE(proxy, nullptr);
742
743 // use platform binder
744 int out;
745 EXPECT_TRUE(proxy->repeatInt(4, &out).isOk());
746 EXPECT_EQ(out, 4);
747
748 // convert back
749 ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
750 EXPECT_EQ(backBinder.get(), binder.get());
751 }
752 }
753
TEST(NdkBinder,ConvertToPlatformParcel)754 TEST(NdkBinder, ConvertToPlatformParcel) {
755 ndk::ScopedAParcel parcel = ndk::ScopedAParcel(AParcel_create());
756 EXPECT_EQ(OK, AParcel_writeInt32(parcel.get(), 42));
757
758 android::Parcel* pparcel = AParcel_viewPlatformParcel(parcel.get());
759 pparcel->setDataPosition(0);
760 EXPECT_EQ(42, pparcel->readInt32());
761 }
762
TEST(NdkBinder,GetAndVerifyScopedAIBinder_Weak)763 TEST(NdkBinder, GetAndVerifyScopedAIBinder_Weak) {
764 for (const ndk::SpAIBinder& binder :
765 {// remote
766 ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
767 // local
768 ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
769 // get a const ScopedAIBinder_Weak and verify promote
770 EXPECT_NE(binder.get(), nullptr);
771 const ndk::ScopedAIBinder_Weak wkAIBinder =
772 ndk::ScopedAIBinder_Weak(AIBinder_Weak_new(binder.get()));
773 EXPECT_EQ(wkAIBinder.promote().get(), binder.get());
774 // get another ScopedAIBinder_Weak and verify
775 ndk::ScopedAIBinder_Weak wkAIBinder2 =
776 ndk::ScopedAIBinder_Weak(AIBinder_Weak_new(binder.get()));
777 EXPECT_FALSE(AIBinder_Weak_lt(wkAIBinder.get(), wkAIBinder2.get()));
778 EXPECT_FALSE(AIBinder_Weak_lt(wkAIBinder2.get(), wkAIBinder.get()));
779 EXPECT_EQ(wkAIBinder2.promote(), wkAIBinder.promote());
780 }
781 }
782
783 class MyResultReceiver : public BnResultReceiver {
784 public:
785 Mutex mMutex;
786 Condition mCondition;
787 bool mHaveResult = false;
788 int32_t mResult = 0;
789
send(int32_t resultCode)790 virtual void send(int32_t resultCode) {
791 AutoMutex _l(mMutex);
792 mResult = resultCode;
793 mHaveResult = true;
794 mCondition.signal();
795 }
796
waitForResult()797 int32_t waitForResult() {
798 AutoMutex _l(mMutex);
799 while (!mHaveResult) {
800 mCondition.wait(mMutex);
801 }
802 return mResult;
803 }
804 };
805
806 class MyShellCallback : public BnShellCallback {
807 public:
openFile(const String16 &,const String16 &,const String16 &)808 virtual int openFile(const String16& /*path*/, const String16& /*seLinuxContext*/,
809 const String16& /*mode*/) {
810 // Empty implementation.
811 return 0;
812 }
813 };
814
ReadFdToString(int fd,std::string * content)815 bool ReadFdToString(int fd, std::string* content) {
816 char buf[64];
817 ssize_t n;
818 while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
819 content->append(buf, n);
820 }
821 return (n == 0) ? true : false;
822 }
823
shellCmdToString(sp<IBinder> unitTestService,const std::vector<const char * > & args)824 std::string shellCmdToString(sp<IBinder> unitTestService, const std::vector<const char*>& args) {
825 int inFd[2] = {-1, -1};
826 int outFd[2] = {-1, -1};
827 int errFd[2] = {-1, -1};
828
829 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, inFd));
830 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, outFd));
831 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, errFd));
832
833 sp<MyShellCallback> cb = new MyShellCallback();
834 sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
835
836 Vector<String16> argsVec;
837 for (int i = 0; i < args.size(); i++) {
838 argsVec.add(String16(args[i]));
839 }
840 status_t error = IBinder::shellCommand(unitTestService, inFd[0], outFd[0], errFd[0], argsVec,
841 cb, resultReceiver);
842 EXPECT_EQ(error, android::OK);
843
844 status_t res = resultReceiver->waitForResult();
845 EXPECT_EQ(res, android::OK);
846
847 close(inFd[0]);
848 close(inFd[1]);
849 close(outFd[0]);
850 close(errFd[0]);
851 close(errFd[1]);
852
853 std::string ret;
854 EXPECT_TRUE(ReadFdToString(outFd[1], &ret));
855 close(outFd[1]);
856 return ret;
857 }
858
TEST(NdkBinder,UseHandleShellCommand)859 TEST(NdkBinder, UseHandleShellCommand) {
860 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
861 sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
862
863 EXPECT_EQ("", shellCmdToString(testService, {}));
864 EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
865 EXPECT_EQ("Hello world!", shellCmdToString(testService, {"Hello ", "world!"}));
866 EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
867 }
868
TEST(NdkBinder,FlaggedServiceAccessible)869 TEST(NdkBinder, FlaggedServiceAccessible) {
870 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
871 sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestServiceFlagged));
872 ASSERT_NE(nullptr, testService);
873 }
874
TEST(NdkBinder,GetClassInterfaceDescriptor)875 TEST(NdkBinder, GetClassInterfaceDescriptor) {
876 ASSERT_STREQ(IFoo::kIFooDescriptor, AIBinder_Class_getDescriptor(IFoo::kClass));
877 }
878
addOne(int * to)879 static void addOne(int* to) {
880 if (!to) return;
881 ++(*to);
882 }
883 struct FakeResource : public ndk::impl::ScopedAResource<int*, addOne, nullptr> {
FakeResourceFakeResource884 explicit FakeResource(int* a) : ScopedAResource(a) {}
885 };
886
TEST(NdkBinder_ScopedAResource,GetDelete)887 TEST(NdkBinder_ScopedAResource, GetDelete) {
888 int deleteCount = 0;
889 { FakeResource resource(&deleteCount); }
890 EXPECT_EQ(deleteCount, 1);
891 }
892
TEST(NdkBinder_ScopedAResource,Release)893 TEST(NdkBinder_ScopedAResource, Release) {
894 int deleteCount = 0;
895 {
896 FakeResource resource(&deleteCount);
897 (void)resource.release();
898 }
899 EXPECT_EQ(deleteCount, 0);
900 }
901
main(int argc,char * argv[])902 int main(int argc, char* argv[]) {
903 ::testing::InitGoogleTest(&argc, argv);
904
905 if (fork() == 0) {
906 prctl(PR_SET_PDEATHSIG, SIGHUP);
907 return manualThreadPoolService(IFoo::kInstanceNameToDieFor);
908 }
909 if (fork() == 0) {
910 prctl(PR_SET_PDEATHSIG, SIGHUP);
911 return manualPollingService(IFoo::kSomeInstanceName);
912 }
913 if (fork() == 0) {
914 prctl(PR_SET_PDEATHSIG, SIGHUP);
915 return lazyService(kLazyBinderNdkUnitTestService);
916 }
917 if (fork() == 0) {
918 prctl(PR_SET_PDEATHSIG, SIGHUP);
919 return lazyService(kForcePersistNdkUnitTestService);
920 }
921 if (fork() == 0) {
922 prctl(PR_SET_PDEATHSIG, SIGHUP);
923 return lazyService(kActiveServicesNdkUnitTestService);
924 }
925 if (fork() == 0) {
926 prctl(PR_SET_PDEATHSIG, SIGHUP);
927 return generatedService();
928 }
929 if (fork() == 0) {
930 prctl(PR_SET_PDEATHSIG, SIGHUP);
931 // We may want to change this flag to be more generic ones for the future
932 AServiceManager_AddServiceFlag test_flags =
933 AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED;
934 return generatedFlaggedService(test_flags, kBinderNdkUnitTestServiceFlagged);
935 }
936
937 ABinderProcess_setThreadPoolMaxThreadCount(1); // to receive death notifications/callbacks
938 ABinderProcess_startThreadPool();
939
940 return RUN_ALL_TESTS();
941 }
942
943 #include <android/binder_auto_utils.h>
944 #include <android/binder_interface_utils.h>
945 #include <android/binder_parcel_utils.h>
946