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_manager.h>
23 #include <android/binder_process.h>
24 #include <gtest/gtest.h>
25 #include <iface/iface.h>
26
27 // warning: this is assuming that libbinder_ndk is using the same copy
28 // of libbinder that we are.
29 #include <binder/IPCThreadState.h>
30 #include <binder/IResultReceiver.h>
31 #include <binder/IServiceManager.h>
32 #include <binder/IShellCallback.h>
33
34 #include <sys/prctl.h>
35 #include <chrono>
36 #include <condition_variable>
37 #include <mutex>
38
39 using namespace android;
40
41 constexpr char kExistingNonNdkService[] = "SurfaceFlinger";
42 constexpr char kBinderNdkUnitTestService[] = "BinderNdkUnitTest";
43
44 class MyBinderNdkUnitTest : public aidl::BnBinderNdkUnitTest {
takeInterface(const std::shared_ptr<aidl::IEmpty> & empty)45 ndk::ScopedAStatus takeInterface(const std::shared_ptr<aidl::IEmpty>& empty) {
46 (void)empty;
47 return ndk::ScopedAStatus::ok();
48 }
forceFlushCommands()49 ndk::ScopedAStatus forceFlushCommands() {
50 // warning: this is assuming that libbinder_ndk is using the same copy
51 // of libbinder that we are.
52 android::IPCThreadState::self()->flushCommands();
53 return ndk::ScopedAStatus::ok();
54 }
handleShellCommand(int,int out,int,const char ** args,uint32_t numArgs)55 binder_status_t handleShellCommand(int /*in*/, int out, int /*err*/, const char** args,
56 uint32_t numArgs) override {
57 for (uint32_t i = 0; i < numArgs; i++) {
58 dprintf(out, "%s", args[i]);
59 }
60 fsync(out);
61 return STATUS_OK;
62 }
63 };
64
generatedService()65 int generatedService() {
66 ABinderProcess_setThreadPoolMaxThreadCount(0);
67
68 auto service = ndk::SharedRefBase::make<MyBinderNdkUnitTest>();
69 binder_status_t status =
70 AServiceManager_addService(service->asBinder().get(), kBinderNdkUnitTestService);
71
72 if (status != STATUS_OK) {
73 LOG(FATAL) << "Could not register: " << status << " " << kBinderNdkUnitTestService;
74 }
75
76 ABinderProcess_joinThreadPool();
77
78 return 1; // should not return
79 }
80
81 // manually-written parceling class considered bad practice
82 class MyFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)83 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
84 *out = 2 * in;
85 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
86 return STATUS_OK;
87 }
88
die()89 binder_status_t die() override {
90 LOG(FATAL) << "IFoo::die called!";
91 return STATUS_UNKNOWN_ERROR;
92 }
93 };
94
manualService(const char * instance)95 int manualService(const char* instance) {
96 ABinderProcess_setThreadPoolMaxThreadCount(0);
97
98 // Strong reference to MyFoo kept by service manager.
99 binder_status_t status = (new MyFoo)->addService(instance);
100
101 if (status != STATUS_OK) {
102 LOG(FATAL) << "Could not register: " << status << " " << instance;
103 }
104
105 ABinderProcess_joinThreadPool();
106
107 return 1; // should not return
108 }
109
110 // This is too slow
111 // TEST(NdkBinder, GetServiceThatDoesntExist) {
112 // sp<IFoo> foo = IFoo::getService("asdfghkl;");
113 // EXPECT_EQ(nullptr, foo.get());
114 // }
115
TEST(NdkBinder,CheckServiceThatDoesntExist)116 TEST(NdkBinder, CheckServiceThatDoesntExist) {
117 AIBinder* binder = AServiceManager_checkService("asdfghkl;");
118 ASSERT_EQ(nullptr, binder);
119 }
120
TEST(NdkBinder,CheckServiceThatDoesExist)121 TEST(NdkBinder, CheckServiceThatDoesExist) {
122 AIBinder* binder = AServiceManager_checkService(kExistingNonNdkService);
123 EXPECT_NE(nullptr, binder);
124 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
125
126 AIBinder_decStrong(binder);
127 }
128
TEST(NdkBinder,DoubleNumber)129 TEST(NdkBinder, DoubleNumber) {
130 sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName);
131 ASSERT_NE(foo, nullptr);
132
133 int32_t out;
134 EXPECT_EQ(STATUS_OK, foo->doubleNumber(1, &out));
135 EXPECT_EQ(2, out);
136 }
137
LambdaOnDeath(void * cookie)138 void LambdaOnDeath(void* cookie) {
139 auto onDeath = static_cast<std::function<void(void)>*>(cookie);
140 (*onDeath)();
141 };
TEST(NdkBinder,DeathRecipient)142 TEST(NdkBinder, DeathRecipient) {
143 using namespace std::chrono_literals;
144
145 AIBinder* binder;
146 sp<IFoo> foo = IFoo::getService(IFoo::kInstanceNameToDieFor, &binder);
147 ASSERT_NE(nullptr, foo.get());
148 ASSERT_NE(nullptr, binder);
149
150 std::mutex deathMutex;
151 std::condition_variable deathCv;
152 bool deathRecieved = false;
153
154 std::function<void(void)> onDeath = [&] {
155 std::cerr << "Binder died (as requested)." << std::endl;
156 deathRecieved = true;
157 deathCv.notify_one();
158 };
159
160 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(LambdaOnDeath);
161
162 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, static_cast<void*>(&onDeath)));
163
164 // the binder driver should return this if the service dies during the transaction
165 EXPECT_EQ(STATUS_DEAD_OBJECT, foo->die());
166
167 foo = nullptr;
168
169 std::unique_lock<std::mutex> lock(deathMutex);
170 EXPECT_TRUE(deathCv.wait_for(lock, 1s, [&] { return deathRecieved; }));
171 EXPECT_TRUE(deathRecieved);
172
173 AIBinder_DeathRecipient_delete(recipient);
174 AIBinder_decStrong(binder);
175 binder = nullptr;
176 }
177
TEST(NdkBinder,RetrieveNonNdkService)178 TEST(NdkBinder, RetrieveNonNdkService) {
179 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
180 ASSERT_NE(nullptr, binder);
181 EXPECT_TRUE(AIBinder_isRemote(binder));
182 EXPECT_TRUE(AIBinder_isAlive(binder));
183 EXPECT_EQ(STATUS_OK, AIBinder_ping(binder));
184
185 AIBinder_decStrong(binder);
186 }
187
OnBinderDeath(void * cookie)188 void OnBinderDeath(void* cookie) {
189 LOG(ERROR) << "BINDER DIED. COOKIE: " << cookie;
190 }
191
TEST(NdkBinder,LinkToDeath)192 TEST(NdkBinder, LinkToDeath) {
193 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
194 ASSERT_NE(nullptr, binder);
195
196 AIBinder_DeathRecipient* recipient = AIBinder_DeathRecipient_new(OnBinderDeath);
197 ASSERT_NE(nullptr, recipient);
198
199 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
200 EXPECT_EQ(STATUS_OK, AIBinder_linkToDeath(binder, recipient, nullptr));
201 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
202 EXPECT_EQ(STATUS_OK, AIBinder_unlinkToDeath(binder, recipient, nullptr));
203 EXPECT_EQ(STATUS_NAME_NOT_FOUND, AIBinder_unlinkToDeath(binder, recipient, nullptr));
204
205 AIBinder_DeathRecipient_delete(recipient);
206 AIBinder_decStrong(binder);
207 }
208
209 class MyTestFoo : public IFoo {
doubleNumber(int32_t in,int32_t * out)210 binder_status_t doubleNumber(int32_t in, int32_t* out) override {
211 *out = 2 * in;
212 LOG(INFO) << "doubleNumber (" << in << ") => " << *out;
213 return STATUS_OK;
214 }
die()215 binder_status_t die() override {
216 ADD_FAILURE() << "die called on local instance";
217 return STATUS_OK;
218 }
219 };
220
TEST(NdkBinder,GetServiceInProcess)221 TEST(NdkBinder, GetServiceInProcess) {
222 static const char* kInstanceName = "test-get-service-in-process";
223
224 sp<IFoo> foo = new MyTestFoo;
225 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName));
226
227 sp<IFoo> getFoo = IFoo::getService(kInstanceName);
228 EXPECT_EQ(foo.get(), getFoo.get());
229
230 int32_t out;
231 EXPECT_EQ(STATUS_OK, getFoo->doubleNumber(1, &out));
232 EXPECT_EQ(2, out);
233 }
234
TEST(NdkBinder,EqualityOfRemoteBinderPointer)235 TEST(NdkBinder, EqualityOfRemoteBinderPointer) {
236 AIBinder* binderA = AServiceManager_getService(kExistingNonNdkService);
237 ASSERT_NE(nullptr, binderA);
238
239 AIBinder* binderB = AServiceManager_getService(kExistingNonNdkService);
240 ASSERT_NE(nullptr, binderB);
241
242 EXPECT_EQ(binderA, binderB);
243
244 AIBinder_decStrong(binderA);
245 AIBinder_decStrong(binderB);
246 }
247
TEST(NdkBinder,ToFromJavaNullptr)248 TEST(NdkBinder, ToFromJavaNullptr) {
249 EXPECT_EQ(nullptr, AIBinder_toJavaBinder(nullptr, nullptr));
250 EXPECT_EQ(nullptr, AIBinder_fromJavaBinder(nullptr, nullptr));
251 }
252
TEST(NdkBinder,ABpBinderRefCount)253 TEST(NdkBinder, ABpBinderRefCount) {
254 AIBinder* binder = AServiceManager_getService(kExistingNonNdkService);
255 AIBinder_Weak* wBinder = AIBinder_Weak_new(binder);
256
257 ASSERT_NE(nullptr, binder);
258 EXPECT_EQ(1, AIBinder_debugGetRefCount(binder));
259
260 AIBinder_decStrong(binder);
261
262 // assert because would need to decStrong if non-null and we shouldn't need to add a no-op here
263 ASSERT_NE(nullptr, AIBinder_Weak_promote(wBinder));
264
265 AIBinder_Weak_delete(wBinder);
266 }
267
TEST(NdkBinder,AddServiceMultipleTimes)268 TEST(NdkBinder, AddServiceMultipleTimes) {
269 static const char* kInstanceName1 = "test-multi-1";
270 static const char* kInstanceName2 = "test-multi-2";
271 sp<IFoo> foo = new MyTestFoo;
272 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName1));
273 EXPECT_EQ(STATUS_OK, foo->addService(kInstanceName2));
274 EXPECT_EQ(IFoo::getService(kInstanceName1), IFoo::getService(kInstanceName2));
275 }
276
TEST(NdkBinder,SentAidlBinderCanBeDestroyed)277 TEST(NdkBinder, SentAidlBinderCanBeDestroyed) {
278 static volatile bool destroyed = false;
279 static std::mutex dMutex;
280 static std::condition_variable cv;
281
282 class MyEmpty : public aidl::BnEmpty {
283 virtual ~MyEmpty() {
284 destroyed = true;
285 cv.notify_one();
286 }
287 };
288
289 std::shared_ptr<MyEmpty> empty = ndk::SharedRefBase::make<MyEmpty>();
290
291 ndk::SpAIBinder binder(AServiceManager_getService(kBinderNdkUnitTestService));
292 std::shared_ptr<aidl::IBinderNdkUnitTest> service =
293 aidl::IBinderNdkUnitTest::fromBinder(binder);
294
295 EXPECT_FALSE(destroyed);
296
297 service->takeInterface(empty);
298 service->forceFlushCommands();
299 empty = nullptr;
300
301 // give other binder thread time to process commands
302 {
303 using namespace std::chrono_literals;
304 std::unique_lock<std::mutex> lk(dMutex);
305 cv.wait_for(lk, 1s, [] { return destroyed; });
306 }
307
308 EXPECT_TRUE(destroyed);
309 }
310
311 class MyResultReceiver : public BnResultReceiver {
312 public:
313 Mutex mMutex;
314 Condition mCondition;
315 bool mHaveResult = false;
316 int32_t mResult = 0;
317
send(int32_t resultCode)318 virtual void send(int32_t resultCode) {
319 AutoMutex _l(mMutex);
320 mResult = resultCode;
321 mHaveResult = true;
322 mCondition.signal();
323 }
324
waitForResult()325 int32_t waitForResult() {
326 AutoMutex _l(mMutex);
327 while (!mHaveResult) {
328 mCondition.wait(mMutex);
329 }
330 return mResult;
331 }
332 };
333
334 class MyShellCallback : public BnShellCallback {
335 public:
openFile(const String16 &,const String16 &,const String16 &)336 virtual int openFile(const String16& /*path*/, const String16& /*seLinuxContext*/,
337 const String16& /*mode*/) {
338 // Empty implementation.
339 return 0;
340 }
341 };
342
ReadFdToString(int fd,std::string * content)343 bool ReadFdToString(int fd, std::string* content) {
344 char buf[64];
345 ssize_t n;
346 while ((n = TEMP_FAILURE_RETRY(read(fd, &buf[0], sizeof(buf)))) > 0) {
347 content->append(buf, n);
348 }
349 return (n == 0) ? true : false;
350 }
351
shellCmdToString(sp<IBinder> unitTestService,const std::vector<const char * > & args)352 std::string shellCmdToString(sp<IBinder> unitTestService, const std::vector<const char*>& args) {
353 int inFd[2] = {-1, -1};
354 int outFd[2] = {-1, -1};
355 int errFd[2] = {-1, -1};
356
357 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, inFd));
358 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, outFd));
359 EXPECT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM, 0, errFd));
360
361 sp<MyShellCallback> cb = new MyShellCallback();
362 sp<MyResultReceiver> resultReceiver = new MyResultReceiver();
363
364 Vector<String16> argsVec;
365 for (int i = 0; i < args.size(); i++) {
366 argsVec.add(String16(args[i]));
367 }
368 status_t error = IBinder::shellCommand(unitTestService, inFd[0], outFd[0], errFd[0], argsVec,
369 cb, resultReceiver);
370 EXPECT_EQ(error, android::OK);
371
372 status_t res = resultReceiver->waitForResult();
373 EXPECT_EQ(res, android::OK);
374
375 close(inFd[0]);
376 close(inFd[1]);
377 close(outFd[0]);
378 close(errFd[0]);
379 close(errFd[1]);
380
381 std::string ret;
382 EXPECT_TRUE(ReadFdToString(outFd[1], &ret));
383 close(outFd[1]);
384 return ret;
385 }
386
TEST(NdkBinder,UseHandleShellCommand)387 TEST(NdkBinder, UseHandleShellCommand) {
388 static const sp<android::IServiceManager> sm(android::defaultServiceManager());
389 sp<IBinder> testService = sm->getService(String16(kBinderNdkUnitTestService));
390
391 EXPECT_EQ("", shellCmdToString(testService, {}));
392 EXPECT_EQ("", shellCmdToString(testService, {"", ""}));
393 EXPECT_EQ("Hello world!", shellCmdToString(testService, {"Hello ", "world!"}));
394 EXPECT_EQ("CMD", shellCmdToString(testService, {"C", "M", "D"}));
395 }
396
main(int argc,char * argv[])397 int main(int argc, char* argv[]) {
398 ::testing::InitGoogleTest(&argc, argv);
399
400 if (fork() == 0) {
401 prctl(PR_SET_PDEATHSIG, SIGHUP);
402 return manualService(IFoo::kInstanceNameToDieFor);
403 }
404 if (fork() == 0) {
405 prctl(PR_SET_PDEATHSIG, SIGHUP);
406 return manualService(IFoo::kSomeInstanceName);
407 }
408 if (fork() == 0) {
409 prctl(PR_SET_PDEATHSIG, SIGHUP);
410 return generatedService();
411 }
412
413 ABinderProcess_setThreadPoolMaxThreadCount(1); // to recieve death notifications/callbacks
414 ABinderProcess_startThreadPool();
415
416 return RUN_ALL_TESTS();
417 }
418
419 #include <android/binder_auto_utils.h>
420 #include <android/binder_interface_utils.h>
421 #include <android/binder_parcel_utils.h>
422