• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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