blob: 17479ca77e6234aed0a6f446ec11c0b8795a4ed4 [file] [log] [blame]
Riley Andrews06b01ad2014-12-18 12:10:08 -08001/*
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) {
Riley Andrews06b01ad2014-12-18 12:10:08 -0800255 struct timespec ts;
256 clock_gettime(CLOCK_REALTIME, &ts);
257 ts.tv_sec += timeout_s;
258 pthread_cond_timedwait(&m_waitCond, &m_waitMutex, &ts);
Riley Andrews06b01ad2014-12-18 12:10:08 -0800259 }
260 ret = m_eventTriggered ? NO_ERROR : TIMED_OUT;
261 pthread_mutex_unlock(&m_waitMutex);
262 return ret;
263 }
264 protected:
265 void triggerEvent(void) {
266 pthread_mutex_lock(&m_waitMutex);
267 pthread_cond_signal(&m_waitCond);
268 m_eventTriggered = true;
269 pthread_mutex_unlock(&m_waitMutex);
270 };
271 private:
272 pthread_mutex_t m_waitMutex;
273 pthread_cond_t m_waitCond;
274 bool m_eventTriggered;
275};
276
277class BinderLibTestCallBack : public BBinder, public BinderLibTestEvent
278{
279 public:
280 BinderLibTestCallBack()
281 : m_result(NOT_ENOUGH_DATA)
282 {
283 }
284 status_t getResult(void)
285 {
286 return m_result;
287 }
288
289 private:
290 virtual status_t onTransact(uint32_t code,
291 const Parcel& data, Parcel* reply,
292 uint32_t flags = 0)
293 {
294 (void)reply;
295 (void)flags;
296 switch(code) {
297 case BINDER_LIB_TEST_CALL_BACK:
298 m_result = data.readInt32();
299 triggerEvent();
300 return NO_ERROR;
301 default:
302 return UNKNOWN_TRANSACTION;
303 }
304 }
305
306 status_t m_result;
307};
308
309class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestEvent
310{
311 private:
312 virtual void binderDied(const wp<IBinder>& who) {
313 (void)who;
314 triggerEvent();
315 };
316};
317
318TEST_F(BinderLibTest, NopTransaction) {
319 status_t ret;
320 Parcel data, reply;
321 ret = m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply);
322 EXPECT_EQ(NO_ERROR, ret);
323}
324
325TEST_F(BinderLibTest, SetError) {
326 int32_t testValue[] = { 0, -123, 123 };
327 for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) {
328 status_t ret;
329 Parcel data, reply;
330 data.writeInt32(testValue[i]);
331 ret = m_server->transact(BINDER_LIB_TEST_SET_ERROR_TRANSACTION, data, &reply);
332 EXPECT_EQ(testValue[i], ret);
333 }
334}
335
336TEST_F(BinderLibTest, GetId) {
337 status_t ret;
338 int32_t id;
339 Parcel data, reply;
340 ret = m_server->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply);
341 EXPECT_EQ(NO_ERROR, ret);
342 ret = reply.readInt32(&id);
343 EXPECT_EQ(NO_ERROR, ret);
344 EXPECT_EQ(0, id);
345}
346
347TEST_F(BinderLibTest, PtrSize) {
348 status_t ret;
349 int32_t ptrsize;
350 Parcel data, reply;
351 sp<IBinder> server = addServer();
352 ASSERT_TRUE(server != NULL);
353 ret = server->transact(BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, data, &reply);
354 EXPECT_EQ(NO_ERROR, ret);
355 ret = reply.readInt32(&ptrsize);
356 EXPECT_EQ(NO_ERROR, ret);
357 RecordProperty("TestPtrSize", sizeof(void *));
358 RecordProperty("ServerPtrSize", sizeof(void *));
359}
360
361TEST_F(BinderLibTest, IndirectGetId2)
362{
363 status_t ret;
364 int32_t id;
365 int32_t count;
366 Parcel data, reply;
367 int32_t serverId[3];
368
369 data.writeInt32(ARRAY_SIZE(serverId));
370 for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
371 sp<IBinder> server;
372 BinderLibTestBundle datai;
373
374 server = addServer(&serverId[i]);
375 ASSERT_TRUE(server != NULL);
376 data.writeStrongBinder(server);
377 data.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
378 datai.appendTo(&data);
379 }
380
381 ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
382 ASSERT_EQ(NO_ERROR, ret);
383
384 ret = reply.readInt32(&id);
385 ASSERT_EQ(NO_ERROR, ret);
386 EXPECT_EQ(0, id);
387
388 ret = reply.readInt32(&count);
389 ASSERT_EQ(NO_ERROR, ret);
390 EXPECT_EQ(ARRAY_SIZE(serverId), count);
391
392 for (size_t i = 0; i < (size_t)count; i++) {
393 BinderLibTestBundle replyi(&reply);
394 EXPECT_TRUE(replyi.isValid());
395 ret = replyi.readInt32(&id);
396 EXPECT_EQ(NO_ERROR, ret);
397 EXPECT_EQ(serverId[i], id);
398 EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
399 }
400
401 EXPECT_EQ(reply.dataSize(), reply.dataPosition());
402}
403
404TEST_F(BinderLibTest, IndirectGetId3)
405{
406 status_t ret;
407 int32_t id;
408 int32_t count;
409 Parcel data, reply;
410 int32_t serverId[3];
411
412 data.writeInt32(ARRAY_SIZE(serverId));
413 for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
414 sp<IBinder> server;
415 BinderLibTestBundle datai;
416 BinderLibTestBundle datai2;
417
418 server = addServer(&serverId[i]);
419 ASSERT_TRUE(server != NULL);
420 data.writeStrongBinder(server);
421 data.writeInt32(BINDER_LIB_TEST_INDIRECT_TRANSACTION);
422
423 datai.writeInt32(1);
424 datai.writeStrongBinder(m_server);
425 datai.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
426 datai2.appendTo(&datai);
427
428 datai.appendTo(&data);
429 }
430
431 ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
432 ASSERT_EQ(NO_ERROR, ret);
433
434 ret = reply.readInt32(&id);
435 ASSERT_EQ(NO_ERROR, ret);
436 EXPECT_EQ(0, id);
437
438 ret = reply.readInt32(&count);
439 ASSERT_EQ(NO_ERROR, ret);
440 EXPECT_EQ(ARRAY_SIZE(serverId), count);
441
442 for (size_t i = 0; i < (size_t)count; i++) {
443 int32_t counti;
444
445 BinderLibTestBundle replyi(&reply);
446 EXPECT_TRUE(replyi.isValid());
447 ret = replyi.readInt32(&id);
448 EXPECT_EQ(NO_ERROR, ret);
449 EXPECT_EQ(serverId[i], id);
450
451 ret = replyi.readInt32(&counti);
452 ASSERT_EQ(NO_ERROR, ret);
453 EXPECT_EQ(1, counti);
454
455 BinderLibTestBundle replyi2(&replyi);
456 EXPECT_TRUE(replyi2.isValid());
457 ret = replyi2.readInt32(&id);
458 EXPECT_EQ(NO_ERROR, ret);
459 EXPECT_EQ(0, id);
460 EXPECT_EQ(replyi2.dataSize(), replyi2.dataPosition());
461
462 EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
463 }
464
465 EXPECT_EQ(reply.dataSize(), reply.dataPosition());
466}
467
468TEST_F(BinderLibTest, CallBack)
469{
470 status_t ret;
471 Parcel data, reply;
472 sp<BinderLibTestCallBack> callBack = new BinderLibTestCallBack();
473 data.writeStrongBinder(callBack);
474 ret = m_server->transact(BINDER_LIB_TEST_NOP_CALL_BACK, data, &reply, TF_ONE_WAY);
475 EXPECT_EQ(NO_ERROR, ret);
476 ret = callBack->waitEvent(5);
477 EXPECT_EQ(NO_ERROR, ret);
478 ret = callBack->getResult();
479 EXPECT_EQ(NO_ERROR, ret);
480}
481
482TEST_F(BinderLibTest, AddServer)
483{
484 sp<IBinder> server = addServer();
485 ASSERT_TRUE(server != NULL);
486}
487
488TEST_F(BinderLibTest, DeathNotificationNoRefs)
489{
490 status_t ret;
491
492 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
493
494 {
495 sp<IBinder> binder = addServer();
496 ASSERT_TRUE(binder != NULL);
497 ret = binder->linkToDeath(testDeathRecipient);
498 EXPECT_EQ(NO_ERROR, ret);
499 }
500 IPCThreadState::self()->flushCommands();
501 ret = testDeathRecipient->waitEvent(5);
502 EXPECT_EQ(NO_ERROR, ret);
503#if 0 /* Is there an unlink api that does not require a strong reference? */
504 ret = binder->unlinkToDeath(testDeathRecipient);
505 EXPECT_EQ(NO_ERROR, ret);
506#endif
507}
508
509TEST_F(BinderLibTest, DeathNotificationWeakRef)
510{
511 status_t ret;
512 wp<IBinder> wbinder;
513
514 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
515
516 {
517 sp<IBinder> binder = addServer();
518 ASSERT_TRUE(binder != NULL);
519 ret = binder->linkToDeath(testDeathRecipient);
520 EXPECT_EQ(NO_ERROR, ret);
521 wbinder = binder;
522 }
523 IPCThreadState::self()->flushCommands();
524 ret = testDeathRecipient->waitEvent(5);
525 EXPECT_EQ(NO_ERROR, ret);
526#if 0 /* Is there an unlink api that does not require a strong reference? */
527 ret = binder->unlinkToDeath(testDeathRecipient);
528 EXPECT_EQ(NO_ERROR, ret);
529#endif
530}
531
532TEST_F(BinderLibTest, DeathNotificationStrongRef)
533{
534 status_t ret;
535 sp<IBinder> sbinder;
536
537 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
538
539 {
540 sp<IBinder> binder = addServer();
541 ASSERT_TRUE(binder != NULL);
542 ret = binder->linkToDeath(testDeathRecipient);
543 EXPECT_EQ(NO_ERROR, ret);
544 sbinder = binder;
545 }
546 {
547 Parcel data, reply;
548 ret = sbinder->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
549 EXPECT_EQ(0, ret);
550 }
551 IPCThreadState::self()->flushCommands();
552 ret = testDeathRecipient->waitEvent(5);
553 EXPECT_EQ(NO_ERROR, ret);
554 ret = sbinder->unlinkToDeath(testDeathRecipient);
555 EXPECT_EQ(DEAD_OBJECT, ret);
556}
557
558TEST_F(BinderLibTest, DeathNotificationMultiple)
559{
560 status_t ret;
561 const int clientcount = 2;
562 sp<IBinder> target;
563 sp<IBinder> linkedclient[clientcount];
564 sp<BinderLibTestCallBack> callBack[clientcount];
565 sp<IBinder> passiveclient[clientcount];
566
567 target = addServer();
568 ASSERT_TRUE(target != NULL);
569 for (int i = 0; i < clientcount; i++) {
570 {
571 Parcel data, reply;
572
573 linkedclient[i] = addServer();
574 ASSERT_TRUE(linkedclient[i] != NULL);
575 callBack[i] = new BinderLibTestCallBack();
576 data.writeStrongBinder(target);
577 data.writeStrongBinder(callBack[i]);
578 ret = linkedclient[i]->transact(BINDER_LIB_TEST_LINK_DEATH_TRANSACTION, data, &reply, TF_ONE_WAY);
579 EXPECT_EQ(NO_ERROR, ret);
580 }
581 {
582 Parcel data, reply;
583
584 passiveclient[i] = addServer();
585 ASSERT_TRUE(passiveclient[i] != NULL);
586 data.writeStrongBinder(target);
587 ret = passiveclient[i]->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply, TF_ONE_WAY);
588 EXPECT_EQ(NO_ERROR, ret);
589 }
590 }
591 {
592 Parcel data, reply;
593 ret = target->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
594 EXPECT_EQ(0, ret);
595 }
596
597 for (int i = 0; i < clientcount; i++) {
598 ret = callBack[i]->waitEvent(5);
599 EXPECT_EQ(NO_ERROR, ret);
600 ret = callBack[i]->getResult();
601 EXPECT_EQ(NO_ERROR, ret);
602 }
603}
604
605TEST_F(BinderLibTest, PassFile) {
606 int ret;
607 int pipefd[2];
608 uint8_t buf[1] = { 0 };
609 uint8_t write_value = 123;
610
611 ret = pipe2(pipefd, O_NONBLOCK);
612 ASSERT_EQ(0, ret);
613
614 {
615 Parcel data, reply;
616 uint8_t writebuf[1] = { write_value };
617
618 ret = data.writeFileDescriptor(pipefd[1], true);
619 EXPECT_EQ(NO_ERROR, ret);
620
621 ret = data.writeInt32(sizeof(writebuf));
622 EXPECT_EQ(NO_ERROR, ret);
623
624 ret = data.write(writebuf, sizeof(writebuf));
625 EXPECT_EQ(NO_ERROR, ret);
626
627 ret = m_server->transact(BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, data, &reply);
628 EXPECT_EQ(NO_ERROR, ret);
629 }
630
631 ret = read(pipefd[0], buf, sizeof(buf));
632 EXPECT_EQ(sizeof(buf), ret);
633 EXPECT_EQ(write_value, buf[0]);
634
635 waitForReadData(pipefd[0], 5000); /* wait for other proccess to close pipe */
636
637 ret = read(pipefd[0], buf, sizeof(buf));
638 EXPECT_EQ(0, ret);
639
640 close(pipefd[0]);
641}
642
643TEST_F(BinderLibTest, PromoteLocal) {
644 sp<IBinder> strong = new BBinder();
645 wp<IBinder> weak = strong;
646 sp<IBinder> strong_from_weak = weak.promote();
647 EXPECT_TRUE(strong != NULL);
648 EXPECT_EQ(strong, strong_from_weak);
649 strong = NULL;
650 strong_from_weak = NULL;
651 strong_from_weak = weak.promote();
652 EXPECT_TRUE(strong_from_weak == NULL);
653}
654
655TEST_F(BinderLibTest, PromoteRemote) {
656 int ret;
657 Parcel data, reply;
658 sp<IBinder> strong = new BBinder();
659 sp<IBinder> server = addServer();
660
661 ASSERT_TRUE(server != NULL);
662 ASSERT_TRUE(strong != NULL);
663
664 ret = data.writeWeakBinder(strong);
665 EXPECT_EQ(NO_ERROR, ret);
666
667 ret = server->transact(BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION, data, &reply);
668 EXPECT_GE(ret, 0);
669}
670
671class BinderLibTestService : public BBinder
672{
673 public:
674 BinderLibTestService(int32_t id)
675 : m_id(id)
676 , m_nextServerId(id + 1)
677 , m_serverStartRequested(false)
678 {
679 pthread_mutex_init(&m_serverWaitMutex, NULL);
680 pthread_cond_init(&m_serverWaitCond, NULL);
681 }
682 ~BinderLibTestService()
683 {
684 exit(EXIT_SUCCESS);
685 }
686 virtual status_t onTransact(uint32_t code,
687 const Parcel& data, Parcel* reply,
688 uint32_t flags = 0) {
689 //printf("%s: code %d\n", __func__, code);
690 (void)flags;
691
692 if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
693 return PERMISSION_DENIED;
694 }
695 switch (code) {
696 case BINDER_LIB_TEST_REGISTER_SERVER: {
697 int32_t id;
698 sp<IBinder> binder;
699 id = data.readInt32();
700 binder = data.readStrongBinder();
701 if (binder == NULL) {
702 return BAD_VALUE;
703 }
704
705 if (m_id != 0)
706 return INVALID_OPERATION;
707
708 pthread_mutex_lock(&m_serverWaitMutex);
709 if (m_serverStartRequested) {
710 m_serverStartRequested = false;
711 m_serverStarted = binder;
712 pthread_cond_signal(&m_serverWaitCond);
713 }
714 pthread_mutex_unlock(&m_serverWaitMutex);
715 return NO_ERROR;
716 }
717 case BINDER_LIB_TEST_ADD_SERVER: {
718 int ret;
719 uint8_t buf[1] = { 0 };
720 int serverid;
721
722 if (m_id != 0) {
723 return INVALID_OPERATION;
724 }
725 pthread_mutex_lock(&m_serverWaitMutex);
726 if (m_serverStartRequested) {
727 ret = -EBUSY;
728 } else {
729 serverid = m_nextServerId++;
730 m_serverStartRequested = true;
731
732 pthread_mutex_unlock(&m_serverWaitMutex);
733 ret = start_server_process(serverid);
734 pthread_mutex_lock(&m_serverWaitMutex);
735 }
736 if (ret > 0) {
737 if (m_serverStartRequested) {
Riley Andrews06b01ad2014-12-18 12:10:08 -0800738 struct timespec ts;
739 clock_gettime(CLOCK_REALTIME, &ts);
740 ts.tv_sec += 5;
741 ret = pthread_cond_timedwait(&m_serverWaitCond, &m_serverWaitMutex, &ts);
Riley Andrews06b01ad2014-12-18 12:10:08 -0800742 }
743 if (m_serverStartRequested) {
744 m_serverStartRequested = false;
745 ret = -ETIMEDOUT;
746 } else {
747 reply->writeStrongBinder(m_serverStarted);
748 reply->writeInt32(serverid);
749 m_serverStarted = NULL;
750 ret = NO_ERROR;
751 }
752 } else if (ret >= 0) {
753 m_serverStartRequested = false;
754 ret = UNKNOWN_ERROR;
755 }
756 pthread_mutex_unlock(&m_serverWaitMutex);
757 return ret;
758 }
759 case BINDER_LIB_TEST_NOP_TRANSACTION:
760 return NO_ERROR;
761 case BINDER_LIB_TEST_NOP_CALL_BACK: {
762 Parcel data2, reply2;
763 sp<IBinder> binder;
764 binder = data.readStrongBinder();
765 if (binder == NULL) {
766 return BAD_VALUE;
767 }
768 reply2.writeInt32(NO_ERROR);
769 binder->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
770 return NO_ERROR;
771 }
772 case BINDER_LIB_TEST_GET_ID_TRANSACTION:
773 reply->writeInt32(m_id);
774 return NO_ERROR;
775 case BINDER_LIB_TEST_INDIRECT_TRANSACTION: {
776 int32_t count;
777 uint32_t indirect_code;
778 sp<IBinder> binder;
779
780 count = data.readInt32();
781 reply->writeInt32(m_id);
782 reply->writeInt32(count);
783 for (int i = 0; i < count; i++) {
784 binder = data.readStrongBinder();
785 if (binder == NULL) {
786 return BAD_VALUE;
787 }
788 indirect_code = data.readInt32();
789 BinderLibTestBundle data2(&data);
790 if (!data2.isValid()) {
791 return BAD_VALUE;
792 }
793 BinderLibTestBundle reply2;
794 binder->transact(indirect_code, data2, &reply2);
795 reply2.appendTo(reply);
796 }
797 return NO_ERROR;
798 }
799 case BINDER_LIB_TEST_SET_ERROR_TRANSACTION:
800 reply->setError(data.readInt32());
801 return NO_ERROR;
802 case BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION:
803 reply->writeInt32(sizeof(void *));
804 return NO_ERROR;
805 case BINDER_LIB_TEST_GET_STATUS_TRANSACTION:
806 return NO_ERROR;
807 case BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION:
808 m_strongRef = data.readStrongBinder();
809 return NO_ERROR;
810 case BINDER_LIB_TEST_LINK_DEATH_TRANSACTION: {
811 int ret;
812 Parcel data2, reply2;
813 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
814 sp<IBinder> target;
815 sp<IBinder> callback;
816
817 target = data.readStrongBinder();
818 if (target == NULL) {
819 return BAD_VALUE;
820 }
821 callback = data.readStrongBinder();
822 if (callback == NULL) {
823 return BAD_VALUE;
824 }
825 ret = target->linkToDeath(testDeathRecipient);
826 if (ret == NO_ERROR)
827 ret = testDeathRecipient->waitEvent(5);
828 data2.writeInt32(ret);
829 callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
830 return NO_ERROR;
831 }
832 case BINDER_LIB_TEST_WRITE_FILE_TRANSACTION: {
833 int ret;
834 int32_t size;
835 const void *buf;
836 int fd;
837
838 fd = data.readFileDescriptor();
839 if (fd < 0) {
840 return BAD_VALUE;
841 }
842 ret = data.readInt32(&size);
843 if (ret != NO_ERROR) {
844 return ret;
845 }
846 buf = data.readInplace(size);
847 if (buf == NULL) {
848 return BAD_VALUE;
849 }
850 ret = write(fd, buf, size);
851 if (ret != size)
852 return UNKNOWN_ERROR;
853 return NO_ERROR;
854 }
855 case BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION: {
856 int ret;
857 wp<IBinder> weak;
858 sp<IBinder> strong;
859 Parcel data2, reply2;
860 sp<IServiceManager> sm = defaultServiceManager();
861 sp<IBinder> server = sm->getService(binderLibTestServiceName);
862
863 weak = data.readWeakBinder();
864 if (weak == NULL) {
865 return BAD_VALUE;
866 }
867 strong = weak.promote();
868
869 ret = server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data2, &reply2);
870 if (ret != NO_ERROR)
871 exit(EXIT_FAILURE);
872
873 if (strong == NULL) {
874 reply->setError(1);
875 }
876 return NO_ERROR;
877 }
878 case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION:
879 alarm(10);
880 return NO_ERROR;
881 case BINDER_LIB_TEST_EXIT_TRANSACTION:
882 while (wait(NULL) != -1 || errno != ECHILD)
883 ;
884 exit(EXIT_SUCCESS);
885 default:
886 return UNKNOWN_TRANSACTION;
887 };
888 }
889 private:
890 int32_t m_id;
891 int32_t m_nextServerId;
892 pthread_mutex_t m_serverWaitMutex;
893 pthread_cond_t m_serverWaitCond;
894 bool m_serverStartRequested;
895 sp<IBinder> m_serverStarted;
896 sp<IBinder> m_strongRef;
897};
898
899int run_server(int index, int readypipefd)
900{
901 status_t ret;
902 sp<IServiceManager> sm = defaultServiceManager();
903 {
904 sp<BinderLibTestService> testService = new BinderLibTestService(index);
905 if (index == 0) {
906 ret = sm->addService(binderLibTestServiceName, testService);
907 } else {
908 sp<IBinder> server = sm->getService(binderLibTestServiceName);
909 Parcel data, reply;
910 data.writeInt32(index);
911 data.writeStrongBinder(testService);
912
913 ret = server->transact(BINDER_LIB_TEST_REGISTER_SERVER, data, &reply);
914 }
915 }
916 write(readypipefd, &ret, sizeof(ret));
917 close(readypipefd);
918 //printf("%s: ret %d\n", __func__, ret);
919 if (ret)
920 return 1;
921 //printf("%s: joinThreadPool\n", __func__);
922 ProcessState::self()->startThreadPool();
923 IPCThreadState::self()->joinThreadPool();
924 //printf("%s: joinThreadPool returned\n", __func__);
925 return 1; /* joinThreadPool should not return */
926}
927
928int main(int argc, char **argv) {
929 int ret;
930
931 if (argc == 3 && !strcmp(argv[1], "--servername")) {
932 binderservername = argv[2];
933 } else {
934 binderservername = argv[0];
935 }
936
937 if (argc == 4 && !strcmp(argv[1], binderserverarg)) {
938 return run_server(atoi(argv[2]), atoi(argv[3]));
939 }
940
941 ::testing::InitGoogleTest(&argc, argv);
942 binder_env = AddGlobalTestEnvironment(new BinderLibTestEnv());
943 ProcessState::self()->startThreadPool();
944 return RUN_ALL_TESTS();
945}
946