• 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 
37 #include <sys/prctl.h>
38 #include <chrono>
39 #include <condition_variable>
40 #include <iostream>
41 #include <mutex>
42 #include "android/binder_ibinder.h"
43 
44 using namespace android;
45 
46 constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
47 constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
48 constexpr char kLazyBinderNdkUnitTestService[] = "LazyBinderNdkUnitTest";
49 constexpr char kForcePersistNdkUnitTestService[] = "ForcePersistNdkUnitTestService";
50 constexpr char kActiveServicesNdkUnitTestService[] = "ActiveServicesNdkUnitTestService";
51 
52 constexpr unsigned int kShutdownWaitTime = 10;
53 constexpr uint64_t kContextTestValue = 0xb4e42fb4d9a1d715;
54 
55 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
repeatInt(int32_t in,int32_t * out)56     ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
57         *out = in;
58         return ndk::ScopedAStatus::ok();
59     }
takeInterface(const std::shared_ptr<aidl::IEmpty> & empty)60     ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
61         (void)empty;
62         return ndk::ScopedAStatus::ok();
63     }
forceFlushCommands()64     ndk::ScopedAStatus forceFlushCommands() {
65         // warning: this is assuming that libbinder_ndk is using the same copy
66         // of libbinder that we are.
67         android::IPCThreadState::self()->flushCommands();
68         return ndk::ScopedAStatus::ok();
69     }
getsRequestedSid(bool * out)70     ndk::ScopedAStatus getsRequestedSid(bool* out) {
71         const char* sid = AIBinder_getCallingSid();
72         std::cout << "Got security context: " << (sid ?: "null") << std::endl;
73         *out = sid != nullptr;
74         return ndk::ScopedAStatus::ok();
75     }
handleShellCommand(int,int out,int,const char ** args,uint32_t numArgs)76     binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
77                                        uint32_t numArgs) override {
78         for (uint32_t i = 0; i < numArgs; i++) {
79             dprintf(out, "%s", args[i]);
80         }
81         fsync(out);
82         return STATUS_OK;
83     }
forcePersist(bool persist)84     ndk::ScopedAStatus forcePersist(bool persist) {
85         AServiceManager_forceLazyServicesPersist(persist);
86         return ndk::ScopedAStatus::ok();
87     }
setCustomActiveServicesCallback()88     ndk::ScopedAStatus setCustomActiveServicesCallback() {
89         AServiceManager_setActiveServicesCallback(activeServicesCallback, this);
90         return ndk::ScopedAStatus::ok();
91     }
activeServicesCallback(bool hasClients,void * context)92     static bool activeServicesCallback(bool hasClients, void* context) {
93         if (hasClients) {
94             return false;
95         }
96 
97         // Unregister all services
98         if (!AServiceManager_tryUnregister()) {
99             // Prevent shutdown (test will fail)
100             return false;
101         }
102 
103         // Re-register all services
104         AServiceManager_reRegister();
105 
106         // Unregister again before shutdown
107         if (!AServiceManager_tryUnregister()) {
108             // Prevent shutdown (test will fail)
109             return false;
110         }
111 
112         // Check if the context was passed correctly
113         MyBinderNdkUnitTest* service = static_cast<MyBinderNdkUnitTest*>(context);
114         if (service->contextTestValue != kContextTestValue) {
115             // Prevent shutdown (test will fail)
116             return false;
117         }
118 
119         exit(EXIT_SUCCESS);
120         // Unreachable
121     }
122 
123     uint64_t contextTestValue = kContextTestValue;
124 };
125 
generatedService()126 int generatedService() {
127     ABinderProcess_setThreadPoolMaxThreadCount(0);
128 
129     auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
130     auto binder = service->asBinder();
131 
132     AIBinder_setRequestingSid(binder.get(), true);
133 
134     binder_exception_t exception =
135             AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
136 
137     if (exception != EX_NONE) {
138         LOG(FATAL) << "Could not register: " << exception << " " << kBinderNdkUnitTestService;
139     }
140 
141     ABinderProcess_joinThreadPool();
142 
143     return 1;  // should not return
144 }
145 
146 // manually-written parceling class considered bad practice
147 class MyFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)148     binder_status_t doubleNumber(int32_t in, int32_t* out) override {
149         *out = 2 * in;
150         LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
151         return STATUS_OK;
152     }
153 
die()154     binder_status_t die() override {
155         LOG(FATAL) << "IFoo::die called!";
156         return STATUS_UNKNOWN_ERROR;
157     }
158 };
159 
manualService(const char * instance)160 void manualService(const char* instance) {
161     // Strong reference to MyFoo kept by service manager.
162     binder_exception_t exception = (new MyFoo)->addService(instance);
163 
164     if (exception != EX_NONE) {
165         LOG(FATAL) << "Could not register: " << exception << " " << instance;
166     }
167 }
manualPollingService(const char * instance)168 int manualPollingService(const char* instance) {
169     int fd;
170     CHECK(STATUS_OK == ABinderProcess_setupPolling(&fd));
171     manualService(instance);
172 
173     class Handler : public LooperCallback {
174         int handleEvent(int /*fd*/, int /*events*/, void* /*data*/) override {
175             ABinderProcess_handlePolledCommands();
176             return 1;  // Continue receiving callbacks.
177         }
178     };
179 
180     sp<Looper> looper = Looper::prepare(0 /* opts */);
181     looper->addFd(fd, Looper::POLL_CALLBACK, Looper::EVENT_INPUT, new Handler(), nullptr /*data*/);
182     // normally, would add additional fds
183     while (true) {
184         looper->pollAll(-1 /* timeoutMillis */);
185     }
186     return 1;  // should not reach
187 }
manualThreadPoolService(const char * instance)188 int manualThreadPoolService(const char* instance) {
189     ABinderProcess_setThreadPoolMaxThreadCount(0);
190     manualService(instance);
191     ABinderProcess_joinThreadPool();
192     return 1;
193 }
194 
lazyService(const char * instance)195 int lazyService(const char* instance) {
196     ABinderProcess_setThreadPoolMaxThreadCount(0);
197     // Wait to register this service to make sure the main test process will
198     // actually wait for the service to be available. Tested with sleep(60),
199     // and reduced for sake of time.
200     sleep(1);
201     // Strong reference to MyBinderNdkUnitTest kept by service manager.
202     // This is just for testing, it has no corresponding init behavior.
203     auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
204     auto binder = service->asBinder();
205 
206     binder_status_t status = AServiceManager_registerLazyService(binder.get(), instance);
207     if (status != STATUS_OK) {
208         LOG(FATAL) << "Could not register: " << status << " " << instance;
209     }
210 
211     ABinderProcess_joinThreadPool();
212 
213     return 1;  // should not return
214 }
215 
isServiceRunning(const char * serviceName)216 bool isServiceRunning(const char* serviceName) {
217     AIBinder* binder = AServiceManager_checkService(serviceName);
218     if (binder == nullptr) {
219         return false;
220     }
221     AIBinder_decStrong(binder);
222 
223     return true;
224 }
225 
TEST(NdkBinder,GetServiceThatDoesntExist)226 TEST(NdkBinder, GetServiceThatDoesntExist) {
227     sp<IFoo> foo = IFoo::getService("asdfghkl;");
228     EXPECT_EQ(nullptr, foo.get());
229 }
230 
TEST(NdkBinder,CheckServiceThatDoesntExist)231 TEST(NdkBinder, CheckServiceThatDoesntExist) {
232     AIBinder* binder = AServiceManager_checkService("asdfghkl;");
233     ASSERT_EQ(nullptr, binder);
234 }
235 
TEST(NdkBinder,CheckServiceThatDoesExist)236 TEST(NdkBinder, CheckServiceThatDoesExist) {
237     AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
238     EXPECT_NE(nullptr, binder);
239     EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
240 
241     AIBinder_decStrong(binder);
242 }
243 
TEST(NdkBinder,UnimplementedDump)244 TEST(NdkBinder, UnimplementedDump) {
245     sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
246     ASSERT_NE(foo, nullptr);
247     AIBinder* binder = foo->getBinder();
248     EXPECT_EQ(OK, AIBinder_dump(binder, STDOUT_FILENO, nullptr, 0));
249     AIBinder_decStrong(binder);
250 }
251 
TEST(NdkBinder,UnimplementedShell)252 TEST(NdkBinder, UnimplementedShell) {
253     // libbinder_ndk doesn't support calling shell, so we are calling from the
254     // libbinder across processes to the NDK service which doesn't implement
255     // shell
256     static const sp<android::IServiceManager> sm(android::defaultServiceManager());
257     sp<IBinder> testService = sm->getService(String16(IFoo::kSomeInstanceName));
258 
259     Vector<String16> argsVec;
260     EXPECT_EQ(OK, IBinder::shellCommand(testService, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO,
261                                         argsVec, nullptr, nullptr));
262 }
263 
TEST(NdkBinder,DoubleNumber)264 TEST(NdkBinder, DoubleNumber) {
265     sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
266     ASSERT_NE(foo, nullptr);
267 
268     int32_t out;
269     EXPECT_EQ(STATUS_OK, foo->doubleNumber(1, &out));
270     EXPECT_EQ(2, out);
271 }
272 
defaultInstanceCounter(const char * instance,void * context)273 void defaultInstanceCounter(const char* instance, void* context) {
274     if (strcmp(instance, "default") == 0) {
275         ++*(size_t*)(context);
276     }
277 }
278 
TEST(NdkBinder,GetDeclaredInstances)279 TEST(NdkBinder, GetDeclaredInstances) {
280     bool hasLight = AServiceManager_isDeclared("android.hardware.light.ILights/default");
281 
282     size_t count;
283     AServiceManager_forEachDeclaredInstance("android.hardware.light.ILights", &count,
284                                             defaultInstanceCounter);
285 
286     // At the time of writing this test, there is no good interface guaranteed
287     // to be on all devices. Cuttlefish has light, so this will generally test
288     // things.
289     EXPECT_EQ(count, hasLight ? 1 : 0);
290 }
291 
TEST(NdkBinder,GetLazyService)292 TEST(NdkBinder, GetLazyService) {
293     // Not declared in the vintf manifest
294     ASSERT_FALSE(AServiceManager_isDeclared(kLazyBinderNdkUnitTestService));
295     ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
296     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
297             aidl::IBinderNdkUnitTest::fromBinder(binder);
298     ASSERT_NE(service, nullptr);
299 
300     EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
301 }
302 
TEST(NdkBinder,IsUpdatable)303 TEST(NdkBinder, IsUpdatable) {
304     bool isUpdatable = AServiceManager_isUpdatableViaApex("android.hardware.light.ILights/default");
305     EXPECT_EQ(isUpdatable, false);
306 }
307 
308 // This is too slow
TEST(NdkBinder,CheckLazyServiceShutDown)309 TEST(NdkBinder, CheckLazyServiceShutDown) {
310     ndk::SpAIBinder binder(AServiceManager_waitForService(kLazyBinderNdkUnitTestService));
311     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
312             aidl::IBinderNdkUnitTest::fromBinder(binder);
313     ASSERT_NE(service, nullptr);
314 
315     EXPECT_EQ(STATUS_OK, AIBinder_ping(binder.get()));
316     binder = nullptr;
317     service = nullptr;
318     IPCThreadState::self()->flushCommands();
319     // Make sure the service is dead after some time of no use
320     sleep(kShutdownWaitTime);
321     ASSERT_EQ(nullptr, AServiceManager_checkService(kLazyBinderNdkUnitTestService));
322 }
323 
TEST(NdkBinder,ForcedPersistenceTest)324 TEST(NdkBinder, ForcedPersistenceTest) {
325     for (int i = 0; i < 2; i++) {
326         ndk::SpAIBinder binder(AServiceManager_waitForService(kForcePersistNdkUnitTestService));
327         std::shared_ptr<aidl::IBinderNdkUnitTest> service =
328                 aidl::IBinderNdkUnitTest::fromBinder(binder);
329         ASSERT_NE(service, nullptr);
330         ASSERT_TRUE(service->forcePersist(i == 0).isOk());
331 
332         binder = nullptr;
333         service = nullptr;
334         IPCThreadState::self()->flushCommands();
335 
336         sleep(kShutdownWaitTime);
337 
338         bool isRunning = isServiceRunning(kForcePersistNdkUnitTestService);
339 
340         if (i == 0) {
341             ASSERT_TRUE(isRunning) << "Service shut down when it shouldn't have.";
342         } else {
343             ASSERT_FALSE(isRunning) << "Service failed to shut down.";
344         }
345     }
346 }
347 
TEST(NdkBinder,ActiveServicesCallbackTest)348 TEST(NdkBinder, ActiveServicesCallbackTest) {
349     ndk::SpAIBinder binder(AServiceManager_waitForService(kActiveServicesNdkUnitTestService));
350     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
351             aidl::IBinderNdkUnitTest::fromBinder(binder);
352     ASSERT_NE(service, nullptr);
353     ASSERT_TRUE(service->setCustomActiveServicesCallback().isOk());
354 
355     binder = nullptr;
356     service = nullptr;
357     IPCThreadState::self()->flushCommands();
358 
359     sleep(kShutdownWaitTime);
360 
361     ASSERT_FALSE(isServiceRunning(kActiveServicesNdkUnitTestService))
362             << "Service failed to shut down.";
363 }
364 
LambdaOnDeath(void * cookie)365 void LambdaOnDeath(void* cookie) {
366     auto onDeath = static_cast<std::function<void(void)>*>(cookie);
367     (*onDeath)();
368 };
TEST(NdkBinder,DeathRecipient)369 TEST(NdkBinder, DeathRecipient) {
370     using namespace std::chrono_literals;
371 
372     AIBinder* binder;
373     sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor, &binder);
374     ASSERT_NE(nullptr, foo.get());
375     ASSERT_NE(nullptr, binder);
376 
377     std::mutex deathMutex;
378     std::condition_variable deathCv;
379     bool deathRecieved = false;
380 
381     std::function<void(void)> onDeath = [&] {
382         std::cerr << "Binder died (as requested)." << std::endl;
383         deathRecieved = true;
384         deathCv.notify_one();
385     };
386 
387     AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
388 
389     EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&onDeath)));
390 
391     // the binder driver should return this if the service dies during the transaction
392     EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
393 
394     foo = nullptr;
395 
396     std::unique_lock<std::mutex> lock(deathMutex);
397     EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; }));
398     EXPECT_TRUE(deathRecieved);
399 
400     AIBinder_DeathRecipient_delete(recipient);
401     AIBinder_decStrong(binder);
402     binder = nullptr;
403 }
404 
TEST(NdkBinder,RetrieveNonNdkService)405 TEST(NdkBinder, RetrieveNonNdkService) {
406     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
407     ASSERT_NE(nullptr, binder);
408     EXPECT_TRUE(AIBinder_isRemote(binder));
409     EXPECT_TRUE(AIBinder_isAlive(binder));
410     EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
411 
412     AIBinder_decStrong(binder);
413 }
414 
OnBinderDeath(void * cookie)415 void OnBinderDeath(void* cookie) {
416     LOG(ERROR) << "BINDER DIED. COOKIE: " << cookie;
417 }
418 
TEST(NdkBinder,LinkToDeath)419 TEST(NdkBinder, LinkToDeath) {
420     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
421     ASSERT_NE(nullptr, binder);
422 
423     AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
424     ASSERT_NE(nullptr, recipient);
425 
426     EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
427     EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
428     EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
429     EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
430     EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
431 
432     AIBinder_DeathRecipient_delete(recipient);
433     AIBinder_decStrong(binder);
434 }
435 
436 class MyTestFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)437     binder_status_t doubleNumber(int32_t in, int32_t* out) override {
438         *out = 2 * in;
439         LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
440         return STATUS_OK;
441     }
die()442     binder_status_t die() override {
443         ADD_FAILURE() << "die called on local instance";
444         return STATUS_OK;
445     }
446 };
447 
TEST(NdkBinder,AddNullService)448 TEST(NdkBinder, AddNullService) {
449     EXPECT_EQ(EX_ILLEGAL_ARGUMENT, AServiceManager_addService(nullptr, "any-service-name"));
450 }
451 
TEST(NdkBinder,AddInvalidServiceName)452 TEST(NdkBinder, AddInvalidServiceName) {
453     sp<IFoo> foo = new MyTestFoo;
454     EXPECT_EQ(EX_ILLEGAL_ARGUMENT, foo->addService("!@#$%^&"));
455 }
456 
TEST(NdkBinder,GetServiceInProcess)457 TEST(NdkBinder, GetServiceInProcess) {
458     static const char* kInstanceName = "test-get-service-in-process";
459 
460     sp<IFoo> foo = new MyTestFoo;
461     EXPECT_EQ(EX_NONE, foo->addService(kInstanceName));
462 
463     sp<IFoo> getFoo = IFoo::getService(kInstanceName);
464     EXPECT_EQ(foo.get(), getFoo.get());
465 
466     int32_t out;
467     EXPECT_EQ(STATUS_OK, getFoo->doubleNumber(1, &out));
468     EXPECT_EQ(2, out);
469 }
470 
TEST(NdkBinder,EqualityOfRemoteBinderPointer)471 TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
472     AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
473     ASSERT_NE(nullptr, binderA);
474 
475     AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
476     ASSERT_NE(nullptr, binderB);
477 
478     EXPECT_EQ(binderA, binderB);
479 
480     AIBinder_decStrong(binderA);
481     AIBinder_decStrong(binderB);
482 }
483 
TEST(NdkBinder,ToFromJavaNullptr)484 TEST(NdkBinder, ToFromJavaNullptr) {
485     EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
486     EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
487 }
488 
TEST(NdkBinder,ABpBinderRefCount)489 TEST(NdkBinder, ABpBinderRefCount) {
490     AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
491     AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
492 
493     ASSERT_NE(nullptr, binder);
494     EXPECT_EQ(1, AIBinder_debugGetRefCount(binder));
495 
496     AIBinder_decStrong(binder);
497 
498     ASSERT_EQ(nullptr, AIBinder_Weak_promote(wBinder));
499 
500     AIBinder_Weak_delete(wBinder);
501 }
502 
TEST(NdkBinder,AddServiceMultipleTimes)503 TEST(NdkBinder, AddServiceMultipleTimes) {
504     static const char* kInstanceName1 = "test-multi-1";
505     static const char* kInstanceName2 = "test-multi-2";
506     sp<IFoo> foo = new MyTestFoo;
507     EXPECT_EQ(EX_NONE, foo->addService(kInstanceName1));
508     EXPECT_EQ(EX_NONE, foo->addService(kInstanceName2));
509     EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
510 }
511 
TEST(NdkBinder,RequestedSidWorks)512 TEST(NdkBinder, RequestedSidWorks) {
513     ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
514     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
515             aidl::IBinderNdkUnitTest::fromBinder(binder);
516 
517     bool gotSid = false;
518     EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk());
519     EXPECT_TRUE(gotSid);
520 }
521 
TEST(NdkBinder,SentAidlBinderCanBeDestroyed)522 TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
523     static volatile bool destroyed = false;
524     static std::mutex dMutex;
525     static std::condition_variable cv;
526 
527     class MyEmpty : public aidl::BnEmpty {
528         virtual ~MyEmpty() {
529             destroyed = true;
530             cv.notify_one();
531         }
532     };
533 
534     std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
535 
536     ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
537     std::shared_ptr<aidl::IBinderNdkUnitTest> service =
538             aidl::IBinderNdkUnitTest::fromBinder(binder);
539 
540     EXPECT_FALSE(destroyed);
541 
542     service->takeInterface(empty);
543     service->forceFlushCommands();
544     empty = nullptr;
545 
546     // give other binder thread time to process commands
547     {
548         using namespace std::chrono_literals;
549         std::unique_lock<std::mutex> lk(dMutex);
550         cv.wait_for(lk, 1s, [] { return destroyed; });
551     }
552 
553     EXPECT_TRUE(destroyed);
554 }
555 
TEST(NdkBinder,ConvertToPlatformBinder)556 TEST(NdkBinder, ConvertToPlatformBinder) {
557     for (const ndk::SpAIBinder& binder :
558          {// remote
559           ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
560           // local
561           ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
562         // convert to platform binder
563         EXPECT_NE(binder.get(), nullptr);
564         sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
565         EXPECT_NE(platformBinder.get(), nullptr);
566         auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
567         EXPECT_NE(proxy, nullptr);
568 
569         // use platform binder
570         int out;
571         EXPECT_TRUE(proxy->repeatInt(4, &out).isOk());
572         EXPECT_EQ(out, 4);
573 
574         // convert back
575         ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
576         EXPECT_EQ(backBinder.get(), binder.get());
577     }
578 }
579 
580 class MyResultReceiver : public BnResultReceiver {
581    public:
582     Mutex mMutex;
583     Condition mCondition;
584     bool mHaveResult = false;
585     int32_t mResult = 0;
586 
send(int32_t resultCode)587     virtual void send(int32_t resultCode) {
588         AutoMutex _l(mMutex);
589         mResult = resultCode;
590         mHaveResult = true;
591         mCondition.signal();
592     }
593 
waitForResult()594     int32_t waitForResult() {
595         AutoMutex _l(mMutex);
596         while (!mHaveResult) {
597             mCondition.wait(mMutex);
598         }
599         return mResult;
600     }
601 };
602 
603 class MyShellCallback : public BnShellCallback {
604    public:
openFile(const String16 &,const String16 &,const String16 &)605     virtual int openFile(const String16& /*path*/, const String16& /*seLinuxContext*/,
606                          const String16& /*mode*/) {
607         // Empty implementation.
608         return 0;
609     }
610 };
611 
ReadFdToString(int fd,std::string * content)612 bool ReadFdToString(int fd, std::string* content) {
613     char buf[64];
614     ssize_t n;
615     while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
616         content->append(buf, n);
617     }
618     return (n == 0) ? true : false;
619 }
620 
shellCmdToString(sp<IBinder> unitTestService,const std::vector<const char * > & args)621 std::string shellCmdToString(sp<IBinder> unitTestService, const std::vector<const char*>& args) {
622     int inFd[2] = {-1, -1};
623     int outFd[2] = {-1, -1};
624     int errFd[2] = {-1, -1};
625 
626     EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, inFd));
627     EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, outFd));
628     EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, errFd));
629 
630     sp<MyShellCallback> cb = new MyShellCallback();
631     sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
632 
633     Vector<String16> argsVec;
634     for (int i = 0; i < args.size(); i++) {
635         argsVec.add(String16(args[i]));
636     }
637     status_t error = IBinder::shellCommand(unitTestService, inFd[0], outFd[0], errFd[0], argsVec,
638                                            cb, resultReceiver);
639     EXPECT_EQ(error, android::OK);
640 
641     status_t res = resultReceiver->waitForResult();
642     EXPECT_EQ(res, android::OK);
643 
644     close(inFd[0]);
645     close(inFd[1]);
646     close(outFd[0]);
647     close(errFd[0]);
648     close(errFd[1]);
649 
650     std::string ret;
651     EXPECT_TRUE(ReadFdToString(outFd[1], &ret));
652     close(outFd[1]);
653     return ret;
654 }
655 
TEST(NdkBinder,UseHandleShellCommand)656 TEST(NdkBinder, UseHandleShellCommand) {
657     static const sp<android::IServiceManager> sm(android::defaultServiceManager());
658     sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
659 
660     EXPECT_EQ("", shellCmdToString(testService, {}));
661     EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
662     EXPECT_EQ("Hello world!", shellCmdToString(testService, {"Hello ", "world!"}));
663     EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
664 }
665 
TEST(NdkBinder,GetClassInterfaceDescriptor)666 TEST(NdkBinder, GetClassInterfaceDescriptor) {
667     ASSERT_STREQ(IFoo::kIFooDescriptor, AIBinder_Class_getDescriptor(IFoo::kClass));
668 }
669 
main(int argc,char * argv[])670 int main(int argc, char* argv[]) {
671     ::testing::InitGoogleTest(&argc, argv);
672 
673     if (fork() == 0) {
674         prctl(PR_SET_PDEATHSIG, SIGHUP);
675         return manualThreadPoolService(IFoo::kInstanceNameToDieFor);
676     }
677     if (fork() == 0) {
678         prctl(PR_SET_PDEATHSIG, SIGHUP);
679         return manualPollingService(IFoo::kSomeInstanceName);
680     }
681     if (fork() == 0) {
682         prctl(PR_SET_PDEATHSIG, SIGHUP);
683         return lazyService(kLazyBinderNdkUnitTestService);
684     }
685     if (fork() == 0) {
686         prctl(PR_SET_PDEATHSIG, SIGHUP);
687         return lazyService(kForcePersistNdkUnitTestService);
688     }
689     if (fork() == 0) {
690         prctl(PR_SET_PDEATHSIG, SIGHUP);
691         return lazyService(kActiveServicesNdkUnitTestService);
692     }
693     if (fork() == 0) {
694         prctl(PR_SET_PDEATHSIG, SIGHUP);
695         return generatedService();
696     }
697 
698     ABinderProcess_setThreadPoolMaxThreadCount(1);  // to receive death notifications/callbacks
699     ABinderProcess_startThreadPool();
700 
701     return RUN_ALL_TESTS();
702 }
703 
704 #include <android/binder_auto_utils.h>
705 #include <android/binder_interface_utils.h>
706 #include <android/binder_parcel_utils.h>
707