• 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 <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