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