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