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