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