blob: e3fdb4bab3affbf1d2a402653cacc0da9815b227 [file] [log] [blame]
Steven Moreland2e87adc2018-08-20 19:47:00 -07001/*
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
Ruchir Rastogicc7a7462020-01-31 14:29:15 -080017#include <IBinderNdkUnitTest.h>
Steven Moreland169bb8f2020-01-29 10:21:35 -080018#include <aidl/BnBinderNdkUnitTest.h>
19#include <aidl/BnEmpty.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070020#include <android-base/logging.h>
Steven Moreland02f75652018-09-18 14:08:30 -070021#include <android/binder_ibinder_jni.h>
Steven Moreland2f405f52020-07-08 22:24:29 +000022#include <android/binder_ibinder_platform.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070023#include <android/binder_manager.h>
Steven Moreland901c7452018-09-04 16:17:28 -070024#include <android/binder_process.h>
Steven Moreland2e87adc2018-08-20 19:47:00 -070025#include <gtest/gtest.h>
26#include <iface/iface.h>
27
Steven Moreland169bb8f2020-01-29 10:21:35 -080028// warning: this is assuming that libbinder_ndk is using the same copy
29// of libbinder that we are.
30#include <binder/IPCThreadState.h>
Ruchir Rastogicc7a7462020-01-31 14:29:15 -080031#include <binder/IResultReceiver.h>
32#include <binder/IServiceManager.h>
33#include <binder/IShellCallback.h>
Steven Moreland169bb8f2020-01-29 10:21:35 -080034
Steven Morelandf92c1fa2020-01-24 13:25:15 -080035#include <sys/prctl.h>
Steven Moreland507547f2018-11-06 15:58:05 -080036#include <chrono>
37#include <condition_variable>
Steven Moreland2f405f52020-07-08 22:24:29 +000038#include <iostream>
Steven Moreland507547f2018-11-06 15:58:05 -080039#include <mutex>
40
Ruchir Rastogicc7a7462020-01-31 14:29:15 -080041using namespace android;
Steven Moreland2e87adc2018-08-20 19:47:00 -070042
43constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
Steven Moreland169bb8f2020-01-29 10:21:35 -080044constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
Steven Moreland2e87adc2018-08-20 19:47:00 -070045
Steven Moreland169bb8f2020-01-29 10:21:35 -080046class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
Steven Morelandb2de9532020-05-29 21:44:41 +000047 ndk::ScopedAStatus repeatInt(int32_t in, int32_t* out) {
48 *out = in;
49 return ndk::ScopedAStatus::ok();
50 }
Steven Moreland169bb8f2020-01-29 10:21:35 -080051 ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
52 (void)empty;
53 return ndk::ScopedAStatus::ok();
54 }
55 ndk::ScopedAStatus forceFlushCommands() {
56 // warning: this is assuming that libbinder_ndk is using the same copy
57 // of libbinder that we are.
58 android::IPCThreadState::self()->flushCommands();
59 return ndk::ScopedAStatus::ok();
60 }
Steven Moreland2f405f52020-07-08 22:24:29 +000061 ndk::ScopedAStatus getsRequestedSid(bool* out) {
62 const char* sid = AIBinder_getCallingSid();
63 std::cout << "Got security context: " << (sid ?: "null") << std::endl;
64 *out = sid != nullptr;
65 return ndk::ScopedAStatus::ok();
66 }
Ruchir Rastogicc7a7462020-01-31 14:29:15 -080067 binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
68 uint32_t numArgs) override {
69 for (uint32_t i = 0; i < numArgs; i++) {
70 dprintf(out, "%s", args[i]);
71 }
72 fsync(out);
73 return STATUS_OK;
74 }
Steven Moreland169bb8f2020-01-29 10:21:35 -080075};
76
77int generatedService() {
78 ABinderProcess_setThreadPoolMaxThreadCount(0);
79
80 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
Steven Moreland2f405f52020-07-08 22:24:29 +000081 auto binder = service->asBinder();
82
83 AIBinder_setRequestingSid(binder.get(), true);
84
85 binder_status_t status = AServiceManager_addService(binder.get(), kBinderNdkUnitTestService);
Steven Moreland169bb8f2020-01-29 10:21:35 -080086
87 if (status != STATUS_OK) {
88 LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService;
89 }
90
91 ABinderProcess_joinThreadPool();
92
93 return 1; // should not return
94}
95
96// manually-written parceling class considered bad practice
Steven Morelandf92c1fa2020-01-24 13:25:15 -080097class MyFoo : public IFoo {
98 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
99 *out = 2 * in;
100 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
101 return STATUS_OK;
102 }
103
104 binder_status_t die() override {
105 LOG(FATAL) << "IFoo::die called!";
106 return STATUS_UNKNOWN_ERROR;
107 }
108};
109
Steven Moreland169bb8f2020-01-29 10:21:35 -0800110int manualService(const char* instance) {
Steven Morelandf92c1fa2020-01-24 13:25:15 -0800111 ABinderProcess_setThreadPoolMaxThreadCount(0);
112
113 // Strong reference to MyFoo kept by service manager.
114 binder_status_t status = (new MyFoo)->addService(instance);
115
116 if (status != STATUS_OK) {
117 LOG(FATAL) << "Could not register: " << status << " " << instance;
118 }
119
120 ABinderProcess_joinThreadPool();
121
122 return 1; // should not return
123}
124
Steven Moreland2e87adc2018-08-20 19:47:00 -0700125// This is too slow
126// TEST(NdkBinder, GetServiceThatDoesntExist) {
127// sp<IFoo> foo = IFoo::getService("asdfghkl;");
128// EXPECT_EQ(nullptr, foo.get());
129// }
130
Steven Morelanddea68bb2019-02-15 10:53:08 -0800131TEST(NdkBinder, CheckServiceThatDoesntExist) {
132 AIBinder* binder = AServiceManager_checkService("asdfghkl;");
133 ASSERT_EQ(nullptr, binder);
134}
135
136TEST(NdkBinder, CheckServiceThatDoesExist) {
137 AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
138 EXPECT_NE(nullptr, binder);
139 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
140
141 AIBinder_decStrong(binder);
142}
143
Steven Moreland2e87adc2018-08-20 19:47:00 -0700144TEST(NdkBinder, DoubleNumber) {
145 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
146 ASSERT_NE(foo, nullptr);
Steven Moreland507547f2018-11-06 15:58:05 -0800147
148 int32_t out;
149 EXPECT_EQ(STATUS_OK, foo->doubleNumber(1, &out));
150 EXPECT_EQ(2, out);
151}
152
153void LambdaOnDeath(void* cookie) {
154 auto onDeath = static_cast<std::function<void(void)>*>(cookie);
155 (*onDeath)();
156};
157TEST(NdkBinder, DeathRecipient) {
158 using namespace std::chrono_literals;
159
160 AIBinder* binder;
161 sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor, &binder);
162 ASSERT_NE(nullptr, foo.get());
163 ASSERT_NE(nullptr, binder);
164
165 std::mutex deathMutex;
166 std::condition_variable deathCv;
167 bool deathRecieved = false;
168
169 std::function<void(void)> onDeath = [&] {
170 std::cerr << "Binder died (as requested)." << std::endl;
171 deathRecieved = true;
172 deathCv.notify_one();
173 };
174
175 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
176
177 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&onDeath)));
178
179 // the binder driver should return this if the service dies during the transaction
180 EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
181
Steven Moreland64127ca2019-03-13 09:25:44 -0700182 foo = nullptr;
Steven Moreland64127ca2019-03-13 09:25:44 -0700183
Steven Moreland507547f2018-11-06 15:58:05 -0800184 std::unique_lock<std::mutex> lock(deathMutex);
185 EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; }));
186 EXPECT_TRUE(deathRecieved);
187
188 AIBinder_DeathRecipient_delete(recipient);
Steven Moreland6bd09192020-01-24 13:06:57 -0800189 AIBinder_decStrong(binder);
190 binder = nullptr;
Steven Moreland2e87adc2018-08-20 19:47:00 -0700191}
192
193TEST(NdkBinder, RetrieveNonNdkService) {
194 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
195 ASSERT_NE(nullptr, binder);
Steven Moreland65867d72018-09-04 14:22:26 -0700196 EXPECT_TRUE(AIBinder_isRemote(binder));
197 EXPECT_TRUE(AIBinder_isAlive(binder));
Steven Moreland5d62e442018-09-13 15:01:02 -0700198 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
Steven Moreland65867d72018-09-04 14:22:26 -0700199
Steven Moreland2e87adc2018-08-20 19:47:00 -0700200 AIBinder_decStrong(binder);
201}
202
Steven Moreland901c7452018-09-04 16:17:28 -0700203void OnBinderDeath(void* cookie) {
204 LOG(ERROR) << "BINDER DIED. COOKIE: " << cookie;
205}
206
207TEST(NdkBinder, LinkToDeath) {
Steven Moreland901c7452018-09-04 16:17:28 -0700208 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
209 ASSERT_NE(nullptr, binder);
210
211 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
212 ASSERT_NE(nullptr, recipient);
213
Steven Moreland5d62e442018-09-13 15:01:02 -0700214 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
215 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
216 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
217 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
218 EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
Steven Moreland901c7452018-09-04 16:17:28 -0700219
Steven Moreland9b80e282018-09-19 13:57:23 -0700220 AIBinder_DeathRecipient_delete(recipient);
Steven Moreland901c7452018-09-04 16:17:28 -0700221 AIBinder_decStrong(binder);
222}
223
Steven Moreland2e87adc2018-08-20 19:47:00 -0700224class MyTestFoo : public IFoo {
Steven Moreland507547f2018-11-06 15:58:05 -0800225 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
226 *out = 2 * in;
227 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
228 return STATUS_OK;
229 }
230 binder_status_t die() override {
231 ADD_FAILURE() << "die called on local instance";
232 return STATUS_OK;
Steven Moreland2e87adc2018-08-20 19:47:00 -0700233 }
234};
235
236TEST(NdkBinder, GetServiceInProcess) {
237 static const char* kInstanceName = "test-get-service-in-process";
238
239 sp<IFoo> foo = new MyTestFoo;
Steven Moreland5d62e442018-09-13 15:01:02 -0700240 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName));
Steven Moreland2e87adc2018-08-20 19:47:00 -0700241
242 sp<IFoo> getFoo = IFoo::getService(kInstanceName);
243 EXPECT_EQ(foo.get(), getFoo.get());
244
Steven Moreland507547f2018-11-06 15:58:05 -0800245 int32_t out;
246 EXPECT_EQ(STATUS_OK, getFoo->doubleNumber(1, &out));
247 EXPECT_EQ(2, out);
Steven Moreland2e87adc2018-08-20 19:47:00 -0700248}
249
Steven Moreland94968952018-09-05 14:42:59 -0700250TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
251 AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
252 ASSERT_NE(nullptr, binderA);
253
254 AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
255 ASSERT_NE(nullptr, binderB);
256
257 EXPECT_EQ(binderA, binderB);
258
259 AIBinder_decStrong(binderA);
260 AIBinder_decStrong(binderB);
261}
262
Steven Moreland02f75652018-09-18 14:08:30 -0700263TEST(NdkBinder, ToFromJavaNullptr) {
264 EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
265 EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
266}
267
Steven Moreland94968952018-09-05 14:42:59 -0700268TEST(NdkBinder, ABpBinderRefCount) {
269 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
270 AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
271
272 ASSERT_NE(nullptr, binder);
273 EXPECT_EQ(1, AIBinder_debugGetRefCount(binder));
274
275 AIBinder_decStrong(binder);
276
277 // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here
278 ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder));
279
Steven Moreland9b80e282018-09-19 13:57:23 -0700280 AIBinder_Weak_delete(wBinder);
Steven Moreland94968952018-09-05 14:42:59 -0700281}
282
Steven Moreland2e87adc2018-08-20 19:47:00 -0700283TEST(NdkBinder, AddServiceMultipleTimes) {
284 static const char* kInstanceName1 = "test-multi-1";
285 static const char* kInstanceName2 = "test-multi-2";
286 sp<IFoo> foo = new MyTestFoo;
Steven Moreland5d62e442018-09-13 15:01:02 -0700287 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName1));
288 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName2));
Steven Moreland2e87adc2018-08-20 19:47:00 -0700289 EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
290}
Steven Moreland2648d202018-08-28 01:23:02 -0700291
Steven Moreland2f405f52020-07-08 22:24:29 +0000292TEST(NdkBinder, RequestedSidWorks) {
293 ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
294 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
295 aidl::IBinderNdkUnitTest::fromBinder(binder);
296
297 bool gotSid = false;
298 EXPECT_TRUE(service->getsRequestedSid(&gotSid).isOk());
299 EXPECT_TRUE(gotSid);
300}
301
Steven Moreland169bb8f2020-01-29 10:21:35 -0800302TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
303 static volatile bool destroyed = false;
304 static std::mutex dMutex;
305 static std::condition_variable cv;
306
307 class MyEmpty : public aidl::BnEmpty {
308 virtual ~MyEmpty() {
309 destroyed = true;
310 cv.notify_one();
311 }
312 };
313
314 std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
315
316 ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
317 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
318 aidl::IBinderNdkUnitTest::fromBinder(binder);
319
320 EXPECT_FALSE(destroyed);
321
322 service->takeInterface(empty);
323 service->forceFlushCommands();
324 empty = nullptr;
325
326 // give other binder thread time to process commands
327 {
328 using namespace std::chrono_literals;
329 std::unique_lock<std::mutex> lk(dMutex);
330 cv.wait_for(lk, 1s, [] { return destroyed; });
331 }
332
333 EXPECT_TRUE(destroyed);
334}
335
Steven Morelandb2de9532020-05-29 21:44:41 +0000336TEST(NdkBinder, ConvertToPlatformBinder) {
337 for (const ndk::SpAIBinder& binder :
338 {// remote
339 ndk::SpAIBinder(AServiceManager_getService(kBinderNdkUnitTestService)),
340 // local
341 ndk::SharedRefBase::make<MyBinderNdkUnitTest>()->asBinder()}) {
342 // convert to platform binder
343 EXPECT_NE(binder.get(), nullptr);
344 sp<IBinder> platformBinder = AIBinder_toPlatformBinder(binder.get());
345 EXPECT_NE(platformBinder.get(), nullptr);
346 auto proxy = interface_cast<IBinderNdkUnitTest>(platformBinder);
347 EXPECT_NE(proxy, nullptr);
348
349 // use platform binder
350 int out;
351 EXPECT_TRUE(proxy->repeatInt(4, &out).isOk());
352 EXPECT_EQ(out, 4);
353
354 // convert back
355 ndk::SpAIBinder backBinder = ndk::SpAIBinder(AIBinder_fromPlatformBinder(platformBinder));
356 EXPECT_EQ(backBinder.get(), binder.get());
357 }
358}
359
Ruchir Rastogicc7a7462020-01-31 14:29:15 -0800360class MyResultReceiver : public BnResultReceiver {
361 public:
362 Mutex mMutex;
363 Condition mCondition;
364 bool mHaveResult = false;
365 int32_t mResult = 0;
366
367 virtual void send(int32_t resultCode) {
368 AutoMutex _l(mMutex);
369 mResult = resultCode;
370 mHaveResult = true;
371 mCondition.signal();
372 }
373
374 int32_t waitForResult() {
375 AutoMutex _l(mMutex);
376 while (!mHaveResult) {
377 mCondition.wait(mMutex);
378 }
379 return mResult;
380 }
381};
382
383class MyShellCallback : public BnShellCallback {
384 public:
385 virtual int openFile(const String16& /*path*/, const String16& /*seLinuxContext*/,
386 const String16& /*mode*/) {
387 // Empty implementation.
388 return 0;
389 }
390};
391
392bool ReadFdToString(int fd, std::string* content) {
393 char buf[64];
394 ssize_t n;
395 while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
396 content->append(buf, n);
397 }
398 return (n == 0) ? true : false;
399}
400
401std::string shellCmdToString(sp<IBinder> unitTestService, const std::vector<const char*>& args) {
402 int inFd[2] = {-1, -1};
403 int outFd[2] = {-1, -1};
404 int errFd[2] = {-1, -1};
405
406 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, inFd));
407 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, outFd));
408 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, errFd));
409
410 sp<MyShellCallback> cb = new MyShellCallback();
411 sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
412
413 Vector<String16> argsVec;
414 for (int i = 0; i < args.size(); i++) {
415 argsVec.add(String16(args[i]));
416 }
417 status_t error = IBinder::shellCommand(unitTestService, inFd[0], outFd[0], errFd[0], argsVec,
418 cb, resultReceiver);
419 EXPECT_EQ(error, android::OK);
420
421 status_t res = resultReceiver->waitForResult();
422 EXPECT_EQ(res, android::OK);
423
424 close(inFd[0]);
425 close(inFd[1]);
426 close(outFd[0]);
427 close(errFd[0]);
428 close(errFd[1]);
429
430 std::string ret;
431 EXPECT_TRUE(ReadFdToString(outFd[1], &ret));
432 close(outFd[1]);
433 return ret;
434}
435
436TEST(NdkBinder, UseHandleShellCommand) {
437 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
438 sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
439
440 EXPECT_EQ("", shellCmdToString(testService, {}));
441 EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
442 EXPECT_EQ("Hello world!", shellCmdToString(testService, {"Hello ", "world!"}));
443 EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
444}
445
Steven Moreland507547f2018-11-06 15:58:05 -0800446int main(int argc, char* argv[]) {
447 ::testing::InitGoogleTest(&argc, argv);
448
Steven Morelandf92c1fa2020-01-24 13:25:15 -0800449 if (fork() == 0) {
450 prctl(PR_SET_PDEATHSIG, SIGHUP);
Steven Moreland169bb8f2020-01-29 10:21:35 -0800451 return manualService(IFoo::kInstanceNameToDieFor);
Steven Morelandf92c1fa2020-01-24 13:25:15 -0800452 }
453 if (fork() == 0) {
454 prctl(PR_SET_PDEATHSIG, SIGHUP);
Steven Moreland169bb8f2020-01-29 10:21:35 -0800455 return manualService(IFoo::kSomeInstanceName);
456 }
457 if (fork() == 0) {
458 prctl(PR_SET_PDEATHSIG, SIGHUP);
459 return generatedService();
Steven Morelandf92c1fa2020-01-24 13:25:15 -0800460 }
461
Steven Moreland507547f2018-11-06 15:58:05 -0800462 ABinderProcess_setThreadPoolMaxThreadCount(1); // to recieve death notifications/callbacks
463 ABinderProcess_startThreadPool();
464
465 return RUN_ALL_TESTS();
466}
467
Steven Moreland2648d202018-08-28 01:23:02 -0700468#include <android/binder_auto_utils.h>
469#include <android/binder_interface_utils.h>
Steven Morelanda8845662018-10-12 11:53:03 -0700470#include <android/binder_parcel_utils.h>