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 <thread>
43
44 #include "android/binder_ibinder.h"
45
46 using namespace android;
47
48 constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
49 constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
50 constexpr char kLazyBinderNdkUnitTestService[] = "LazyBinderNdkUnitTest";
51 constexpr char kForcePersistNdkUnitTestService[] = "ForcePersistNdkUnitTestService";
52 constexpr char kActiveServicesNdkUnitTestService[] = "ActiveServicesNdkUnitTestService";
53 constexpr char kBinderNdkUnitTestServiceFlagged[] = "BinderNdkUnitTestFlagged";
54
55 constexpr unsigned int kShutdownWaitTime = 11;
56 constexpr uint64_t kContextTestValue = 0xb4e42fb4d9a1d715;
57
58 class MyTestFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)59 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
60 *out = 2 * in;
61 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
62 return STATUS_OK;
63 }
die()64 binder_status_t die() override {
65 ADD_FAILURE() << "die called on local instance";
66 return STATUS_OK;
67 }
68 };
69
70 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
repeatInt(int32_t in,int32_t * out)71 ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
72 *out = in;
73 return ndk::ScopedAStatus::ok();
74 }
takeInterface(const std::shared_ptr<aidl::IEmpty> & empty)75 ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
76 (void)empty;
77 return ndk::ScopedAStatus::ok();
78 }
forceFlushCommands()79 ndk::ScopedAStatus forceFlushCommands() {
80 // warning: this is assuming that libbinder_ndk is using the same copy
81 // of libbinder that we are.
82 android::IPCThreadState::self()->flushCommands();
83 return ndk::ScopedAStatus::ok();
84 }
getsRequestedSid(bool * out)85 ndk::ScopedAStatus getsRequestedSid(bool* out) {
86 const char* sid = AIBinder_getCallingSid();
87 std::cout << "Got security context: " << (sid ?: "null") << std::endl;
88 *out = sid != nullptr;
89 return ndk::ScopedAStatus::ok();
90 }
handleShellCommand(int,int out,int,const char ** args,uint32_t numArgs)91 binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
92 uint32_t numArgs) override {
93 for (uint32_t i = 0; i < numArgs; i++) {
94 dprintf(out, "%s", args[i]);
95 }
96 fsync(out);
97 return STATUS_OK;
98 }
forcePersist(bool persist)99 ndk::ScopedAStatus forcePersist(bool persist) {
100 AServiceManager_forceLazyServicesPersist(persist);
101 return ndk::ScopedAStatus::ok();
102 }
setCustomActiveServicesCallback()103 ndk::ScopedAStatus setCustomActiveServicesCallback() {
104 AServiceManager_setActiveServicesCallback(activeServicesCallback, this);
105 return ndk::ScopedAStatus::ok();
106 }
activeServicesCallback(bool hasClients,void * context)107 static bool activeServicesCallback(bool hasClients, void* context) {
108 if (hasClients) {
109 LOG(INFO) << "hasClients, so not unregistering.";
110 return false;
111 }
112
113 // Unregister all services
114 if (!AServiceManager_tryUnregister()) {
115 LOG(INFO) << "Could not unregister service the first time.";
116 // Prevent shutdown (test will fail)
117 return false;
118 }
119
120 // Re-register all services
121 AServiceManager_reRegister();
122
123 // Unregister again before shutdown
124 if (!AServiceManager_tryUnregister()) {
125 LOG(INFO) << "Could not unregister service the second time.";
126 // Prevent shutdown (test will fail)
127 return false;
128 }
129
130 // Check if the context was passed correctly
131 MyBinderNdkUnitTest* service = static_cast<MyBinderNdkUnitTest*>(context);
132 if (service->contextTestValue != kContextTestValue) {
133 LOG(INFO) << "Incorrect context value.";
134 // Prevent shutdown (test will fail)
135 return false;
136 }
137
138 exit(EXIT_SUCCESS);
139 // Unreachable
140 }
141
142 uint64_t contextTestValue = kContextTestValue;
143 };
144
generatedService()145 int generatedService() {
146 ABinderProcess_setThreadPoolMaxThreadCount(0);
147
148 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
149 auto binder = service->asBinder();
150
151 AIBinder_setRequestingSid(binder.get(), true);
152
153 binder_exception_t exception =
154 AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
155
156 if (exception != EX_NONE) {
157 LOG(FATAL) << "Could not register: " << exception << " " << kBinderNdkUnitTestService;
158 }
159
160 ABinderProcess_joinThreadPool();
161
162 return 1; // should not return
163 }
164
generatedFlaggedService(const AServiceManager_AddServiceFlag flags,const char * instance)165 int generatedFlaggedService(const AServiceManager_AddServiceFlag flags, const char* instance) {
166 ABinderProcess_setThreadPoolMaxThreadCount(0);
167
168 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
169 auto binder = service->asBinder();
170
171 binder_exception_t exception =
172 AServiceManager_addServiceWithFlags(binder.get(), instance, flags);
173
174 if (exception != EX_NONE) {
175 LOG(FATAL) << "Could not register: " << exception << " " << instance;
176 }
177
178 ABinderProcess_joinThreadPool();
179
180 return 1; // should not return
181 }
182
183 // manually-written parceling class considered bad practice
184 class MyFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)185 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
186 *out = 2 * in;
187 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
188 return STATUS_OK;
189 }
190
die()191 binder_status_t die() override {
192 LOG(FATAL) << "IFoo::die called!";
193 return STATUS_UNKNOWN_ERROR;
194 }
195 };
196
manualService(const char * instance)197 void manualService(const char* instance) {
198 // Strong reference to MyFoo kept by service manager.
199 binder_exception_t exception = (new MyFoo)->addService(instance);
200
201 if (exception != EX_NONE) {
202 LOG(FATAL) << "Could not register: " << exception << " " << instance;
203 }
204 }
manualPollingService(const char * instance)205 int manualPollingService(const char* instance) {
206 int fd;
207 CHECK(STATUS_OK == ABinderProcess_setupPolling(&fd));
208 manualService(instance);
209
210 class Handler : public LooperCallback {
211 int handleEvent(int /*fd*/, int /*events*/, void* /*data*/) override {
212 ABinderProcess_handlePolledCommands();
213 return 1; // Continue receiving callbacks.
214 }
215 };
216
217 sp<Looper> looper = Looper::prepare(0 /* opts */);
218 looper->addFd(fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, new Handler(), nullptr /*data*/);
219 // normally, would add additional fds
220 while (true) {
221 looper->pollAll(-1 /* timeoutMillis */);
222 }
223 return 1; // should not reach
224 }
manualThreadPoolService(const char * instance)225 int manualThreadPoolService(const char* instance) {
226 ABinderProcess_setThreadPoolMaxThreadCount(0);
227 manualService(instance);
228 ABinderProcess_joinThreadPool();
229 return 1;
230 }
231
lazyService(const char * instance)232 int lazyService(const char* instance) {
233 ABinderProcess_setThreadPoolMaxThreadCount(0);
234 // Wait to register this service to make sure the main test process will
235 // actually wait for the service to be available. Tested with sleep(60),
236 // and reduced for sake of time.
237 sleep(1);
238 // Strong reference to MyBinderNdkUnitTest kept by service manager.
239 // This is just for testing, it has no corresponding init behavior.
240 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
241 auto binder = service->asBinder();
242
243 binder_status_t status = AServiceManager_registerLazyService(binder.get(), instance);
244 if (status != STATUS_OK) {
245 LOG(FATAL) << "Could not register: " << status << " " << instance;
246 }
247
248 ABinderProcess_joinThreadPool();
249
250 return 1; // should not return
251 }
252
isServiceRunning(const char * serviceName)253 bool isServiceRunning(const char* serviceName) {
254 AIBinder* binder = AServiceManager_checkService(serviceName);
255 if (binder == nullptr) {
256 return false;
257 }
258 AIBinder_decStrong(binder);
259
260 return true;
261 }
262
TEST(NdkBinder,DetectDoubleOwn)263 TEST(NdkBinder, DetectDoubleOwn) {
264 auto badService = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
265 EXPECT_DEATH(std::shared_ptr<MyBinderNdkUnitTest>(badService.get()),
266 "Is this object double-owned?");
267 }
268
TEST(NdkBinder,DetectNoSharedRefBaseCreated)269 TEST(NdkBinder, DetectNoSharedRefBaseCreated) {
270 EXPECT_DEATH(MyBinderNdkUnitTest(), "SharedRefBase: no ref created during lifetime");
271 }
272
TEST(NdkBinder,GetServiceThatDoesntExist)273 TEST(NdkBinder, GetServiceThatDoesntExist) {
274 sp<IFoo> foo = IFoo::getService("asdfghkl;");
275 EXPECT_EQ(nullptr, foo.get());
276 }
277
TEST(NdkBinder,CheckServiceThatDoesntExist)278 TEST(NdkBinder, CheckServiceThatDoesntExist) {
279 AIBinder* binder = AServiceManager_checkService("asdfghkl;");
280 ASSERT_EQ(nullptr, binder);
281 }
282
TEST(NdkBinder,CheckServiceThatDoesExist)283 TEST(NdkBinder, CheckServiceThatDoesExist) {
284 AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
285 ASSERT_NE(nullptr, binder) << "Could not get " << kExistingNonNdkService;
286 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder)) << "Could not ping " << kExistingNonNdkService;
287
288 AIBinder_decStrong(binder);
289 }
290
291 struct ServiceData {
292 std::string instance;
293 ndk::SpAIBinder binder;
294
fillOnRegisterServiceData295 static void fillOnRegister(const char* instance, AIBinder* binder, void* cookie) {
296 ServiceData* d = reinterpret_cast<ServiceData*>(cookie);
297 d->instance = instance;
298 d->binder = ndk::SpAIBinder(binder);
299 }
300 };
301
TEST(NdkBinder,RegisterForServiceNotificationsNonExisting)302 TEST(NdkBinder, RegisterForServiceNotificationsNonExisting) {
303 ServiceData data;
304 auto* notif = AServiceManager_registerForServiceNotifications(
305 "DOES_NOT_EXIST", ServiceData::fillOnRegister, (void*)&data);
306 ASSERT_NE(notif, nullptr);
307
308 sleep(1); // give us a chance to fail
309 AServiceManager_NotificationRegistration_delete(notif);
310
311 // checking after deleting to avoid needing a mutex over the data - otherwise
312 // in an environment w/ multiple threads, you would need to guard access
313 EXPECT_EQ(data.instance, "");
314 EXPECT_EQ(data.binder, nullptr);
315 }
316
TEST(NdkBinder,RegisterForServiceNotificationsExisting)317 TEST(NdkBinder, RegisterForServiceNotificationsExisting) {
318 ServiceData data;
319 auto* notif = AServiceManager_registerForServiceNotifications(
320 kExistingNonNdkService, ServiceData::fillOnRegister, (void*)&data);
321 ASSERT_NE(notif, nullptr);
322
323 sleep(1); // give us a chance to fail
324 AServiceManager_NotificationRegistration_delete(notif);
325
326 // checking after deleting to avoid needing a mutex over the data - otherwise
327 // in an environment w/ multiple threads, you would need to guard access
328 EXPECT_EQ(data.instance, kExistingNonNdkService);
329 EXPECT_EQ(data.binder, ndk::SpAIBinder(AServiceManager_checkService(kExistingNonNdkService)));
330 }
331
TEST(NdkBinder,UnimplementedDump)332 TEST(NdkBinder, UnimplementedDump) {
333 ndk::SpAIBinder binder;
334 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName, binder.getR());
335 ASSERT_NE(foo, nullptr);
336 EXPECT_EQ(OK, AIBinder_dump(binder.get(), STDOUT_FILENO, nullptr, 0));
337 }
338
TEST(NdkBinder,UnimplementedShell)339 TEST(NdkBinder, UnimplementedShell) {
340 // libbinder_ndk doesn't support calling shell, so we are calling from the
341 // libbinder across processes to the NDK service which doesn't implement
342 // shell
343 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
344 #pragma clang diagnostic push
345 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
346 sp<IBinder> testService = sm->getService(String16(IFoo::kSomeInstanceName));
347 #pragma clang diagnostic pop
348
349 Vector<String16> argsVec;
350 EXPECT_EQ(OK, IBinder::shellCommand(testService, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
351 argsVec, nullptr, nullptr));
352 }
353
TEST(NdkBinder,DoubleNumber)354 TEST(NdkBinder, DoubleNumber) {
355 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
356 ASSERT_NE(foo, nullptr);
357
358 int32_t out;
359 EXPECT_EQ(STATUS_OK, foo->doubleNumber(1, &out));
360 EXPECT_EQ(2, out);
361 }
362
TEST(NdkBinder,ReassociateBpBinderWithSameDescriptor)363 TEST(NdkBinder, ReassociateBpBinderWithSameDescriptor) {
364 ndk::SpAIBinder binder;
365 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName, binder.getR());
366
367 EXPECT_TRUE(AIBinder_isRemote(binder.get()));
368
369 EXPECT_TRUE(AIBinder_associateClass(binder.get(), IFoo::kClassDupe));
370 }
371
TEST(NdkBinder,CantHaveTwoLocalBinderClassesWithSameDescriptor)372 TEST(NdkBinder, CantHaveTwoLocalBinderClassesWithSameDescriptor) {
373 sp<IFoo> foo = sp<MyTestFoo>::make();
374 ndk::SpAIBinder binder(foo->getBinder());
375
376 EXPECT_FALSE(AIBinder_isRemote(binder.get()));
377
378 EXPECT_FALSE(AIBinder_associateClass(binder.get(), IFoo::kClassDupe));
379 }
380
TEST(NdkBinder,GetTestServiceStressTest)381 TEST(NdkBinder, GetTestServiceStressTest) {
382 constexpr size_t kNumThreads = 10;
383 constexpr size_t kNumCalls = 1000;
384 std::vector<std::thread> threads;
385
386 // this is not a lazy service, but we must make sure that it's started before calling
387 // checkService on it, since the other process serving it might not be started yet.
388 {
389 // getService, not waitForService, to take advantage of timeout
390 #pragma clang diagnostic push
391 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
392 auto binder = ndk::SpAIBinder(AServiceManager_getService(IFoo::kSomeInstanceName));
393 #pragma clang diagnostic pop
394 ASSERT_NE(nullptr, binder.get());
395 }
396
397 for (size_t i = 0; i < kNumThreads; i++) {
398 threads.push_back(std::thread([&]() {
399 for (size_t j = 0; j < kNumCalls; j++) {
400 auto binder =
401 ndk::SpAIBinder(AServiceManager_checkService(IFoo::kSomeInstanceName));
402 ASSERT_NE(nullptr, binder.get());
403 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
404 }
405 }));
406 }
407
408 for (auto& thread : threads) thread.join();
409 }
410
defaultInstanceCounter(const char * instance,void * context)411 void defaultInstanceCounter(const char* instance, void* context) {
412 if (strcmp(instance, "default") == 0) {
413 ++*(size_t*)(context);
414 }
415 }
416
TEST(NdkBinder,GetDeclaredInstances)417 TEST(NdkBinder, GetDeclaredInstances) {
418 bool hasLight = AServiceManager_isDeclared("android.hardware.light.ILights/default");
419
420 size_t count;
421 AServiceManager_forEachDeclaredInstance("android.hardware.light.ILights", &count,
422 defaultInstanceCounter);
423
424 // At the time of writing this test, there is no good interface guaranteed
425 // to be on all devices. Cuttlefish has light, so this will generally test
426 // things.
427 EXPECT_EQ(count, hasLight ? 1 : 0);
428 }
429
TEST(NdkBinder,GetLazyService)430 TEST(NdkBinder, GetLazyService) {
431 // Not declared in the vintf manifest
432 ASSERT_FALSE(AServiceManager_isDeclared(kLazyBinderNdkUnitTestService));
433 ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
434 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
435 aidl::IBinderNdkUnitTest::fromBinder(binder);
436 ASSERT_NE(service, nullptr);
437
438 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
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 LOG(INFO) << "ActiveServicesCallbackTest starting";
483
484 ndk::SpAIBinder binder(AServiceManager_waitForService(kActiveServicesNdkUnitTestService));
485 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
486 aidl::IBinderNdkUnitTest::fromBinder(binder);
487 ASSERT_NE(service, nullptr);
488 ASSERT_TRUE(service->setCustomActiveServicesCallback().isOk());
489
490 binder = nullptr;
491 service = nullptr;
492 IPCThreadState::self()->flushCommands();
493
494 LOG(INFO) << "ActiveServicesCallbackTest about to sleep";
495 sleep(kShutdownWaitTime);
496
497 ASSERT_FALSE(isServiceRunning(kActiveServicesNdkUnitTestService))
498 << "Service failed to shut down.";
499 }
500
501 struct DeathRecipientCookie {
502 std::function<void(void)>*onDeath, *onUnlink;
503
504 // may contain additional data
505 // - if it contains AIBinder, then you must call AIBinder_unlinkToDeath manually,
506 // because it would form a strong reference cycle
507 // - if it points to a data member of another structure, this should have a weak
508 // promotable reference or a strong reference, in case that object is deleted
509 // while the death recipient is firing
510 };
LambdaOnDeath(void * cookie)511 void LambdaOnDeath(void* cookie) {
512 auto funcs = static_cast<DeathRecipientCookie*>(cookie);
513
514 // may reference other cookie members
515
516 (*funcs->onDeath)();
517 };
LambdaOnUnlink(void * cookie)518 void LambdaOnUnlink(void* cookie) {
519 auto funcs = static_cast<DeathRecipientCookie*>(cookie);
520 (*funcs->onUnlink)();
521
522 // may reference other cookie members
523
524 delete funcs;
525 };
TEST(NdkBinder,DeathRecipient)526 TEST(NdkBinder, DeathRecipient) {
527 using namespace std::chrono_literals;
528
529 AIBinder* binder;
530 sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor, &binder);
531 ASSERT_NE(nullptr, foo.get());
532 ASSERT_NE(nullptr, binder);
533
534 std::mutex deathMutex;
535 std::condition_variable deathCv;
536 bool deathReceived = false;
537
538 std::function<void(void)> onDeath = [&] {
539 std::unique_lock<std::mutex> lockDeath(deathMutex);
540 std::cerr << "Binder died (as requested)." << std::endl;
541 deathReceived = true;
542 deathCv.notify_one();
543 };
544
545 std::mutex unlinkMutex;
546 std::condition_variable unlinkCv;
547 bool unlinkReceived = false;
548 bool wasDeathReceivedFirst = false;
549
550 std::function<void(void)> onUnlink = [&] {
551 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
552 std::cerr << "Binder unlinked (as requested)." << std::endl;
553 wasDeathReceivedFirst = deathReceived;
554 unlinkReceived = true;
555 unlinkCv.notify_one();
556 };
557
558 DeathRecipientCookie* cookie = new DeathRecipientCookie{&onDeath, &onUnlink};
559
560 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
561 AIBinder_DeathRecipient_setOnUnlinked(recipient, LambdaOnUnlink);
562
563 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(cookie)));
564
565 EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
566
567 foo = nullptr;
568
569 std::unique_lock<std::mutex> lockDeath(deathMutex);
570 EXPECT_TRUE(deathCv.wait_for(lockDeath, 1s, [&] { return deathReceived; }));
571 EXPECT_TRUE(deathReceived);
572
573 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
574 EXPECT_TRUE(deathCv.wait_for(lockUnlink, 1s, [&] { return unlinkReceived; }));
575 EXPECT_TRUE(unlinkReceived);
576 EXPECT_TRUE(wasDeathReceivedFirst);
577
578 AIBinder_DeathRecipient_delete(recipient);
579 AIBinder_decStrong(binder);
580 binder = nullptr;
581 }
582
TEST(NdkBinder,DeathRecipientDropBinderNoDeath)583 TEST(NdkBinder, DeathRecipientDropBinderNoDeath) {
584 using namespace std::chrono_literals;
585
586 std::mutex deathMutex;
587 std::condition_variable deathCv;
588 bool deathReceived = false;
589
590 std::function<void(void)> onDeath = [&] {
591 std::unique_lock<std::mutex> lockDeath(deathMutex);
592 std::cerr << "Binder died (as requested)." << std::endl;
593 deathReceived = true;
594 deathCv.notify_one();
595 };
596
597 std::mutex unlinkMutex;
598 std::condition_variable unlinkCv;
599 bool unlinkReceived = false;
600 bool wasDeathReceivedFirst = false;
601
602 std::function<void(void)> onUnlink = [&] {
603 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
604 std::cerr << "Binder unlinked (as requested)." << std::endl;
605 wasDeathReceivedFirst = deathReceived;
606 unlinkReceived = true;
607 unlinkCv.notify_one();
608 };
609
610 // keep the death recipient around
611 ndk::ScopedAIBinder_DeathRecipient recipient(AIBinder_DeathRecipient_new(LambdaOnDeath));
612 AIBinder_DeathRecipient_setOnUnlinked(recipient.get(), LambdaOnUnlink);
613
614 {
615 AIBinder* binder;
616 sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor2, &binder);
617 ASSERT_NE(nullptr, foo.get());
618 ASSERT_NE(nullptr, binder);
619
620 DeathRecipientCookie* cookie = new DeathRecipientCookie{&onDeath, &onUnlink};
621
622 EXPECT_EQ(STATUS_OK,
623 AIBinder_linkToDeath(binder, recipient.get(), static_cast<void*>(cookie)));
624 // let the sp<IFoo> and AIBinder fall out of scope
625 AIBinder_decStrong(binder);
626 binder = nullptr;
627 }
628
629 {
630 std::unique_lock<std::mutex> lockDeath(deathMutex);
631 EXPECT_FALSE(deathCv.wait_for(lockDeath, 100ms, [&] { return deathReceived; }));
632 EXPECT_FALSE(deathReceived);
633 }
634
635 {
636 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
637 EXPECT_TRUE(deathCv.wait_for(lockUnlink, 1s, [&] { return unlinkReceived; }));
638 EXPECT_TRUE(unlinkReceived);
639 EXPECT_FALSE(wasDeathReceivedFirst);
640 }
641 }
642
TEST(NdkBinder,DeathRecipientDropBinderOnDied)643 TEST(NdkBinder, DeathRecipientDropBinderOnDied) {
644 using namespace std::chrono_literals;
645
646 std::mutex deathMutex;
647 std::condition_variable deathCv;
648 bool deathReceived = false;
649
650 sp<IFoo> foo;
651 AIBinder* binder;
652 std::function<void(void)> onDeath = [&] {
653 std::unique_lock<std::mutex> lockDeath(deathMutex);
654 std::cerr << "Binder died (as requested)." << std::endl;
655 deathReceived = true;
656 AIBinder_decStrong(binder);
657 binder = nullptr;
658 deathCv.notify_one();
659 };
660
661 std::mutex unlinkMutex;
662 std::condition_variable unlinkCv;
663 bool unlinkReceived = false;
664 bool wasDeathReceivedFirst = false;
665
666 std::function<void(void)> onUnlink = [&] {
667 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
668 std::cerr << "Binder unlinked (as requested)." << std::endl;
669 wasDeathReceivedFirst = deathReceived;
670 unlinkReceived = true;
671 unlinkCv.notify_one();
672 };
673
674 ndk::ScopedAIBinder_DeathRecipient recipient(AIBinder_DeathRecipient_new(LambdaOnDeath));
675 AIBinder_DeathRecipient_setOnUnlinked(recipient.get(), LambdaOnUnlink);
676
677 foo = IFoo::getService(IFoo::kInstanceNameToDieFor2, &binder);
678 ASSERT_NE(nullptr, foo.get());
679 ASSERT_NE(nullptr, binder);
680
681 DeathRecipientCookie* cookie = new DeathRecipientCookie{&onDeath, &onUnlink};
682 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient.get(), static_cast<void*>(cookie)));
683
684 EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
685
686 {
687 std::unique_lock<std::mutex> lockDeath(deathMutex);
688 EXPECT_TRUE(deathCv.wait_for(lockDeath, 1s, [&] { return deathReceived; }));
689 EXPECT_TRUE(deathReceived);
690 }
691
692 {
693 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
694 EXPECT_TRUE(deathCv.wait_for(lockUnlink, 100ms, [&] { return unlinkReceived; }));
695 EXPECT_TRUE(unlinkReceived);
696 EXPECT_TRUE(wasDeathReceivedFirst);
697 }
698 }
699
LambdaOnUnlinkMultiple(void * cookie)700 void LambdaOnUnlinkMultiple(void* cookie) {
701 auto funcs = static_cast<DeathRecipientCookie*>(cookie);
702 (*funcs->onUnlink)();
703 };
704
TEST(NdkBinder,DeathRecipientMultipleLinks)705 TEST(NdkBinder, DeathRecipientMultipleLinks) {
706 using namespace std::chrono_literals;
707
708 ndk::SpAIBinder binder;
709 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName, binder.getR());
710 ASSERT_NE(nullptr, foo.get());
711 ASSERT_NE(nullptr, binder);
712
713 std::function<void(void)> onDeath = [&] {};
714
715 std::mutex unlinkMutex;
716 std::condition_variable unlinkCv;
717 bool unlinkReceived = false;
718 constexpr uint32_t kNumberOfLinksToDeath = 4;
719 uint32_t countdown = kNumberOfLinksToDeath;
720
721 std::function<void(void)> onUnlink = [&] {
722 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
723 countdown--;
724 if (countdown == 0) {
725 unlinkReceived = true;
726 unlinkCv.notify_one();
727 }
728 };
729
730 DeathRecipientCookie* cookie = new DeathRecipientCookie{&onDeath, &onUnlink};
731
732 ndk::ScopedAIBinder_DeathRecipient recipient(AIBinder_DeathRecipient_new(LambdaOnDeath));
733 AIBinder_DeathRecipient_setOnUnlinked(recipient.get(), LambdaOnUnlinkMultiple);
734
735 for (int32_t i = 0; i < kNumberOfLinksToDeath; i++) {
736 EXPECT_EQ(STATUS_OK,
737 AIBinder_linkToDeath(binder.get(), recipient.get(), static_cast<void*>(cookie)));
738 }
739
740 foo = nullptr;
741 binder = nullptr;
742
743 std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
744 EXPECT_TRUE(unlinkCv.wait_for(lockUnlink, 5s, [&] { return unlinkReceived; }))
745 << "countdown: " << countdown;
746 EXPECT_TRUE(unlinkReceived);
747 EXPECT_EQ(countdown, 0);
748 }
749
TEST(NdkBinder,RetrieveNonNdkService)750 TEST(NdkBinder, RetrieveNonNdkService) {
751 #pragma clang diagnostic push
752 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
753 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
754 #pragma clang diagnostic pop
755 ASSERT_NE(nullptr, binder);
756 EXPECT_TRUE(AIBinder_isRemote(binder));
757 EXPECT_TRUE(AIBinder_isAlive(binder));
758 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
759
760 AIBinder_decStrong(binder);
761 }
762
OnBinderDeath(void * cookie)763 void OnBinderDeath(void* cookie) {
764 LOG(ERROR) << "BINDER DIED. COOKIE: " << cookie;
765 }
766
TEST(NdkBinder,LinkToDeath)767 TEST(NdkBinder, LinkToDeath) {
768 #pragma clang diagnostic push
769 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
770 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
771 #pragma clang diagnostic pop
772 ASSERT_NE(nullptr, binder);
773
774 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
775 ASSERT_NE(nullptr, recipient);
776
777 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
778 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
779 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
780 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
781 EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
782
783 AIBinder_DeathRecipient_delete(recipient);
784 AIBinder_decStrong(binder);
785 }
786
TEST(NdkBinder,SetInheritRt)787 TEST(NdkBinder, SetInheritRt) {
788 // functional test in binderLibTest
789 sp<IFoo> foo = sp<MyTestFoo>::make();
790 AIBinder* binder = foo->getBinder();
791
792 // does not abort
793 AIBinder_setInheritRt(binder, true);
794 AIBinder_setInheritRt(binder, false);
795 AIBinder_setInheritRt(binder, true);
796
797 AIBinder_decStrong(binder);
798 }
799
TEST(NdkBinder,SetInheritRtNonLocal)800 TEST(NdkBinder, SetInheritRtNonLocal) {
801 #pragma clang diagnostic push
802 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
803 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
804 #pragma clang diagnostic pop
805 ASSERT_NE(binder, nullptr);
806
807 ASSERT_TRUE(AIBinder_isRemote(binder));
808
809 EXPECT_DEATH(AIBinder_setInheritRt(binder, true), "");
810 EXPECT_DEATH(AIBinder_setInheritRt(binder, false), "");
811
812 AIBinder_decStrong(binder);
813 }
814
TEST(NdkBinder,AddNullService)815 TEST(NdkBinder, AddNullService) {
816 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, AServiceManager_addService(nullptr, "any-service-name"));
817 }
818
TEST(NdkBinder,AddInvalidServiceName)819 TEST(NdkBinder, AddInvalidServiceName) {
820 sp<IFoo> foo = new MyTestFoo;
821 EXPECT_EQ(EX_ILLEGAL_ARGUMENT, foo->addService("!@#$%^&"));
822 }
823
TEST(NdkBinder,GetServiceInProcess)824 TEST(NdkBinder, GetServiceInProcess) {
825 static const char* kInstanceName = "test-get-service-in-process";
826
827 sp<IFoo> foo = new MyTestFoo;
828 EXPECT_EQ(EX_NONE, foo->addService(kInstanceName));
829
830 ndk::SpAIBinder binder;
831 sp<IFoo> getFoo = IFoo::getService(kInstanceName, binder.getR());
832 EXPECT_EQ(foo.get(), getFoo.get());
833
834 int32_t out;
835 EXPECT_EQ(STATUS_OK, getFoo->doubleNumber(1, &out));
836 EXPECT_EQ(2, out);
837 }
838
TEST(NdkBinder,EqualityOfRemoteBinderPointer)839 TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
840 #pragma clang diagnostic push
841 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
842 AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
843 ASSERT_NE(nullptr, binderA);
844
845 AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
846 ASSERT_NE(nullptr, binderB);
847 #pragma clang diagnostic pop
848
849 EXPECT_EQ(binderA, binderB);
850
851 AIBinder_decStrong(binderA);
852 AIBinder_decStrong(binderB);
853 }
854
TEST(NdkBinder,ToFromJavaNullptr)855 TEST(NdkBinder, ToFromJavaNullptr) {
856 EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
857 EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
858 }
859
TEST(NdkBinder,ABpBinderRefCount)860 TEST(NdkBinder, ABpBinderRefCount) {
861 #pragma clang diagnostic push
862 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
863 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
864 #pragma clang diagnostic pop
865 AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
866
867 ASSERT_NE(nullptr, binder);
868 EXPECT_EQ(1, AIBinder_debugGetRefCount(binder));
869
870 AIBinder_decStrong(binder);
871
872 ASSERT_EQ(nullptr, AIBinder_Weak_promote(wBinder));
873
874 AIBinder_Weak_delete(wBinder);
875 }
876
TEST(NdkBinder,AddServiceMultipleTimes)877 TEST(NdkBinder, AddServiceMultipleTimes) {
878 static const char* kInstanceName1 = "test-multi-1";
879 static const char* kInstanceName2 = "test-multi-2";
880 sp<IFoo> foo = new MyTestFoo;
881 EXPECT_EQ(EX_NONE, foo->addService(kInstanceName1));
882 EXPECT_EQ(EX_NONE, foo->addService(kInstanceName2));
883 EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
884 }
885
TEST(NdkBinder,RequestedSidWorks)886 TEST(NdkBinder, RequestedSidWorks) {
887 #pragma clang diagnostic push
888 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
889 ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
890 #pragma clang diagnostic pop
891 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
892 aidl::IBinderNdkUnitTest::fromBinder(binder);
893
894 bool gotSid = false;
895 EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk());
896 EXPECT_TRUE(gotSid);
897 }
898
TEST(NdkBinder,SentAidlBinderCanBeDestroyed)899 TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
900 static volatile bool destroyed = false;
901 static std::mutex dMutex;
902 static std::condition_variable cv;
903
904 class MyEmpty : public aidl::BnEmpty {
905 virtual ~MyEmpty() {
906 destroyed = true;
907 cv.notify_one();
908 }
909 };
910
911 std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
912
913 #pragma clang diagnostic push
914 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
915 ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
916 #pragma clang diagnostic pop
917 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
918 aidl::IBinderNdkUnitTest::fromBinder(binder);
919
920 EXPECT_FALSE(destroyed);
921
922 service->takeInterface(empty);
923 service->forceFlushCommands();
924 empty = nullptr;
925
926 // give other binder thread time to process commands
927 {
928 using namespace std::chrono_literals;
929 std::unique_lock<std::mutex> lk(dMutex);
930 cv.wait_for(lk, 1s, [] { return destroyed; });
931 }
932
933 EXPECT_TRUE(destroyed);
934 }
935
TEST(NdkBinder,ConvertToPlatformBinder)936 TEST(NdkBinder, ConvertToPlatformBinder) {
937 for (const ndk::SpAIBinder& binder :
938 {// remote
939 #pragma clang diagnostic push
940 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
941 ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
942 #pragma clang diagnostic pop
943 // local
944 ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
945 // convert to platform binder
946 EXPECT_NE(binder, nullptr);
947 sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
948 EXPECT_NE(platformBinder, nullptr);
949 auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
950 EXPECT_NE(proxy, nullptr);
951
952 // use platform binder
953 int out;
954 EXPECT_TRUE(proxy->repeatInt(4, &out).isOk());
955 EXPECT_EQ(out, 4);
956
957 // convert back
958 ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
959 EXPECT_EQ(backBinder, binder);
960 }
961 }
962
TEST(NdkBinder,ConvertToPlatformParcel)963 TEST(NdkBinder, ConvertToPlatformParcel) {
964 ndk::ScopedAParcel parcel = ndk::ScopedAParcel(AParcel_create());
965 EXPECT_EQ(OK, AParcel_writeInt32(parcel.get(), 42));
966
967 android::Parcel* pparcel = AParcel_viewPlatformParcel(parcel.get());
968 pparcel->setDataPosition(0);
969 EXPECT_EQ(42, pparcel->readInt32());
970 }
971
TEST(NdkBinder,GetAndVerifyScopedAIBinder_Weak)972 TEST(NdkBinder, GetAndVerifyScopedAIBinder_Weak) {
973 for (const ndk::SpAIBinder& binder :
974 {// remote
975 #pragma clang diagnostic push
976 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
977 ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
978 #pragma clang diagnostic pop
979 // local
980 ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
981 // get a const ScopedAIBinder_Weak and verify promote
982 EXPECT_NE(binder.get(), nullptr);
983 const ndk::ScopedAIBinder_Weak wkAIBinder =
984 ndk::ScopedAIBinder_Weak(AIBinder_Weak_new(binder.get()));
985 EXPECT_EQ(wkAIBinder.promote().get(), binder.get());
986 // get another ScopedAIBinder_Weak and verify
987 ndk::ScopedAIBinder_Weak wkAIBinder2 =
988 ndk::ScopedAIBinder_Weak(AIBinder_Weak_new(binder.get()));
989 EXPECT_FALSE(AIBinder_Weak_lt(wkAIBinder.get(), wkAIBinder2.get()));
990 EXPECT_FALSE(AIBinder_Weak_lt(wkAIBinder2.get(), wkAIBinder.get()));
991 EXPECT_EQ(wkAIBinder2.promote(), wkAIBinder.promote());
992 }
993 }
994
995 class MyResultReceiver : public BnResultReceiver {
996 public:
997 Mutex mMutex;
998 Condition mCondition;
999 bool mHaveResult = false;
1000 int32_t mResult = 0;
1001
send(int32_t resultCode)1002 virtual void send(int32_t resultCode) {
1003 AutoMutex _l(mMutex);
1004 mResult = resultCode;
1005 mHaveResult = true;
1006 mCondition.signal();
1007 }
1008
waitForResult()1009 int32_t waitForResult() {
1010 AutoMutex _l(mMutex);
1011 while (!mHaveResult) {
1012 mCondition.wait(mMutex);
1013 }
1014 return mResult;
1015 }
1016 };
1017
1018 class MyShellCallback : public BnShellCallback {
1019 public:
openFile(const String16 &,const String16 &,const String16 &)1020 virtual int openFile(const String16& /*path*/, const String16& /*seLinuxContext*/,
1021 const String16& /*mode*/) {
1022 // Empty implementation.
1023 return 0;
1024 }
1025 };
1026
ReadFdToString(int fd,std::string * content)1027 bool ReadFdToString(int fd, std::string* content) {
1028 char buf[64];
1029 ssize_t n;
1030 while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
1031 content->append(buf, n);
1032 }
1033 return (n == 0) ? true : false;
1034 }
1035
shellCmdToString(sp<IBinder> unitTestService,const std::vector<const char * > & args)1036 std::string shellCmdToString(sp<IBinder> unitTestService, const std::vector<const char*>& args) {
1037 int inFd[2] = {-1, -1};
1038 int outFd[2] = {-1, -1};
1039 int errFd[2] = {-1, -1};
1040
1041 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, inFd));
1042 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, outFd));
1043 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, errFd));
1044
1045 sp<MyShellCallback> cb = new MyShellCallback();
1046 sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
1047
1048 Vector<String16> argsVec;
1049 for (int i = 0; i < args.size(); i++) {
1050 argsVec.add(String16(args[i]));
1051 }
1052 status_t error = IBinder::shellCommand(unitTestService, inFd[0], outFd[0], errFd[0], argsVec,
1053 cb, resultReceiver);
1054 EXPECT_EQ(error, android::OK);
1055
1056 status_t res = resultReceiver->waitForResult();
1057 EXPECT_EQ(res, android::OK);
1058
1059 close(inFd[0]);
1060 close(inFd[1]);
1061 close(outFd[0]);
1062 close(errFd[0]);
1063 close(errFd[1]);
1064
1065 std::string ret;
1066 EXPECT_TRUE(ReadFdToString(outFd[1], &ret));
1067 close(outFd[1]);
1068 return ret;
1069 }
1070
TEST(NdkBinder,UseHandleShellCommand)1071 TEST(NdkBinder, UseHandleShellCommand) {
1072 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
1073 #pragma clang diagnostic push
1074 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1075 sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
1076 #pragma clang diagnostic pop
1077
1078 EXPECT_EQ("", shellCmdToString(testService, {}));
1079 EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
1080 EXPECT_EQ("Hello world!", shellCmdToString(testService, {"Hello ", "world!"}));
1081 EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
1082 }
1083
TEST(NdkBinder,FlaggedServiceAccessible)1084 TEST(NdkBinder, FlaggedServiceAccessible) {
1085 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
1086 #pragma clang diagnostic push
1087 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
1088 sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestServiceFlagged));
1089 #pragma clang diagnostic pop
1090 ASSERT_NE(nullptr, testService);
1091 }
1092
TEST(NdkBinder,GetClassInterfaceDescriptor)1093 TEST(NdkBinder, GetClassInterfaceDescriptor) {
1094 ASSERT_STREQ(IFoo::kIFooDescriptor, AIBinder_Class_getDescriptor(IFoo::kClass));
1095 }
1096
addOne(int * to)1097 static void addOne(int* to) {
1098 if (!to) return;
1099 ++(*to);
1100 }
1101 struct FakeResource : public ndk::impl::ScopedAResource<int*, addOne, nullptr> {
FakeResourceFakeResource1102 explicit FakeResource(int* a) : ScopedAResource(a) {}
1103 };
1104
TEST(NdkBinder_ScopedAResource,GetDelete)1105 TEST(NdkBinder_ScopedAResource, GetDelete) {
1106 int deleteCount = 0;
1107 { FakeResource resource(&deleteCount); }
1108 EXPECT_EQ(deleteCount, 1);
1109 }
1110
TEST(NdkBinder_ScopedAResource,Release)1111 TEST(NdkBinder_ScopedAResource, Release) {
1112 int deleteCount = 0;
1113 {
1114 FakeResource resource(&deleteCount);
1115 (void)resource.release();
1116 }
1117 EXPECT_EQ(deleteCount, 0);
1118 }
1119
main(int argc,char * argv[])1120 int main(int argc, char* argv[]) {
1121 ::testing::InitGoogleTest(&argc, argv);
1122
1123 if (fork() == 0) {
1124 prctl(PR_SET_PDEATHSIG, SIGHUP);
1125 return manualThreadPoolService(IFoo::kInstanceNameToDieFor);
1126 }
1127 if (fork() == 0) {
1128 prctl(PR_SET_PDEATHSIG, SIGHUP);
1129 return manualThreadPoolService(IFoo::kInstanceNameToDieFor2);
1130 }
1131 if (fork() == 0) {
1132 prctl(PR_SET_PDEATHSIG, SIGHUP);
1133 return manualPollingService(IFoo::kSomeInstanceName);
1134 }
1135 if (fork() == 0) {
1136 prctl(PR_SET_PDEATHSIG, SIGHUP);
1137 return lazyService(kLazyBinderNdkUnitTestService);
1138 }
1139 if (fork() == 0) {
1140 prctl(PR_SET_PDEATHSIG, SIGHUP);
1141 return lazyService(kForcePersistNdkUnitTestService);
1142 }
1143 if (fork() == 0) {
1144 prctl(PR_SET_PDEATHSIG, SIGHUP);
1145 return lazyService(kActiveServicesNdkUnitTestService);
1146 }
1147 if (fork() == 0) {
1148 prctl(PR_SET_PDEATHSIG, SIGHUP);
1149 return generatedService();
1150 }
1151 if (fork() == 0) {
1152 prctl(PR_SET_PDEATHSIG, SIGHUP);
1153 // We may want to change this flag to be more generic ones for the future
1154 AServiceManager_AddServiceFlag test_flags =
1155 AServiceManager_AddServiceFlag::ADD_SERVICE_ALLOW_ISOLATED;
1156 return generatedFlaggedService(test_flags, kBinderNdkUnitTestServiceFlagged);
1157 }
1158
1159 ABinderProcess_setThreadPoolMaxThreadCount(0);
1160 ABinderProcess_startThreadPool();
1161
1162 return RUN_ALL_TESTS();
1163 }
1164
1165 #include <android/binder_auto_utils.h>
1166 #include <android/binder_interface_utils.h>
1167 #include <android/binder_parcel_utils.h>
1168