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
33using namespace android;
34
35static testing::Environment* binder_env;
36static char *binderservername;
37static char binderserverarg[] = "--binderserver";
38
39static String16 binderLibTestServiceName = String16("test.binderLib");
40
41enum 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
60pid_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
113class BinderLibTestEnv : public ::testing::Environment {
114    public:
115        BinderLibTestEnv() {}
116        sp<IBinder> getServer(void) {
117            return m_server;
118        }
119
120    private:
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        }
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
158class BinderLibTest : public ::testing::Test {
159    public:
160        virtual void SetUp() {
161            m_server = static_cast<BinderLibTestEnv *>(binder_env)->getServer();
162        }
163        virtual void TearDown() {
164        }
165    protected:
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        }
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
198class BinderLibTestBundle : public Parcel
199{
200    public:
201        BinderLibTestBundle(void) {}
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        }
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        };
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
241class BinderLibTestEvent
242{
243    public:
244        BinderLibTestEvent(void)
245            : m_eventTriggered(false)
246        {
247            pthread_mutex_init(&m_waitMutex, NULL);
248            pthread_cond_init(&m_waitCond, NULL);
249        }
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:
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
281class BinderLibTestCallBack : public BBinder, public BinderLibTestEvent
282{
283    public:
284        BinderLibTestCallBack()
285            : m_result(NOT_ENOUGH_DATA)
286        {
287        }
288        status_t getResult(void)
289        {
290            return m_result;
291        }
292
293    private:
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
313class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestEvent
314{
315    private:
316        virtual void binderDied(const wp<IBinder>& who) {
317            (void)who;
318            triggerEvent();
319        };
320};
321
322TEST_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
329TEST_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
340TEST_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
351TEST_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
365TEST_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
408TEST_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
472TEST_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
486TEST_F(BinderLibTest, AddServer)
487{
488    sp<IBinder> server = addServer();
489    ASSERT_TRUE(server != NULL);
490}
491
492TEST_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
513TEST_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
536TEST_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
562TEST_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
609TEST_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
647TEST_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
659TEST_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
675class BinderLibTestService : public BBinder
676{
677    public:
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        }
686        ~BinderLibTestService()
687        {
688            exit(EXIT_SUCCESS);
689        }
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
907int 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
936int 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