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