1 /*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <poll.h>
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23
24 #include <gtest/gtest.h>
25
26 #include <binder/Binder.h>
27 #include <binder/IBinder.h>
28 #include <binder/IPCThreadState.h>
29 #include <binder/IServiceManager.h>
30
31 #define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
32
33 using namespace android;
34
35 static testing::Environment* binder_env;
36 static char *binderservername;
37 static char *binderserversuffix;
38 static char binderserverarg[] = "--binderserver";
39
40 static String16 binderLibTestServiceName = String16("test.binderLib");
41
42 enum 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
start_server_process(int arg2)63 pid_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
117 class BinderLibTestEnv : public ::testing::Environment {
118 public:
BinderLibTestEnv()119 BinderLibTestEnv() {}
getServer(void)120 sp<IBinder> getServer(void) {
121 return m_server;
122 }
123
124 private:
SetUp()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 }
TearDown()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
162 class BinderLibTest : public ::testing::Test {
163 public:
SetUp()164 virtual void SetUp() {
165 m_server = static_cast<BinderLibTestEnv *>(binder_env)->getServer();
166 }
TearDown()167 virtual void TearDown() {
168 }
169 protected:
addServer(int32_t * idPtr=NULL)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 }
waitForReadData(int fd,int timeout_ms)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
202 class BinderLibTestBundle : public Parcel
203 {
204 public:
BinderLibTestBundle(void)205 BinderLibTestBundle(void) {}
BinderLibTestBundle(const Parcel * source)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 }
appendTo(Parcel * dest)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 };
isValid(void)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
245 class BinderLibTestEvent
246 {
247 public:
BinderLibTestEvent(void)248 BinderLibTestEvent(void)
249 : m_eventTriggered(false)
250 {
251 pthread_mutex_init(&m_waitMutex, NULL);
252 pthread_cond_init(&m_waitCond, NULL);
253 }
waitEvent(int timeout_s)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:
triggerEvent(void)269 void triggerEvent(void) {
270 pthread_mutex_lock(&m_waitMutex);
271 pthread_cond_signal(&m_waitCond);
272 m_eventTriggered = true;
273 pthread_mutex_unlock(&m_waitMutex);
274 };
275 private:
276 pthread_mutex_t m_waitMutex;
277 pthread_cond_t m_waitCond;
278 bool m_eventTriggered;
279 };
280
281 class BinderLibTestCallBack : public BBinder, public BinderLibTestEvent
282 {
283 public:
BinderLibTestCallBack()284 BinderLibTestCallBack()
285 : m_result(NOT_ENOUGH_DATA)
286 {
287 }
getResult(void)288 status_t getResult(void)
289 {
290 return m_result;
291 }
292
293 private:
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)294 virtual status_t onTransact(uint32_t code,
295 const Parcel& data, Parcel* reply,
296 uint32_t flags = 0)
297 {
298 (void)reply;
299 (void)flags;
300 switch(code) {
301 case BINDER_LIB_TEST_CALL_BACK:
302 m_result = data.readInt32();
303 triggerEvent();
304 return NO_ERROR;
305 default:
306 return UNKNOWN_TRANSACTION;
307 }
308 }
309
310 status_t m_result;
311 };
312
313 class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestEvent
314 {
315 private:
binderDied(const wp<IBinder> & who)316 virtual void binderDied(const wp<IBinder>& who) {
317 (void)who;
318 triggerEvent();
319 };
320 };
321
TEST_F(BinderLibTest,NopTransaction)322 TEST_F(BinderLibTest, NopTransaction) {
323 status_t ret;
324 Parcel data, reply;
325 ret = m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply);
326 EXPECT_EQ(NO_ERROR, ret);
327 }
328
TEST_F(BinderLibTest,SetError)329 TEST_F(BinderLibTest, SetError) {
330 int32_t testValue[] = { 0, -123, 123 };
331 for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) {
332 status_t ret;
333 Parcel data, reply;
334 data.writeInt32(testValue[i]);
335 ret = m_server->transact(BINDER_LIB_TEST_SET_ERROR_TRANSACTION, data, &reply);
336 EXPECT_EQ(testValue[i], ret);
337 }
338 }
339
TEST_F(BinderLibTest,GetId)340 TEST_F(BinderLibTest, GetId) {
341 status_t ret;
342 int32_t id;
343 Parcel data, reply;
344 ret = m_server->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply);
345 EXPECT_EQ(NO_ERROR, ret);
346 ret = reply.readInt32(&id);
347 EXPECT_EQ(NO_ERROR, ret);
348 EXPECT_EQ(0, id);
349 }
350
TEST_F(BinderLibTest,PtrSize)351 TEST_F(BinderLibTest, PtrSize) {
352 status_t ret;
353 int32_t ptrsize;
354 Parcel data, reply;
355 sp<IBinder> server = addServer();
356 ASSERT_TRUE(server != NULL);
357 ret = server->transact(BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, data, &reply);
358 EXPECT_EQ(NO_ERROR, ret);
359 ret = reply.readInt32(&ptrsize);
360 EXPECT_EQ(NO_ERROR, ret);
361 RecordProperty("TestPtrSize", sizeof(void *));
362 RecordProperty("ServerPtrSize", sizeof(void *));
363 }
364
TEST_F(BinderLibTest,IndirectGetId2)365 TEST_F(BinderLibTest, IndirectGetId2)
366 {
367 status_t ret;
368 int32_t id;
369 int32_t count;
370 Parcel data, reply;
371 int32_t serverId[3];
372
373 data.writeInt32(ARRAY_SIZE(serverId));
374 for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
375 sp<IBinder> server;
376 BinderLibTestBundle datai;
377
378 server = addServer(&serverId[i]);
379 ASSERT_TRUE(server != NULL);
380 data.writeStrongBinder(server);
381 data.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
382 datai.appendTo(&data);
383 }
384
385 ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
386 ASSERT_EQ(NO_ERROR, ret);
387
388 ret = reply.readInt32(&id);
389 ASSERT_EQ(NO_ERROR, ret);
390 EXPECT_EQ(0, id);
391
392 ret = reply.readInt32(&count);
393 ASSERT_EQ(NO_ERROR, ret);
394 EXPECT_EQ(ARRAY_SIZE(serverId), (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
TEST_F(BinderLibTest,IndirectGetId3)408 TEST_F(BinderLibTest, IndirectGetId3)
409 {
410 status_t ret;
411 int32_t id;
412 int32_t count;
413 Parcel data, reply;
414 int32_t serverId[3];
415
416 data.writeInt32(ARRAY_SIZE(serverId));
417 for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
418 sp<IBinder> server;
419 BinderLibTestBundle datai;
420 BinderLibTestBundle datai2;
421
422 server = addServer(&serverId[i]);
423 ASSERT_TRUE(server != NULL);
424 data.writeStrongBinder(server);
425 data.writeInt32(BINDER_LIB_TEST_INDIRECT_TRANSACTION);
426
427 datai.writeInt32(1);
428 datai.writeStrongBinder(m_server);
429 datai.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
430 datai2.appendTo(&datai);
431
432 datai.appendTo(&data);
433 }
434
435 ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
436 ASSERT_EQ(NO_ERROR, ret);
437
438 ret = reply.readInt32(&id);
439 ASSERT_EQ(NO_ERROR, ret);
440 EXPECT_EQ(0, id);
441
442 ret = reply.readInt32(&count);
443 ASSERT_EQ(NO_ERROR, ret);
444 EXPECT_EQ(ARRAY_SIZE(serverId), (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
TEST_F(BinderLibTest,CallBack)472 TEST_F(BinderLibTest, CallBack)
473 {
474 status_t ret;
475 Parcel data, reply;
476 sp<BinderLibTestCallBack> callBack = new BinderLibTestCallBack();
477 data.writeStrongBinder(callBack);
478 ret = m_server->transact(BINDER_LIB_TEST_NOP_CALL_BACK, data, &reply, TF_ONE_WAY);
479 EXPECT_EQ(NO_ERROR, ret);
480 ret = callBack->waitEvent(5);
481 EXPECT_EQ(NO_ERROR, ret);
482 ret = callBack->getResult();
483 EXPECT_EQ(NO_ERROR, ret);
484 }
485
TEST_F(BinderLibTest,AddServer)486 TEST_F(BinderLibTest, AddServer)
487 {
488 sp<IBinder> server = addServer();
489 ASSERT_TRUE(server != NULL);
490 }
491
TEST_F(BinderLibTest,DeathNotificationNoRefs)492 TEST_F(BinderLibTest, DeathNotificationNoRefs)
493 {
494 status_t ret;
495
496 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
497
498 {
499 sp<IBinder> binder = addServer();
500 ASSERT_TRUE(binder != NULL);
501 ret = binder->linkToDeath(testDeathRecipient);
502 EXPECT_EQ(NO_ERROR, ret);
503 }
504 IPCThreadState::self()->flushCommands();
505 ret = testDeathRecipient->waitEvent(5);
506 EXPECT_EQ(NO_ERROR, ret);
507 #if 0 /* Is there an unlink api that does not require a strong reference? */
508 ret = binder->unlinkToDeath(testDeathRecipient);
509 EXPECT_EQ(NO_ERROR, ret);
510 #endif
511 }
512
TEST_F(BinderLibTest,DeathNotificationWeakRef)513 TEST_F(BinderLibTest, DeathNotificationWeakRef)
514 {
515 status_t ret;
516 wp<IBinder> wbinder;
517
518 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
519
520 {
521 sp<IBinder> binder = addServer();
522 ASSERT_TRUE(binder != NULL);
523 ret = binder->linkToDeath(testDeathRecipient);
524 EXPECT_EQ(NO_ERROR, ret);
525 wbinder = binder;
526 }
527 IPCThreadState::self()->flushCommands();
528 ret = testDeathRecipient->waitEvent(5);
529 EXPECT_EQ(NO_ERROR, ret);
530 #if 0 /* Is there an unlink api that does not require a strong reference? */
531 ret = binder->unlinkToDeath(testDeathRecipient);
532 EXPECT_EQ(NO_ERROR, ret);
533 #endif
534 }
535
TEST_F(BinderLibTest,DeathNotificationStrongRef)536 TEST_F(BinderLibTest, DeathNotificationStrongRef)
537 {
538 status_t ret;
539 sp<IBinder> sbinder;
540
541 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
542
543 {
544 sp<IBinder> binder = addServer();
545 ASSERT_TRUE(binder != NULL);
546 ret = binder->linkToDeath(testDeathRecipient);
547 EXPECT_EQ(NO_ERROR, ret);
548 sbinder = binder;
549 }
550 {
551 Parcel data, reply;
552 ret = sbinder->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
553 EXPECT_EQ(0, ret);
554 }
555 IPCThreadState::self()->flushCommands();
556 ret = testDeathRecipient->waitEvent(5);
557 EXPECT_EQ(NO_ERROR, ret);
558 ret = sbinder->unlinkToDeath(testDeathRecipient);
559 EXPECT_EQ(DEAD_OBJECT, ret);
560 }
561
TEST_F(BinderLibTest,DeathNotificationMultiple)562 TEST_F(BinderLibTest, DeathNotificationMultiple)
563 {
564 status_t ret;
565 const int clientcount = 2;
566 sp<IBinder> target;
567 sp<IBinder> linkedclient[clientcount];
568 sp<BinderLibTestCallBack> callBack[clientcount];
569 sp<IBinder> passiveclient[clientcount];
570
571 target = addServer();
572 ASSERT_TRUE(target != NULL);
573 for (int i = 0; i < clientcount; i++) {
574 {
575 Parcel data, reply;
576
577 linkedclient[i] = addServer();
578 ASSERT_TRUE(linkedclient[i] != NULL);
579 callBack[i] = new BinderLibTestCallBack();
580 data.writeStrongBinder(target);
581 data.writeStrongBinder(callBack[i]);
582 ret = linkedclient[i]->transact(BINDER_LIB_TEST_LINK_DEATH_TRANSACTION, data, &reply, TF_ONE_WAY);
583 EXPECT_EQ(NO_ERROR, ret);
584 }
585 {
586 Parcel data, reply;
587
588 passiveclient[i] = addServer();
589 ASSERT_TRUE(passiveclient[i] != NULL);
590 data.writeStrongBinder(target);
591 ret = passiveclient[i]->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply, TF_ONE_WAY);
592 EXPECT_EQ(NO_ERROR, ret);
593 }
594 }
595 {
596 Parcel data, reply;
597 ret = target->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
598 EXPECT_EQ(0, ret);
599 }
600
601 for (int i = 0; i < clientcount; i++) {
602 ret = callBack[i]->waitEvent(5);
603 EXPECT_EQ(NO_ERROR, ret);
604 ret = callBack[i]->getResult();
605 EXPECT_EQ(NO_ERROR, ret);
606 }
607 }
608
TEST_F(BinderLibTest,PassFile)609 TEST_F(BinderLibTest, PassFile) {
610 int ret;
611 int pipefd[2];
612 uint8_t buf[1] = { 0 };
613 uint8_t write_value = 123;
614
615 ret = pipe2(pipefd, O_NONBLOCK);
616 ASSERT_EQ(0, ret);
617
618 {
619 Parcel data, reply;
620 uint8_t writebuf[1] = { write_value };
621
622 ret = data.writeFileDescriptor(pipefd[1], true);
623 EXPECT_EQ(NO_ERROR, ret);
624
625 ret = data.writeInt32(sizeof(writebuf));
626 EXPECT_EQ(NO_ERROR, ret);
627
628 ret = data.write(writebuf, sizeof(writebuf));
629 EXPECT_EQ(NO_ERROR, ret);
630
631 ret = m_server->transact(BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, data, &reply);
632 EXPECT_EQ(NO_ERROR, ret);
633 }
634
635 ret = read(pipefd[0], buf, sizeof(buf));
636 EXPECT_EQ(sizeof(buf), (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
TEST_F(BinderLibTest,PromoteLocal)647 TEST_F(BinderLibTest, PromoteLocal) {
648 sp<IBinder> strong = new BBinder();
649 wp<IBinder> weak = strong;
650 sp<IBinder> strong_from_weak = weak.promote();
651 EXPECT_TRUE(strong != NULL);
652 EXPECT_EQ(strong, strong_from_weak);
653 strong = NULL;
654 strong_from_weak = NULL;
655 strong_from_weak = weak.promote();
656 EXPECT_TRUE(strong_from_weak == NULL);
657 }
658
TEST_F(BinderLibTest,PromoteRemote)659 TEST_F(BinderLibTest, PromoteRemote) {
660 int ret;
661 Parcel data, reply;
662 sp<IBinder> strong = new BBinder();
663 sp<IBinder> server = addServer();
664
665 ASSERT_TRUE(server != NULL);
666 ASSERT_TRUE(strong != NULL);
667
668 ret = data.writeWeakBinder(strong);
669 EXPECT_EQ(NO_ERROR, ret);
670
671 ret = server->transact(BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION, data, &reply);
672 EXPECT_GE(ret, 0);
673 }
674
TEST_F(BinderLibTest,CheckHandleZeroBinderHighBitsZeroCookie)675 TEST_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(BINDER_TYPE_HANDLE, fb->type);
685 EXPECT_EQ(m_server, ProcessState::self()->getStrongProxyForHandle(fb->handle));
686 EXPECT_EQ((binder_uintptr_t)0, fb->cookie);
687 EXPECT_EQ((uint64_t)0, (uint64_t)fb->binder >> 32);
688 }
689
TEST_F(BinderLibTest,FreedBinder)690 TEST_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
731 class BinderLibTestService : public BBinder
732 {
733 public:
BinderLibTestService(int32_t id)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 }
~BinderLibTestService()742 ~BinderLibTestService()
743 {
744 exit(EXIT_SUCCESS);
745 }
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags=0)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
run_server(int index,int readypipefd)972 int 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
main(int argc,char ** argv)1003 int 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