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 *binderserversuffix;
38static char binderserverarg[] = "--binderserver";
39
40static String16 binderLibTestServiceName = String16("test.binderLib");
41
42enum BinderLibTestTranscationCode {
43    BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
44    BINDER_LIB_TEST_REGISTER_SERVER,
45    BINDER_LIB_TEST_ADD_SERVER,
46    BINDER_LIB_TEST_CALL_BACK,
47    BINDER_LIB_TEST_NOP_CALL_BACK,
48    BINDER_LIB_TEST_GET_SELF_TRANSACTION,
49    BINDER_LIB_TEST_GET_ID_TRANSACTION,
50    BINDER_LIB_TEST_INDIRECT_TRANSACTION,
51    BINDER_LIB_TEST_SET_ERROR_TRANSACTION,
52    BINDER_LIB_TEST_GET_STATUS_TRANSACTION,
53    BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
54    BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
55    BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
56    BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION,
57    BINDER_LIB_TEST_EXIT_TRANSACTION,
58    BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
59    BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
60    BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION,
61};
62
63pid_t start_server_process(int arg2)
64{
65    int ret;
66    pid_t pid;
67    status_t status;
68    int pipefd[2];
69    char stri[16];
70    char strpipefd1[16];
71    char *childargv[] = {
72        binderservername,
73        binderserverarg,
74        stri,
75        strpipefd1,
76        binderserversuffix,
77        NULL
78    };
79
80    ret = pipe(pipefd);
81    if (ret < 0)
82        return ret;
83
84    snprintf(stri, sizeof(stri), "%d", arg2);
85    snprintf(strpipefd1, sizeof(strpipefd1), "%d", pipefd[1]);
86
87    pid = fork();
88    if (pid == -1)
89        return pid;
90    if (pid == 0) {
91        close(pipefd[0]);
92        execv(binderservername, childargv);
93        status = -errno;
94        write(pipefd[1], &status, sizeof(status));
95        fprintf(stderr, "execv failed, %s\n", strerror(errno));
96        _exit(EXIT_FAILURE);
97    }
98    close(pipefd[1]);
99    ret = read(pipefd[0], &status, sizeof(status));
100    //printf("pipe read returned %d, status %d\n", ret, status);
101    close(pipefd[0]);
102    if (ret == sizeof(status)) {
103        ret = status;
104    } else {
105        kill(pid, SIGKILL);
106        if (ret >= 0) {
107            ret = NO_INIT;
108        }
109    }
110    if (ret < 0) {
111        wait(NULL);
112        return ret;
113    }
114    return pid;
115}
116
117class BinderLibTestEnv : public ::testing::Environment {
118    public:
119        BinderLibTestEnv() {}
120        sp<IBinder> getServer(void) {
121            return m_server;
122        }
123
124    private:
125        virtual void SetUp() {
126            m_serverpid = start_server_process(0);
127            //printf("m_serverpid %d\n", m_serverpid);
128            ASSERT_GT(m_serverpid, 0);
129
130            sp<IServiceManager> sm = defaultServiceManager();
131            //printf("%s: pid %d, get service\n", __func__, m_pid);
132            m_server = sm->getService(binderLibTestServiceName);
133            ASSERT_TRUE(m_server != NULL);
134            //printf("%s: pid %d, get service done\n", __func__, m_pid);
135        }
136        virtual void TearDown() {
137            status_t ret;
138            Parcel data, reply;
139            int exitStatus;
140            pid_t pid;
141
142            //printf("%s: pid %d\n", __func__, m_pid);
143            if (m_server != NULL) {
144                ret = m_server->transact(BINDER_LIB_TEST_GET_STATUS_TRANSACTION, data, &reply);
145                EXPECT_EQ(0, ret);
146                ret = m_server->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
147                EXPECT_EQ(0, ret);
148            }
149            if (m_serverpid > 0) {
150                //printf("wait for %d\n", m_pids[i]);
151                pid = wait(&exitStatus);
152                EXPECT_EQ(m_serverpid, pid);
153                EXPECT_TRUE(WIFEXITED(exitStatus));
154                EXPECT_EQ(0, WEXITSTATUS(exitStatus));
155            }
156        }
157
158        pid_t m_serverpid;
159        sp<IBinder> m_server;
160};
161
162class BinderLibTest : public ::testing::Test {
163    public:
164        virtual void SetUp() {
165            m_server = static_cast<BinderLibTestEnv *>(binder_env)->getServer();
166        }
167        virtual void TearDown() {
168        }
169    protected:
170        sp<IBinder> addServer(int32_t *idPtr = NULL)
171        {
172            int ret;
173            int32_t id;
174            Parcel data, reply;
175            sp<IBinder> binder;
176
177            ret = m_server->transact(BINDER_LIB_TEST_ADD_SERVER, data, &reply);
178            EXPECT_EQ(NO_ERROR, ret);
179
180            EXPECT_FALSE(binder != NULL);
181            binder = reply.readStrongBinder();
182            EXPECT_TRUE(binder != NULL);
183            ret = reply.readInt32(&id);
184            EXPECT_EQ(NO_ERROR, ret);
185            if (idPtr)
186                *idPtr = id;
187            return binder;
188        }
189        void waitForReadData(int fd, int timeout_ms) {
190            int ret;
191            pollfd pfd = pollfd();
192
193            pfd.fd = fd;
194            pfd.events = POLLIN;
195            ret = poll(&pfd, 1, timeout_ms);
196            EXPECT_EQ(1, ret);
197        }
198
199        sp<IBinder> m_server;
200};
201
202class BinderLibTestBundle : public Parcel
203{
204    public:
205        BinderLibTestBundle(void) {}
206        BinderLibTestBundle(const Parcel *source) : m_isValid(false) {
207            int32_t mark;
208            int32_t bundleLen;
209            size_t pos;
210
211            if (source->readInt32(&mark))
212                return;
213            if (mark != MARK_START)
214                return;
215            if (source->readInt32(&bundleLen))
216                return;
217            pos = source->dataPosition();
218            if (Parcel::appendFrom(source, pos, bundleLen))
219                return;
220            source->setDataPosition(pos + bundleLen);
221            if (source->readInt32(&mark))
222                return;
223            if (mark != MARK_END)
224                return;
225            m_isValid = true;
226            setDataPosition(0);
227        }
228        void appendTo(Parcel *dest) {
229            dest->writeInt32(MARK_START);
230            dest->writeInt32(dataSize());
231            dest->appendFrom(this, 0, dataSize());
232            dest->writeInt32(MARK_END);
233        };
234        bool isValid(void) {
235            return m_isValid;
236        }
237    private:
238        enum {
239            MARK_START  = B_PACK_CHARS('B','T','B','S'),
240            MARK_END    = B_PACK_CHARS('B','T','B','E'),
241        };
242        bool m_isValid;
243};
244
245class BinderLibTestEvent
246{
247    public:
248        BinderLibTestEvent(void)
249            : m_eventTriggered(false)
250        {
251            pthread_mutex_init(&m_waitMutex, NULL);
252            pthread_cond_init(&m_waitCond, NULL);
253        }
254        int waitEvent(int timeout_s)
255        {
256            int ret;
257            pthread_mutex_lock(&m_waitMutex);
258            if (!m_eventTriggered) {
259                struct timespec ts;
260                clock_gettime(CLOCK_REALTIME, &ts);
261                ts.tv_sec += timeout_s;
262                pthread_cond_timedwait(&m_waitCond, &m_waitMutex, &ts);
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), (size_t)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), (size_t)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), (size_t)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
675TEST_F(BinderLibTest, CheckHandleZeroBinderHighBitsZeroCookie) {
676    status_t ret;
677    Parcel data, reply;
678
679    ret = m_server->transact(BINDER_LIB_TEST_GET_SELF_TRANSACTION, data, &reply);
680    EXPECT_EQ(NO_ERROR, ret);
681
682    const flat_binder_object *fb = reply.readObject(false);
683    ASSERT_TRUE(fb != NULL);
684    EXPECT_EQ(fb->type, BINDER_TYPE_HANDLE);
685    EXPECT_EQ(ProcessState::self()->getStrongProxyForHandle(fb->handle), m_server);
686    EXPECT_EQ(fb->cookie, (binder_uintptr_t)0);
687    EXPECT_EQ(fb->binder >> 32, (binder_uintptr_t)0);
688}
689
690TEST_F(BinderLibTest, FreedBinder) {
691    status_t ret;
692
693    sp<IBinder> server = addServer();
694    ASSERT_TRUE(server != NULL);
695
696    __u32 freedHandle;
697    wp<IBinder> keepFreedBinder;
698    {
699        Parcel data, reply;
700        data.writeBool(false); /* request weak reference */
701        ret = server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, data, &reply);
702        ASSERT_EQ(NO_ERROR, ret);
703        struct flat_binder_object *freed = (struct flat_binder_object *)(reply.data());
704        freedHandle = freed->handle;
705        /* Add a weak ref to the freed binder so the driver does not
706         * delete its reference to it - otherwise the transaction
707         * fails regardless of whether the driver is fixed.
708         */
709        keepFreedBinder = reply.readWeakBinder();
710    }
711    {
712        Parcel data, reply;
713        data.writeStrongBinder(server);
714        /* Replace original handle with handle to the freed binder */
715        struct flat_binder_object *strong = (struct flat_binder_object *)(data.data());
716        __u32 oldHandle = strong->handle;
717        strong->handle = freedHandle;
718        ret = server->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply);
719        /* Returns DEAD_OBJECT (-32) if target crashes and
720         * FAILED_TRANSACTION if the driver rejects the invalid
721         * object.
722         */
723        EXPECT_EQ((status_t)FAILED_TRANSACTION, ret);
724        /* Restore original handle so parcel destructor does not use
725         * the wrong handle.
726         */
727        strong->handle = oldHandle;
728    }
729}
730
731class BinderLibTestService : public BBinder
732{
733    public:
734        BinderLibTestService(int32_t id)
735            : m_id(id)
736            , m_nextServerId(id + 1)
737            , m_serverStartRequested(false)
738        {
739            pthread_mutex_init(&m_serverWaitMutex, NULL);
740            pthread_cond_init(&m_serverWaitCond, NULL);
741        }
742        ~BinderLibTestService()
743        {
744            exit(EXIT_SUCCESS);
745        }
746        virtual status_t onTransact(uint32_t code,
747                                    const Parcel& data, Parcel* reply,
748                                    uint32_t flags = 0) {
749            //printf("%s: code %d\n", __func__, code);
750            (void)flags;
751
752            if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
753                return PERMISSION_DENIED;
754            }
755            switch (code) {
756            case BINDER_LIB_TEST_REGISTER_SERVER: {
757                int32_t id;
758                sp<IBinder> binder;
759                id = data.readInt32();
760                binder = data.readStrongBinder();
761                if (binder == NULL) {
762                    return BAD_VALUE;
763                }
764
765                if (m_id != 0)
766                    return INVALID_OPERATION;
767
768                pthread_mutex_lock(&m_serverWaitMutex);
769                if (m_serverStartRequested) {
770                    m_serverStartRequested = false;
771                    m_serverStarted = binder;
772                    pthread_cond_signal(&m_serverWaitCond);
773                }
774                pthread_mutex_unlock(&m_serverWaitMutex);
775                return NO_ERROR;
776            }
777            case BINDER_LIB_TEST_ADD_SERVER: {
778                int ret;
779                uint8_t buf[1] = { 0 };
780                int serverid;
781
782                if (m_id != 0) {
783                    return INVALID_OPERATION;
784                }
785                pthread_mutex_lock(&m_serverWaitMutex);
786                if (m_serverStartRequested) {
787                    ret = -EBUSY;
788                } else {
789                    serverid = m_nextServerId++;
790                    m_serverStartRequested = true;
791
792                    pthread_mutex_unlock(&m_serverWaitMutex);
793                    ret = start_server_process(serverid);
794                    pthread_mutex_lock(&m_serverWaitMutex);
795                }
796                if (ret > 0) {
797                    if (m_serverStartRequested) {
798                        struct timespec ts;
799                        clock_gettime(CLOCK_REALTIME, &ts);
800                        ts.tv_sec += 5;
801                        ret = pthread_cond_timedwait(&m_serverWaitCond, &m_serverWaitMutex, &ts);
802                    }
803                    if (m_serverStartRequested) {
804                        m_serverStartRequested = false;
805                        ret = -ETIMEDOUT;
806                    } else {
807                        reply->writeStrongBinder(m_serverStarted);
808                        reply->writeInt32(serverid);
809                        m_serverStarted = NULL;
810                        ret = NO_ERROR;
811                    }
812                } else if (ret >= 0) {
813                    m_serverStartRequested = false;
814                    ret = UNKNOWN_ERROR;
815                }
816                pthread_mutex_unlock(&m_serverWaitMutex);
817                return ret;
818            }
819            case BINDER_LIB_TEST_NOP_TRANSACTION:
820                return NO_ERROR;
821            case BINDER_LIB_TEST_NOP_CALL_BACK: {
822                Parcel data2, reply2;
823                sp<IBinder> binder;
824                binder = data.readStrongBinder();
825                if (binder == NULL) {
826                    return BAD_VALUE;
827                }
828                reply2.writeInt32(NO_ERROR);
829                binder->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
830                return NO_ERROR;
831            }
832            case BINDER_LIB_TEST_GET_SELF_TRANSACTION:
833                reply->writeStrongBinder(this);
834                return NO_ERROR;
835            case BINDER_LIB_TEST_GET_ID_TRANSACTION:
836                reply->writeInt32(m_id);
837                return NO_ERROR;
838            case BINDER_LIB_TEST_INDIRECT_TRANSACTION: {
839                int32_t count;
840                uint32_t indirect_code;
841                sp<IBinder> binder;
842
843                count = data.readInt32();
844                reply->writeInt32(m_id);
845                reply->writeInt32(count);
846                for (int i = 0; i < count; i++) {
847                    binder = data.readStrongBinder();
848                    if (binder == NULL) {
849                        return BAD_VALUE;
850                    }
851                    indirect_code = data.readInt32();
852                    BinderLibTestBundle data2(&data);
853                    if (!data2.isValid()) {
854                        return BAD_VALUE;
855                    }
856                    BinderLibTestBundle reply2;
857                    binder->transact(indirect_code, data2, &reply2);
858                    reply2.appendTo(reply);
859                }
860                return NO_ERROR;
861            }
862            case BINDER_LIB_TEST_SET_ERROR_TRANSACTION:
863                reply->setError(data.readInt32());
864                return NO_ERROR;
865            case BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION:
866                reply->writeInt32(sizeof(void *));
867                return NO_ERROR;
868            case BINDER_LIB_TEST_GET_STATUS_TRANSACTION:
869                return NO_ERROR;
870            case BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION:
871                m_strongRef = data.readStrongBinder();
872                return NO_ERROR;
873            case BINDER_LIB_TEST_LINK_DEATH_TRANSACTION: {
874                int ret;
875                Parcel data2, reply2;
876                sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
877                sp<IBinder> target;
878                sp<IBinder> callback;
879
880                target = data.readStrongBinder();
881                if (target == NULL) {
882                    return BAD_VALUE;
883                }
884                callback = data.readStrongBinder();
885                if (callback == NULL) {
886                    return BAD_VALUE;
887                }
888                ret = target->linkToDeath(testDeathRecipient);
889                if (ret == NO_ERROR)
890                    ret = testDeathRecipient->waitEvent(5);
891                data2.writeInt32(ret);
892                callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
893                return NO_ERROR;
894            }
895            case BINDER_LIB_TEST_WRITE_FILE_TRANSACTION: {
896                int ret;
897                int32_t size;
898                const void *buf;
899                int fd;
900
901                fd = data.readFileDescriptor();
902                if (fd < 0) {
903                    return BAD_VALUE;
904                }
905                ret = data.readInt32(&size);
906                if (ret != NO_ERROR) {
907                    return ret;
908                }
909                buf = data.readInplace(size);
910                if (buf == NULL) {
911                    return BAD_VALUE;
912                }
913                ret = write(fd, buf, size);
914                if (ret != size)
915                    return UNKNOWN_ERROR;
916                return NO_ERROR;
917            }
918            case BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION: {
919                int ret;
920                wp<IBinder> weak;
921                sp<IBinder> strong;
922                Parcel data2, reply2;
923                sp<IServiceManager> sm = defaultServiceManager();
924                sp<IBinder> server = sm->getService(binderLibTestServiceName);
925
926                weak = data.readWeakBinder();
927                if (weak == NULL) {
928                    return BAD_VALUE;
929                }
930                strong = weak.promote();
931
932                ret = server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data2, &reply2);
933                if (ret != NO_ERROR)
934                    exit(EXIT_FAILURE);
935
936                if (strong == NULL) {
937                    reply->setError(1);
938                }
939                return NO_ERROR;
940            }
941            case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION:
942                alarm(10);
943                return NO_ERROR;
944            case BINDER_LIB_TEST_EXIT_TRANSACTION:
945                while (wait(NULL) != -1 || errno != ECHILD)
946                    ;
947                exit(EXIT_SUCCESS);
948            case BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION: {
949                bool strongRef = data.readBool();
950                sp<IBinder> binder = new BBinder();
951                if (strongRef) {
952                    reply->writeStrongBinder(binder);
953                } else {
954                    reply->writeWeakBinder(binder);
955                }
956                return NO_ERROR;
957            }
958            default:
959                return UNKNOWN_TRANSACTION;
960            };
961        }
962    private:
963        int32_t m_id;
964        int32_t m_nextServerId;
965        pthread_mutex_t m_serverWaitMutex;
966        pthread_cond_t m_serverWaitCond;
967        bool m_serverStartRequested;
968        sp<IBinder> m_serverStarted;
969        sp<IBinder> m_strongRef;
970};
971
972int run_server(int index, int readypipefd)
973{
974    binderLibTestServiceName += String16(binderserversuffix);
975
976    status_t ret;
977    sp<IServiceManager> sm = defaultServiceManager();
978    {
979        sp<BinderLibTestService> testService = new BinderLibTestService(index);
980        if (index == 0) {
981            ret = sm->addService(binderLibTestServiceName, testService);
982        } else {
983            sp<IBinder> server = sm->getService(binderLibTestServiceName);
984            Parcel data, reply;
985            data.writeInt32(index);
986            data.writeStrongBinder(testService);
987
988            ret = server->transact(BINDER_LIB_TEST_REGISTER_SERVER, data, &reply);
989        }
990    }
991    write(readypipefd, &ret, sizeof(ret));
992    close(readypipefd);
993    //printf("%s: ret %d\n", __func__, ret);
994    if (ret)
995        return 1;
996    //printf("%s: joinThreadPool\n", __func__);
997    ProcessState::self()->startThreadPool();
998    IPCThreadState::self()->joinThreadPool();
999    //printf("%s: joinThreadPool returned\n", __func__);
1000    return 1; /* joinThreadPool should not return */
1001}
1002
1003int main(int argc, char **argv) {
1004    int ret;
1005
1006    if (argc == 4 && !strcmp(argv[1], "--servername")) {
1007        binderservername = argv[2];
1008    } else {
1009        binderservername = argv[0];
1010    }
1011
1012    if (argc == 5 && !strcmp(argv[1], binderserverarg)) {
1013        binderserversuffix = argv[4];
1014        return run_server(atoi(argv[2]), atoi(argv[3]));
1015    }
1016    binderserversuffix = new char[16];
1017    snprintf(binderserversuffix, 16, "%d", getpid());
1018    binderLibTestServiceName += String16(binderserversuffix);
1019
1020    ::testing::InitGoogleTest(&argc, argv);
1021    binder_env = AddGlobalTestEnvironment(new BinderLibTestEnv());
1022    ProcessState::self()->startThreadPool();
1023    return RUN_ALL_TESTS();
1024}
1025
1026