• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 <errno.h>
18 #include <fcntl.h>
19 #include <poll.h>
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 
24 #include <gtest/gtest.h>
25 
26 #include <binder/Binder.h>
27 #include <binder/IBinder.h>
28 #include <binder/IPCThreadState.h>
29 #include <binder/IServiceManager.h>
30 
31 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
32 
33 using namespace android;
34 
35 static testing::Environment* binder_env;
36 static char *binderservername;
37 static char binderserverarg[] = "--binderserver";
38 
39 static String16 binderLibTestServiceName = String16("test.binderLib");
40 
41 enum BinderLibTestTranscationCode {
42     BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
43     BINDER_LIB_TEST_REGISTER_SERVER,
44     BINDER_LIB_TEST_ADD_SERVER,
45     BINDER_LIB_TEST_CALL_BACK,
46     BINDER_LIB_TEST_NOP_CALL_BACK,
47     BINDER_LIB_TEST_GET_ID_TRANSACTION,
48     BINDER_LIB_TEST_INDIRECT_TRANSACTION,
49     BINDER_LIB_TEST_SET_ERROR_TRANSACTION,
50     BINDER_LIB_TEST_GET_STATUS_TRANSACTION,
51     BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
52     BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
53     BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
54     BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION,
55     BINDER_LIB_TEST_EXIT_TRANSACTION,
56     BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
57     BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
58 };
59 
start_server_process(int arg2)60 pid_t start_server_process(int arg2)
61 {
62     int ret;
63     pid_t pid;
64     status_t status;
65     int pipefd[2];
66     char stri[16];
67     char strpipefd1[16];
68     char *childargv[] = {
69         binderservername,
70         binderserverarg,
71         stri,
72         strpipefd1,
73         NULL
74     };
75 
76     ret = pipe(pipefd);
77     if (ret < 0)
78         return ret;
79 
80     snprintf(stri, sizeof(stri), "%d", arg2);
81     snprintf(strpipefd1, sizeof(strpipefd1), "%d", pipefd[1]);
82 
83     pid = fork();
84     if (pid == -1)
85         return pid;
86     if (pid == 0) {
87         close(pipefd[0]);
88         execv(binderservername, childargv);
89         status = -errno;
90         write(pipefd[1], &status, sizeof(status));
91         fprintf(stderr, "execv failed, %s\n", strerror(errno));
92         _exit(EXIT_FAILURE);
93     }
94     close(pipefd[1]);
95     ret = read(pipefd[0], &status, sizeof(status));
96     //printf("pipe read returned %d, status %d\n", ret, status);
97     close(pipefd[0]);
98     if (ret == sizeof(status)) {
99         ret = status;
100     } else {
101         kill(pid, SIGKILL);
102         if (ret >= 0) {
103             ret = NO_INIT;
104         }
105     }
106     if (ret < 0) {
107         wait(NULL);
108         return ret;
109     }
110     return pid;
111 }
112 
113 class BinderLibTestEnv : public ::testing::Environment {
114     public:
BinderLibTestEnv()115         BinderLibTestEnv() {}
getServer(void)116         sp<IBinder> getServer(void) {
117             return m_server;
118         }
119 
120     private:
SetUp()121         virtual void SetUp() {
122             m_serverpid = start_server_process(0);
123             //printf("m_serverpid %d\n", m_serverpid);
124             ASSERT_GT(m_serverpid, 0);
125 
126             sp<IServiceManager> sm = defaultServiceManager();
127             //printf("%s: pid %d, get service\n", __func__, m_pid);
128             m_server = sm->getService(binderLibTestServiceName);
129             ASSERT_TRUE(m_server != NULL);
130             //printf("%s: pid %d, get service done\n", __func__, m_pid);
131         }
TearDown()132         virtual void TearDown() {
133             status_t ret;
134             Parcel data, reply;
135             int exitStatus;
136             pid_t pid;
137 
138             //printf("%s: pid %d\n", __func__, m_pid);
139             if (m_server != NULL) {
140                 ret = m_server->transact(BINDER_LIB_TEST_GET_STATUS_TRANSACTION, data, &reply);
141                 EXPECT_EQ(0, ret);
142                 ret = m_server->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
143                 EXPECT_EQ(0, ret);
144             }
145             if (m_serverpid > 0) {
146                 //printf("wait for %d\n", m_pids[i]);
147                 pid = wait(&exitStatus);
148                 EXPECT_EQ(m_serverpid, pid);
149                 EXPECT_TRUE(WIFEXITED(exitStatus));
150                 EXPECT_EQ(0, WEXITSTATUS(exitStatus));
151             }
152         }
153 
154         pid_t m_serverpid;
155         sp<IBinder> m_server;
156 };
157 
158 class BinderLibTest : public ::testing::Test {
159     public:
SetUp()160         virtual void SetUp() {
161             m_server = static_cast<BinderLibTestEnv *>(binder_env)->getServer();
162         }
TearDown()163         virtual void TearDown() {
164         }
165     protected:
addServer(int32_t * idPtr=NULL)166         sp<IBinder> addServer(int32_t *idPtr = NULL)
167         {
168             int ret;
169             int32_t id;
170             Parcel data, reply;
171             sp<IBinder> binder;
172 
173             ret = m_server->transact(BINDER_LIB_TEST_ADD_SERVER, data, &reply);
174             EXPECT_EQ(NO_ERROR, ret);
175 
176             EXPECT_FALSE(binder != NULL);
177             binder = reply.readStrongBinder();
178             EXPECT_TRUE(binder != NULL);
179             ret = reply.readInt32(&id);
180             EXPECT_EQ(NO_ERROR, ret);
181             if (idPtr)
182                 *idPtr = id;
183             return binder;
184         }
waitForReadData(int fd,int timeout_ms)185         void waitForReadData(int fd, int timeout_ms) {
186             int ret;
187             pollfd pfd = pollfd();
188 
189             pfd.fd = fd;
190             pfd.events = POLLIN;
191             ret = poll(&pfd, 1, timeout_ms);
192             EXPECT_EQ(1, ret);
193         }
194 
195         sp<IBinder> m_server;
196 };
197 
198 class BinderLibTestBundle : public Parcel
199 {
200     public:
BinderLibTestBundle(void)201         BinderLibTestBundle(void) {}
BinderLibTestBundle(const Parcel * source)202         BinderLibTestBundle(const Parcel *source) : m_isValid(false) {
203             int32_t mark;
204             int32_t bundleLen;
205             size_t pos;
206 
207             if (source->readInt32(&mark))
208                 return;
209             if (mark != MARK_START)
210                 return;
211             if (source->readInt32(&bundleLen))
212                 return;
213             pos = source->dataPosition();
214             if (Parcel::appendFrom(source, pos, bundleLen))
215                 return;
216             source->setDataPosition(pos + bundleLen);
217             if (source->readInt32(&mark))
218                 return;
219             if (mark != MARK_END)
220                 return;
221             m_isValid = true;
222             setDataPosition(0);
223         }
appendTo(Parcel * dest)224         void appendTo(Parcel *dest) {
225             dest->writeInt32(MARK_START);
226             dest->writeInt32(dataSize());
227             dest->appendFrom(this, 0, dataSize());
228             dest->writeInt32(MARK_END);
229         };
isValid(void)230         bool isValid(void) {
231             return m_isValid;
232         }
233     private:
234         enum {
235             MARK_START  = B_PACK_CHARS('B','T','B','S'),
236             MARK_END    = B_PACK_CHARS('B','T','B','E'),
237         };
238         bool m_isValid;
239 };
240 
241 class BinderLibTestEvent
242 {
243     public:
BinderLibTestEvent(void)244         BinderLibTestEvent(void)
245             : m_eventTriggered(false)
246         {
247             pthread_mutex_init(&m_waitMutex, NULL);
248             pthread_cond_init(&m_waitCond, NULL);
249         }
waitEvent(int timeout_s)250         int waitEvent(int timeout_s)
251         {
252             int ret;
253             pthread_mutex_lock(&m_waitMutex);
254             if (!m_eventTriggered) {
255 #if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
256                 pthread_cond_timeout_np(&m_waitCond, &m_waitMutex, timeout_s * 1000);
257 #else
258                 struct timespec ts;
259                 clock_gettime(CLOCK_REALTIME, &ts);
260                 ts.tv_sec += timeout_s;
261                 pthread_cond_timedwait(&m_waitCond, &m_waitMutex, &ts);
262 #endif
263             }
264             ret = m_eventTriggered ? NO_ERROR : TIMED_OUT;
265             pthread_mutex_unlock(&m_waitMutex);
266             return ret;
267         }
268     protected:
triggerEvent(void)269         void triggerEvent(void) {
270             pthread_mutex_lock(&m_waitMutex);
271             pthread_cond_signal(&m_waitCond);
272             m_eventTriggered = true;
273             pthread_mutex_unlock(&m_waitMutex);
274         };
275     private:
276         pthread_mutex_t m_waitMutex;
277         pthread_cond_t m_waitCond;
278         bool m_eventTriggered;
279 };
280 
281 class BinderLibTestCallBack : public BBinder, public BinderLibTestEvent
282 {
283     public:
BinderLibTestCallBack()284         BinderLibTestCallBack()
285             : m_result(NOT_ENOUGH_DATA)
286         {
287         }
getResult(void)288         status_t getResult(void)
289         {
290             return m_result;
291         }
292 
293     private:
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)294         virtual status_t onTransact(uint32_t code,
295                                     const Parcel& data, Parcel* reply,
296                                     uint32_t flags = 0)
297         {
298             (void)reply;
299             (void)flags;
300             switch(code) {
301             case BINDER_LIB_TEST_CALL_BACK:
302                 m_result = data.readInt32();
303                 triggerEvent();
304                 return NO_ERROR;
305             default:
306                 return UNKNOWN_TRANSACTION;
307             }
308         }
309 
310         status_t m_result;
311 };
312 
313 class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestEvent
314 {
315     private:
binderDied(const wp<IBinder> & who)316         virtual void binderDied(const wp<IBinder>& who) {
317             (void)who;
318             triggerEvent();
319         };
320 };
321 
TEST_F(BinderLibTest,NopTransaction)322 TEST_F(BinderLibTest, NopTransaction) {
323     status_t ret;
324     Parcel data, reply;
325     ret = m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply);
326     EXPECT_EQ(NO_ERROR, ret);
327 }
328 
TEST_F(BinderLibTest,SetError)329 TEST_F(BinderLibTest, SetError) {
330     int32_t testValue[] = { 0, -123, 123 };
331     for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) {
332         status_t ret;
333         Parcel data, reply;
334         data.writeInt32(testValue[i]);
335         ret = m_server->transact(BINDER_LIB_TEST_SET_ERROR_TRANSACTION, data, &reply);
336         EXPECT_EQ(testValue[i], ret);
337     }
338 }
339 
TEST_F(BinderLibTest,GetId)340 TEST_F(BinderLibTest, GetId) {
341     status_t ret;
342     int32_t id;
343     Parcel data, reply;
344     ret = m_server->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply);
345     EXPECT_EQ(NO_ERROR, ret);
346     ret = reply.readInt32(&id);
347     EXPECT_EQ(NO_ERROR, ret);
348     EXPECT_EQ(0, id);
349 }
350 
TEST_F(BinderLibTest,PtrSize)351 TEST_F(BinderLibTest, PtrSize) {
352     status_t ret;
353     int32_t ptrsize;
354     Parcel data, reply;
355     sp<IBinder> server = addServer();
356     ASSERT_TRUE(server != NULL);
357     ret = server->transact(BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, data, &reply);
358     EXPECT_EQ(NO_ERROR, ret);
359     ret = reply.readInt32(&ptrsize);
360     EXPECT_EQ(NO_ERROR, ret);
361     RecordProperty("TestPtrSize", sizeof(void *));
362     RecordProperty("ServerPtrSize", sizeof(void *));
363 }
364 
TEST_F(BinderLibTest,IndirectGetId2)365 TEST_F(BinderLibTest, IndirectGetId2)
366 {
367     status_t ret;
368     int32_t id;
369     int32_t count;
370     Parcel data, reply;
371     int32_t serverId[3];
372 
373     data.writeInt32(ARRAY_SIZE(serverId));
374     for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
375         sp<IBinder> server;
376         BinderLibTestBundle datai;
377 
378         server = addServer(&serverId[i]);
379         ASSERT_TRUE(server != NULL);
380         data.writeStrongBinder(server);
381         data.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
382         datai.appendTo(&data);
383     }
384 
385     ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
386     ASSERT_EQ(NO_ERROR, ret);
387 
388     ret = reply.readInt32(&id);
389     ASSERT_EQ(NO_ERROR, ret);
390     EXPECT_EQ(0, id);
391 
392     ret = reply.readInt32(&count);
393     ASSERT_EQ(NO_ERROR, ret);
394     EXPECT_EQ(ARRAY_SIZE(serverId), count);
395 
396     for (size_t i = 0; i < (size_t)count; i++) {
397         BinderLibTestBundle replyi(&reply);
398         EXPECT_TRUE(replyi.isValid());
399         ret = replyi.readInt32(&id);
400         EXPECT_EQ(NO_ERROR, ret);
401         EXPECT_EQ(serverId[i], id);
402         EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
403     }
404 
405     EXPECT_EQ(reply.dataSize(), reply.dataPosition());
406 }
407 
TEST_F(BinderLibTest,IndirectGetId3)408 TEST_F(BinderLibTest, IndirectGetId3)
409 {
410     status_t ret;
411     int32_t id;
412     int32_t count;
413     Parcel data, reply;
414     int32_t serverId[3];
415 
416     data.writeInt32(ARRAY_SIZE(serverId));
417     for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
418         sp<IBinder> server;
419         BinderLibTestBundle datai;
420         BinderLibTestBundle datai2;
421 
422         server = addServer(&serverId[i]);
423         ASSERT_TRUE(server != NULL);
424         data.writeStrongBinder(server);
425         data.writeInt32(BINDER_LIB_TEST_INDIRECT_TRANSACTION);
426 
427         datai.writeInt32(1);
428         datai.writeStrongBinder(m_server);
429         datai.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
430         datai2.appendTo(&datai);
431 
432         datai.appendTo(&data);
433     }
434 
435     ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
436     ASSERT_EQ(NO_ERROR, ret);
437 
438     ret = reply.readInt32(&id);
439     ASSERT_EQ(NO_ERROR, ret);
440     EXPECT_EQ(0, id);
441 
442     ret = reply.readInt32(&count);
443     ASSERT_EQ(NO_ERROR, ret);
444     EXPECT_EQ(ARRAY_SIZE(serverId), count);
445 
446     for (size_t i = 0; i < (size_t)count; i++) {
447         int32_t counti;
448 
449         BinderLibTestBundle replyi(&reply);
450         EXPECT_TRUE(replyi.isValid());
451         ret = replyi.readInt32(&id);
452         EXPECT_EQ(NO_ERROR, ret);
453         EXPECT_EQ(serverId[i], id);
454 
455         ret = replyi.readInt32(&counti);
456         ASSERT_EQ(NO_ERROR, ret);
457         EXPECT_EQ(1, counti);
458 
459         BinderLibTestBundle replyi2(&replyi);
460         EXPECT_TRUE(replyi2.isValid());
461         ret = replyi2.readInt32(&id);
462         EXPECT_EQ(NO_ERROR, ret);
463         EXPECT_EQ(0, id);
464         EXPECT_EQ(replyi2.dataSize(), replyi2.dataPosition());
465 
466         EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
467     }
468 
469     EXPECT_EQ(reply.dataSize(), reply.dataPosition());
470 }
471 
TEST_F(BinderLibTest,CallBack)472 TEST_F(BinderLibTest, CallBack)
473 {
474     status_t ret;
475     Parcel data, reply;
476     sp<BinderLibTestCallBack> callBack = new BinderLibTestCallBack();
477     data.writeStrongBinder(callBack);
478     ret = m_server->transact(BINDER_LIB_TEST_NOP_CALL_BACK, data, &reply, TF_ONE_WAY);
479     EXPECT_EQ(NO_ERROR, ret);
480     ret = callBack->waitEvent(5);
481     EXPECT_EQ(NO_ERROR, ret);
482     ret = callBack->getResult();
483     EXPECT_EQ(NO_ERROR, ret);
484 }
485 
TEST_F(BinderLibTest,AddServer)486 TEST_F(BinderLibTest, AddServer)
487 {
488     sp<IBinder> server = addServer();
489     ASSERT_TRUE(server != NULL);
490 }
491 
TEST_F(BinderLibTest,DeathNotificationNoRefs)492 TEST_F(BinderLibTest, DeathNotificationNoRefs)
493 {
494     status_t ret;
495 
496     sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
497 
498     {
499         sp<IBinder> binder = addServer();
500         ASSERT_TRUE(binder != NULL);
501         ret = binder->linkToDeath(testDeathRecipient);
502         EXPECT_EQ(NO_ERROR, ret);
503     }
504     IPCThreadState::self()->flushCommands();
505     ret = testDeathRecipient->waitEvent(5);
506     EXPECT_EQ(NO_ERROR, ret);
507 #if 0 /* Is there an unlink api that does not require a strong reference? */
508     ret = binder->unlinkToDeath(testDeathRecipient);
509     EXPECT_EQ(NO_ERROR, ret);
510 #endif
511 }
512 
TEST_F(BinderLibTest,DeathNotificationWeakRef)513 TEST_F(BinderLibTest, DeathNotificationWeakRef)
514 {
515     status_t ret;
516     wp<IBinder> wbinder;
517 
518     sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
519 
520     {
521         sp<IBinder> binder = addServer();
522         ASSERT_TRUE(binder != NULL);
523         ret = binder->linkToDeath(testDeathRecipient);
524         EXPECT_EQ(NO_ERROR, ret);
525         wbinder = binder;
526     }
527     IPCThreadState::self()->flushCommands();
528     ret = testDeathRecipient->waitEvent(5);
529     EXPECT_EQ(NO_ERROR, ret);
530 #if 0 /* Is there an unlink api that does not require a strong reference? */
531     ret = binder->unlinkToDeath(testDeathRecipient);
532     EXPECT_EQ(NO_ERROR, ret);
533 #endif
534 }
535 
TEST_F(BinderLibTest,DeathNotificationStrongRef)536 TEST_F(BinderLibTest, DeathNotificationStrongRef)
537 {
538     status_t ret;
539     sp<IBinder> sbinder;
540 
541     sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
542 
543     {
544         sp<IBinder> binder = addServer();
545         ASSERT_TRUE(binder != NULL);
546         ret = binder->linkToDeath(testDeathRecipient);
547         EXPECT_EQ(NO_ERROR, ret);
548         sbinder = binder;
549     }
550     {
551         Parcel data, reply;
552         ret = sbinder->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
553         EXPECT_EQ(0, ret);
554     }
555     IPCThreadState::self()->flushCommands();
556     ret = testDeathRecipient->waitEvent(5);
557     EXPECT_EQ(NO_ERROR, ret);
558     ret = sbinder->unlinkToDeath(testDeathRecipient);
559     EXPECT_EQ(DEAD_OBJECT, ret);
560 }
561 
TEST_F(BinderLibTest,DeathNotificationMultiple)562 TEST_F(BinderLibTest, DeathNotificationMultiple)
563 {
564     status_t ret;
565     const int clientcount = 2;
566     sp<IBinder> target;
567     sp<IBinder> linkedclient[clientcount];
568     sp<BinderLibTestCallBack> callBack[clientcount];
569     sp<IBinder> passiveclient[clientcount];
570 
571     target = addServer();
572     ASSERT_TRUE(target != NULL);
573     for (int i = 0; i < clientcount; i++) {
574         {
575             Parcel data, reply;
576 
577             linkedclient[i] = addServer();
578             ASSERT_TRUE(linkedclient[i] != NULL);
579             callBack[i] = new BinderLibTestCallBack();
580             data.writeStrongBinder(target);
581             data.writeStrongBinder(callBack[i]);
582             ret = linkedclient[i]->transact(BINDER_LIB_TEST_LINK_DEATH_TRANSACTION, data, &reply, TF_ONE_WAY);
583             EXPECT_EQ(NO_ERROR, ret);
584         }
585         {
586             Parcel data, reply;
587 
588             passiveclient[i] = addServer();
589             ASSERT_TRUE(passiveclient[i] != NULL);
590             data.writeStrongBinder(target);
591             ret = passiveclient[i]->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply, TF_ONE_WAY);
592             EXPECT_EQ(NO_ERROR, ret);
593         }
594     }
595     {
596         Parcel data, reply;
597         ret = target->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
598         EXPECT_EQ(0, ret);
599     }
600 
601     for (int i = 0; i < clientcount; i++) {
602         ret = callBack[i]->waitEvent(5);
603         EXPECT_EQ(NO_ERROR, ret);
604         ret = callBack[i]->getResult();
605         EXPECT_EQ(NO_ERROR, ret);
606     }
607 }
608 
TEST_F(BinderLibTest,PassFile)609 TEST_F(BinderLibTest, PassFile) {
610     int ret;
611     int pipefd[2];
612     uint8_t buf[1] = { 0 };
613     uint8_t write_value = 123;
614 
615     ret = pipe2(pipefd, O_NONBLOCK);
616     ASSERT_EQ(0, ret);
617 
618     {
619         Parcel data, reply;
620         uint8_t writebuf[1] = { write_value };
621 
622         ret = data.writeFileDescriptor(pipefd[1], true);
623         EXPECT_EQ(NO_ERROR, ret);
624 
625         ret = data.writeInt32(sizeof(writebuf));
626         EXPECT_EQ(NO_ERROR, ret);
627 
628         ret = data.write(writebuf, sizeof(writebuf));
629         EXPECT_EQ(NO_ERROR, ret);
630 
631         ret = m_server->transact(BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, data, &reply);
632         EXPECT_EQ(NO_ERROR, ret);
633     }
634 
635     ret = read(pipefd[0], buf, sizeof(buf));
636     EXPECT_EQ(sizeof(buf), ret);
637     EXPECT_EQ(write_value, buf[0]);
638 
639     waitForReadData(pipefd[0], 5000); /* wait for other proccess to close pipe */
640 
641     ret = read(pipefd[0], buf, sizeof(buf));
642     EXPECT_EQ(0, ret);
643 
644     close(pipefd[0]);
645 }
646 
TEST_F(BinderLibTest,PromoteLocal)647 TEST_F(BinderLibTest, PromoteLocal) {
648     sp<IBinder> strong = new BBinder();
649     wp<IBinder> weak = strong;
650     sp<IBinder> strong_from_weak = weak.promote();
651     EXPECT_TRUE(strong != NULL);
652     EXPECT_EQ(strong, strong_from_weak);
653     strong = NULL;
654     strong_from_weak = NULL;
655     strong_from_weak = weak.promote();
656     EXPECT_TRUE(strong_from_weak == NULL);
657 }
658 
TEST_F(BinderLibTest,PromoteRemote)659 TEST_F(BinderLibTest, PromoteRemote) {
660     int ret;
661     Parcel data, reply;
662     sp<IBinder> strong = new BBinder();
663     sp<IBinder> server = addServer();
664 
665     ASSERT_TRUE(server != NULL);
666     ASSERT_TRUE(strong != NULL);
667 
668     ret = data.writeWeakBinder(strong);
669     EXPECT_EQ(NO_ERROR, ret);
670 
671     ret = server->transact(BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION, data, &reply);
672     EXPECT_GE(ret, 0);
673 }
674 
675 class BinderLibTestService : public BBinder
676 {
677     public:
BinderLibTestService(int32_t id)678         BinderLibTestService(int32_t id)
679             : m_id(id)
680             , m_nextServerId(id + 1)
681             , m_serverStartRequested(false)
682         {
683             pthread_mutex_init(&m_serverWaitMutex, NULL);
684             pthread_cond_init(&m_serverWaitCond, NULL);
685         }
~BinderLibTestService()686         ~BinderLibTestService()
687         {
688             exit(EXIT_SUCCESS);
689         }
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)690         virtual status_t onTransact(uint32_t code,
691                                     const Parcel& data, Parcel* reply,
692                                     uint32_t flags = 0) {
693             //printf("%s: code %d\n", __func__, code);
694             (void)flags;
695 
696             if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
697                 return PERMISSION_DENIED;
698             }
699             switch (code) {
700             case BINDER_LIB_TEST_REGISTER_SERVER: {
701                 int32_t id;
702                 sp<IBinder> binder;
703                 id = data.readInt32();
704                 binder = data.readStrongBinder();
705                 if (binder == NULL) {
706                     return BAD_VALUE;
707                 }
708 
709                 if (m_id != 0)
710                     return INVALID_OPERATION;
711 
712                 pthread_mutex_lock(&m_serverWaitMutex);
713                 if (m_serverStartRequested) {
714                     m_serverStartRequested = false;
715                     m_serverStarted = binder;
716                     pthread_cond_signal(&m_serverWaitCond);
717                 }
718                 pthread_mutex_unlock(&m_serverWaitMutex);
719                 return NO_ERROR;
720             }
721             case BINDER_LIB_TEST_ADD_SERVER: {
722                 int ret;
723                 uint8_t buf[1] = { 0 };
724                 int serverid;
725 
726                 if (m_id != 0) {
727                     return INVALID_OPERATION;
728                 }
729                 pthread_mutex_lock(&m_serverWaitMutex);
730                 if (m_serverStartRequested) {
731                     ret = -EBUSY;
732                 } else {
733                     serverid = m_nextServerId++;
734                     m_serverStartRequested = true;
735 
736                     pthread_mutex_unlock(&m_serverWaitMutex);
737                     ret = start_server_process(serverid);
738                     pthread_mutex_lock(&m_serverWaitMutex);
739                 }
740                 if (ret > 0) {
741                     if (m_serverStartRequested) {
742 #if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
743                         ret = pthread_cond_timeout_np(&m_serverWaitCond, &m_serverWaitMutex, 5000);
744 #else
745                         struct timespec ts;
746                         clock_gettime(CLOCK_REALTIME, &ts);
747                         ts.tv_sec += 5;
748                         ret = pthread_cond_timedwait(&m_serverWaitCond, &m_serverWaitMutex, &ts);
749 #endif
750                     }
751                     if (m_serverStartRequested) {
752                         m_serverStartRequested = false;
753                         ret = -ETIMEDOUT;
754                     } else {
755                         reply->writeStrongBinder(m_serverStarted);
756                         reply->writeInt32(serverid);
757                         m_serverStarted = NULL;
758                         ret = NO_ERROR;
759                     }
760                 } else if (ret >= 0) {
761                     m_serverStartRequested = false;
762                     ret = UNKNOWN_ERROR;
763                 }
764                 pthread_mutex_unlock(&m_serverWaitMutex);
765                 return ret;
766             }
767             case BINDER_LIB_TEST_NOP_TRANSACTION:
768                 return NO_ERROR;
769             case BINDER_LIB_TEST_NOP_CALL_BACK: {
770                 Parcel data2, reply2;
771                 sp<IBinder> binder;
772                 binder = data.readStrongBinder();
773                 if (binder == NULL) {
774                     return BAD_VALUE;
775                 }
776                 reply2.writeInt32(NO_ERROR);
777                 binder->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
778                 return NO_ERROR;
779             }
780             case BINDER_LIB_TEST_GET_ID_TRANSACTION:
781                 reply->writeInt32(m_id);
782                 return NO_ERROR;
783             case BINDER_LIB_TEST_INDIRECT_TRANSACTION: {
784                 int32_t count;
785                 uint32_t indirect_code;
786                 sp<IBinder> binder;
787 
788                 count = data.readInt32();
789                 reply->writeInt32(m_id);
790                 reply->writeInt32(count);
791                 for (int i = 0; i < count; i++) {
792                     binder = data.readStrongBinder();
793                     if (binder == NULL) {
794                         return BAD_VALUE;
795                     }
796                     indirect_code = data.readInt32();
797                     BinderLibTestBundle data2(&data);
798                     if (!data2.isValid()) {
799                         return BAD_VALUE;
800                     }
801                     BinderLibTestBundle reply2;
802                     binder->transact(indirect_code, data2, &reply2);
803                     reply2.appendTo(reply);
804                 }
805                 return NO_ERROR;
806             }
807             case BINDER_LIB_TEST_SET_ERROR_TRANSACTION:
808                 reply->setError(data.readInt32());
809                 return NO_ERROR;
810             case BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION:
811                 reply->writeInt32(sizeof(void *));
812                 return NO_ERROR;
813             case BINDER_LIB_TEST_GET_STATUS_TRANSACTION:
814                 return NO_ERROR;
815             case BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION:
816                 m_strongRef = data.readStrongBinder();
817                 return NO_ERROR;
818             case BINDER_LIB_TEST_LINK_DEATH_TRANSACTION: {
819                 int ret;
820                 Parcel data2, reply2;
821                 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
822                 sp<IBinder> target;
823                 sp<IBinder> callback;
824 
825                 target = data.readStrongBinder();
826                 if (target == NULL) {
827                     return BAD_VALUE;
828                 }
829                 callback = data.readStrongBinder();
830                 if (callback == NULL) {
831                     return BAD_VALUE;
832                 }
833                 ret = target->linkToDeath(testDeathRecipient);
834                 if (ret == NO_ERROR)
835                     ret = testDeathRecipient->waitEvent(5);
836                 data2.writeInt32(ret);
837                 callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
838                 return NO_ERROR;
839             }
840             case BINDER_LIB_TEST_WRITE_FILE_TRANSACTION: {
841                 int ret;
842                 int32_t size;
843                 const void *buf;
844                 int fd;
845 
846                 fd = data.readFileDescriptor();
847                 if (fd < 0) {
848                     return BAD_VALUE;
849                 }
850                 ret = data.readInt32(&size);
851                 if (ret != NO_ERROR) {
852                     return ret;
853                 }
854                 buf = data.readInplace(size);
855                 if (buf == NULL) {
856                     return BAD_VALUE;
857                 }
858                 ret = write(fd, buf, size);
859                 if (ret != size)
860                     return UNKNOWN_ERROR;
861                 return NO_ERROR;
862             }
863             case BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION: {
864                 int ret;
865                 wp<IBinder> weak;
866                 sp<IBinder> strong;
867                 Parcel data2, reply2;
868                 sp<IServiceManager> sm = defaultServiceManager();
869                 sp<IBinder> server = sm->getService(binderLibTestServiceName);
870 
871                 weak = data.readWeakBinder();
872                 if (weak == NULL) {
873                     return BAD_VALUE;
874                 }
875                 strong = weak.promote();
876 
877                 ret = server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data2, &reply2);
878                 if (ret != NO_ERROR)
879                     exit(EXIT_FAILURE);
880 
881                 if (strong == NULL) {
882                     reply->setError(1);
883                 }
884                 return NO_ERROR;
885             }
886             case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION:
887                 alarm(10);
888                 return NO_ERROR;
889             case BINDER_LIB_TEST_EXIT_TRANSACTION:
890                 while (wait(NULL) != -1 || errno != ECHILD)
891                     ;
892                 exit(EXIT_SUCCESS);
893             default:
894                 return UNKNOWN_TRANSACTION;
895             };
896         }
897     private:
898         int32_t m_id;
899         int32_t m_nextServerId;
900         pthread_mutex_t m_serverWaitMutex;
901         pthread_cond_t m_serverWaitCond;
902         bool m_serverStartRequested;
903         sp<IBinder> m_serverStarted;
904         sp<IBinder> m_strongRef;
905 };
906 
run_server(int index,int readypipefd)907 int run_server(int index, int readypipefd)
908 {
909     status_t ret;
910     sp<IServiceManager> sm = defaultServiceManager();
911     {
912         sp<BinderLibTestService> testService = new BinderLibTestService(index);
913         if (index == 0) {
914             ret = sm->addService(binderLibTestServiceName, testService);
915         } else {
916             sp<IBinder> server = sm->getService(binderLibTestServiceName);
917             Parcel data, reply;
918             data.writeInt32(index);
919             data.writeStrongBinder(testService);
920 
921             ret = server->transact(BINDER_LIB_TEST_REGISTER_SERVER, data, &reply);
922         }
923     }
924     write(readypipefd, &ret, sizeof(ret));
925     close(readypipefd);
926     //printf("%s: ret %d\n", __func__, ret);
927     if (ret)
928         return 1;
929     //printf("%s: joinThreadPool\n", __func__);
930     ProcessState::self()->startThreadPool();
931     IPCThreadState::self()->joinThreadPool();
932     //printf("%s: joinThreadPool returned\n", __func__);
933     return 1; /* joinThreadPool should not return */
934 }
935 
main(int argc,char ** argv)936 int main(int argc, char **argv) {
937     int ret;
938 
939     if (argc == 3 && !strcmp(argv[1], "--servername")) {
940         binderservername = argv[2];
941     } else {
942         binderservername = argv[0];
943     }
944 
945     if (argc == 4 && !strcmp(argv[1], binderserverarg)) {
946         return run_server(atoi(argv[2]), atoi(argv[3]));
947     }
948 
949     ::testing::InitGoogleTest(&argc, argv);
950     binder_env = AddGlobalTestEnvironment(new BinderLibTestEnv());
951     ProcessState::self()->startThreadPool();
952     return RUN_ALL_TESTS();
953 }
954 
955