blob: b7d5643dadf9cb65bcbb3b6c36b59a2d1b44f8b6 [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,
Connor O'Brien52be2c92016-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 }
Martijn Coenenf7100e42017-07-31 12:14:09 +0200268 pthread_t getTriggeringThread()
269 {
270 return m_triggeringThread;
271 }
Riley Andrews06b01ad2014-12-18 12:10:08 -0800272 protected:
273 void triggerEvent(void) {
274 pthread_mutex_lock(&m_waitMutex);
275 pthread_cond_signal(&m_waitCond);
276 m_eventTriggered = true;
Martijn Coenenf7100e42017-07-31 12:14:09 +0200277 m_triggeringThread = pthread_self();
Riley Andrews06b01ad2014-12-18 12:10:08 -0800278 pthread_mutex_unlock(&m_waitMutex);
279 };
280 private:
281 pthread_mutex_t m_waitMutex;
282 pthread_cond_t m_waitCond;
283 bool m_eventTriggered;
Martijn Coenenf7100e42017-07-31 12:14:09 +0200284 pthread_t m_triggeringThread;
Riley Andrews06b01ad2014-12-18 12:10:08 -0800285};
286
287class BinderLibTestCallBack : public BBinder, public BinderLibTestEvent
288{
289 public:
290 BinderLibTestCallBack()
291 : m_result(NOT_ENOUGH_DATA)
292 {
293 }
294 status_t getResult(void)
295 {
296 return m_result;
297 }
298
299 private:
300 virtual status_t onTransact(uint32_t code,
301 const Parcel& data, Parcel* reply,
302 uint32_t flags = 0)
303 {
304 (void)reply;
305 (void)flags;
306 switch(code) {
307 case BINDER_LIB_TEST_CALL_BACK:
308 m_result = data.readInt32();
309 triggerEvent();
310 return NO_ERROR;
311 default:
312 return UNKNOWN_TRANSACTION;
313 }
314 }
315
316 status_t m_result;
317};
318
319class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestEvent
320{
321 private:
322 virtual void binderDied(const wp<IBinder>& who) {
323 (void)who;
324 triggerEvent();
325 };
326};
327
328TEST_F(BinderLibTest, NopTransaction) {
329 status_t ret;
330 Parcel data, reply;
331 ret = m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply);
332 EXPECT_EQ(NO_ERROR, ret);
333}
334
335TEST_F(BinderLibTest, SetError) {
336 int32_t testValue[] = { 0, -123, 123 };
337 for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) {
338 status_t ret;
339 Parcel data, reply;
340 data.writeInt32(testValue[i]);
341 ret = m_server->transact(BINDER_LIB_TEST_SET_ERROR_TRANSACTION, data, &reply);
342 EXPECT_EQ(testValue[i], ret);
343 }
344}
345
346TEST_F(BinderLibTest, GetId) {
347 status_t ret;
348 int32_t id;
349 Parcel data, reply;
350 ret = m_server->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply);
351 EXPECT_EQ(NO_ERROR, ret);
352 ret = reply.readInt32(&id);
353 EXPECT_EQ(NO_ERROR, ret);
354 EXPECT_EQ(0, id);
355}
356
357TEST_F(BinderLibTest, PtrSize) {
358 status_t ret;
359 int32_t ptrsize;
360 Parcel data, reply;
361 sp<IBinder> server = addServer();
362 ASSERT_TRUE(server != NULL);
363 ret = server->transact(BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, data, &reply);
364 EXPECT_EQ(NO_ERROR, ret);
365 ret = reply.readInt32(&ptrsize);
366 EXPECT_EQ(NO_ERROR, ret);
367 RecordProperty("TestPtrSize", sizeof(void *));
368 RecordProperty("ServerPtrSize", sizeof(void *));
369}
370
371TEST_F(BinderLibTest, IndirectGetId2)
372{
373 status_t ret;
374 int32_t id;
375 int32_t count;
376 Parcel data, reply;
377 int32_t serverId[3];
378
379 data.writeInt32(ARRAY_SIZE(serverId));
380 for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
381 sp<IBinder> server;
382 BinderLibTestBundle datai;
383
384 server = addServer(&serverId[i]);
385 ASSERT_TRUE(server != NULL);
386 data.writeStrongBinder(server);
387 data.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
388 datai.appendTo(&data);
389 }
390
391 ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
392 ASSERT_EQ(NO_ERROR, ret);
393
394 ret = reply.readInt32(&id);
395 ASSERT_EQ(NO_ERROR, ret);
396 EXPECT_EQ(0, id);
397
398 ret = reply.readInt32(&count);
399 ASSERT_EQ(NO_ERROR, ret);
Arve Hjønnevåg6d5fa942016-08-12 15:32:48 -0700400 EXPECT_EQ(ARRAY_SIZE(serverId), (size_t)count);
Riley Andrews06b01ad2014-12-18 12:10:08 -0800401
402 for (size_t i = 0; i < (size_t)count; i++) {
403 BinderLibTestBundle replyi(&reply);
404 EXPECT_TRUE(replyi.isValid());
405 ret = replyi.readInt32(&id);
406 EXPECT_EQ(NO_ERROR, ret);
407 EXPECT_EQ(serverId[i], id);
408 EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
409 }
410
411 EXPECT_EQ(reply.dataSize(), reply.dataPosition());
412}
413
414TEST_F(BinderLibTest, IndirectGetId3)
415{
416 status_t ret;
417 int32_t id;
418 int32_t count;
419 Parcel data, reply;
420 int32_t serverId[3];
421
422 data.writeInt32(ARRAY_SIZE(serverId));
423 for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
424 sp<IBinder> server;
425 BinderLibTestBundle datai;
426 BinderLibTestBundle datai2;
427
428 server = addServer(&serverId[i]);
429 ASSERT_TRUE(server != NULL);
430 data.writeStrongBinder(server);
431 data.writeInt32(BINDER_LIB_TEST_INDIRECT_TRANSACTION);
432
433 datai.writeInt32(1);
434 datai.writeStrongBinder(m_server);
435 datai.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
436 datai2.appendTo(&datai);
437
438 datai.appendTo(&data);
439 }
440
441 ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
442 ASSERT_EQ(NO_ERROR, ret);
443
444 ret = reply.readInt32(&id);
445 ASSERT_EQ(NO_ERROR, ret);
446 EXPECT_EQ(0, id);
447
448 ret = reply.readInt32(&count);
449 ASSERT_EQ(NO_ERROR, ret);
Arve Hjønnevåg6d5fa942016-08-12 15:32:48 -0700450 EXPECT_EQ(ARRAY_SIZE(serverId), (size_t)count);
Riley Andrews06b01ad2014-12-18 12:10:08 -0800451
452 for (size_t i = 0; i < (size_t)count; i++) {
453 int32_t counti;
454
455 BinderLibTestBundle replyi(&reply);
456 EXPECT_TRUE(replyi.isValid());
457 ret = replyi.readInt32(&id);
458 EXPECT_EQ(NO_ERROR, ret);
459 EXPECT_EQ(serverId[i], id);
460
461 ret = replyi.readInt32(&counti);
462 ASSERT_EQ(NO_ERROR, ret);
463 EXPECT_EQ(1, counti);
464
465 BinderLibTestBundle replyi2(&replyi);
466 EXPECT_TRUE(replyi2.isValid());
467 ret = replyi2.readInt32(&id);
468 EXPECT_EQ(NO_ERROR, ret);
469 EXPECT_EQ(0, id);
470 EXPECT_EQ(replyi2.dataSize(), replyi2.dataPosition());
471
472 EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
473 }
474
475 EXPECT_EQ(reply.dataSize(), reply.dataPosition());
476}
477
478TEST_F(BinderLibTest, CallBack)
479{
480 status_t ret;
481 Parcel data, reply;
482 sp<BinderLibTestCallBack> callBack = new BinderLibTestCallBack();
483 data.writeStrongBinder(callBack);
484 ret = m_server->transact(BINDER_LIB_TEST_NOP_CALL_BACK, data, &reply, TF_ONE_WAY);
485 EXPECT_EQ(NO_ERROR, ret);
486 ret = callBack->waitEvent(5);
487 EXPECT_EQ(NO_ERROR, ret);
488 ret = callBack->getResult();
489 EXPECT_EQ(NO_ERROR, ret);
490}
491
492TEST_F(BinderLibTest, AddServer)
493{
494 sp<IBinder> server = addServer();
495 ASSERT_TRUE(server != NULL);
496}
497
498TEST_F(BinderLibTest, DeathNotificationNoRefs)
499{
500 status_t ret;
501
502 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
503
504 {
505 sp<IBinder> binder = addServer();
506 ASSERT_TRUE(binder != NULL);
507 ret = binder->linkToDeath(testDeathRecipient);
508 EXPECT_EQ(NO_ERROR, ret);
509 }
510 IPCThreadState::self()->flushCommands();
511 ret = testDeathRecipient->waitEvent(5);
512 EXPECT_EQ(NO_ERROR, ret);
513#if 0 /* Is there an unlink api that does not require a strong reference? */
514 ret = binder->unlinkToDeath(testDeathRecipient);
515 EXPECT_EQ(NO_ERROR, ret);
516#endif
517}
518
519TEST_F(BinderLibTest, DeathNotificationWeakRef)
520{
521 status_t ret;
522 wp<IBinder> wbinder;
523
524 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
525
526 {
527 sp<IBinder> binder = addServer();
528 ASSERT_TRUE(binder != NULL);
529 ret = binder->linkToDeath(testDeathRecipient);
530 EXPECT_EQ(NO_ERROR, ret);
531 wbinder = binder;
532 }
533 IPCThreadState::self()->flushCommands();
534 ret = testDeathRecipient->waitEvent(5);
535 EXPECT_EQ(NO_ERROR, ret);
536#if 0 /* Is there an unlink api that does not require a strong reference? */
537 ret = binder->unlinkToDeath(testDeathRecipient);
538 EXPECT_EQ(NO_ERROR, ret);
539#endif
540}
541
542TEST_F(BinderLibTest, DeathNotificationStrongRef)
543{
544 status_t ret;
545 sp<IBinder> sbinder;
546
547 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
548
549 {
550 sp<IBinder> binder = addServer();
551 ASSERT_TRUE(binder != NULL);
552 ret = binder->linkToDeath(testDeathRecipient);
553 EXPECT_EQ(NO_ERROR, ret);
554 sbinder = binder;
555 }
556 {
557 Parcel data, reply;
558 ret = sbinder->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
559 EXPECT_EQ(0, ret);
560 }
561 IPCThreadState::self()->flushCommands();
562 ret = testDeathRecipient->waitEvent(5);
563 EXPECT_EQ(NO_ERROR, ret);
564 ret = sbinder->unlinkToDeath(testDeathRecipient);
565 EXPECT_EQ(DEAD_OBJECT, ret);
566}
567
568TEST_F(BinderLibTest, DeathNotificationMultiple)
569{
570 status_t ret;
571 const int clientcount = 2;
572 sp<IBinder> target;
573 sp<IBinder> linkedclient[clientcount];
574 sp<BinderLibTestCallBack> callBack[clientcount];
575 sp<IBinder> passiveclient[clientcount];
576
577 target = addServer();
578 ASSERT_TRUE(target != NULL);
579 for (int i = 0; i < clientcount; i++) {
580 {
581 Parcel data, reply;
582
583 linkedclient[i] = addServer();
584 ASSERT_TRUE(linkedclient[i] != NULL);
585 callBack[i] = new BinderLibTestCallBack();
586 data.writeStrongBinder(target);
587 data.writeStrongBinder(callBack[i]);
588 ret = linkedclient[i]->transact(BINDER_LIB_TEST_LINK_DEATH_TRANSACTION, data, &reply, TF_ONE_WAY);
589 EXPECT_EQ(NO_ERROR, ret);
590 }
591 {
592 Parcel data, reply;
593
594 passiveclient[i] = addServer();
595 ASSERT_TRUE(passiveclient[i] != NULL);
596 data.writeStrongBinder(target);
597 ret = passiveclient[i]->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply, TF_ONE_WAY);
598 EXPECT_EQ(NO_ERROR, ret);
599 }
600 }
601 {
602 Parcel data, reply;
603 ret = target->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
604 EXPECT_EQ(0, ret);
605 }
606
607 for (int i = 0; i < clientcount; i++) {
608 ret = callBack[i]->waitEvent(5);
609 EXPECT_EQ(NO_ERROR, ret);
610 ret = callBack[i]->getResult();
611 EXPECT_EQ(NO_ERROR, ret);
612 }
613}
614
Martijn Coenenf7100e42017-07-31 12:14:09 +0200615TEST_F(BinderLibTest, DeathNotificationThread)
616{
617 status_t ret;
618 sp<BinderLibTestCallBack> callback;
619 sp<IBinder> target = addServer();
620 ASSERT_TRUE(target != NULL);
621 sp<IBinder> client = addServer();
622 ASSERT_TRUE(client != NULL);
623
624 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
625
626 ret = target->linkToDeath(testDeathRecipient);
627 EXPECT_EQ(NO_ERROR, ret);
628
629 {
630 Parcel data, reply;
631 ret = target->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
632 EXPECT_EQ(0, ret);
633 }
634
635 /* Make sure it's dead */
636 testDeathRecipient->waitEvent(5);
637
638 /* Now, pass the ref to another process and ask that process to
639 * call linkToDeath() on it, and wait for a response. This tests
640 * two things:
641 * 1) You still get death notifications when calling linkToDeath()
642 * on a ref that is already dead when it was passed to you.
643 * 2) That death notifications are not directly pushed to the thread
644 * registering them, but to the threadpool (proc workqueue) instead.
645 *
646 * 2) is tested because the thread handling BINDER_LIB_TEST_DEATH_TRANSACTION
647 * is blocked on a condition variable waiting for the death notification to be
648 * called; therefore, that thread is not available for handling proc work.
649 * So, if the death notification was pushed to the thread workqueue, the callback
650 * would never be called, and the test would timeout and fail.
651 *
652 * Note that we can't do this part of the test from this thread itself, because
653 * the binder driver would only push death notifications to the thread if
654 * it is a looper thread, which this thread is not.
655 *
656 * See b/23525545 for details.
657 */
658 {
659 Parcel data, reply;
660
661 callback = new BinderLibTestCallBack();
662 data.writeStrongBinder(target);
663 data.writeStrongBinder(callback);
664 ret = client->transact(BINDER_LIB_TEST_LINK_DEATH_TRANSACTION, data, &reply, TF_ONE_WAY);
665 EXPECT_EQ(NO_ERROR, ret);
666 }
667
668 ret = callback->waitEvent(5);
669 EXPECT_EQ(NO_ERROR, ret);
670 ret = callback->getResult();
671 EXPECT_EQ(NO_ERROR, ret);
672}
673
Riley Andrews06b01ad2014-12-18 12:10:08 -0800674TEST_F(BinderLibTest, PassFile) {
675 int ret;
676 int pipefd[2];
677 uint8_t buf[1] = { 0 };
678 uint8_t write_value = 123;
679
680 ret = pipe2(pipefd, O_NONBLOCK);
681 ASSERT_EQ(0, ret);
682
683 {
684 Parcel data, reply;
685 uint8_t writebuf[1] = { write_value };
686
687 ret = data.writeFileDescriptor(pipefd[1], true);
688 EXPECT_EQ(NO_ERROR, ret);
689
690 ret = data.writeInt32(sizeof(writebuf));
691 EXPECT_EQ(NO_ERROR, ret);
692
693 ret = data.write(writebuf, sizeof(writebuf));
694 EXPECT_EQ(NO_ERROR, ret);
695
696 ret = m_server->transact(BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, data, &reply);
697 EXPECT_EQ(NO_ERROR, ret);
698 }
699
700 ret = read(pipefd[0], buf, sizeof(buf));
Arve Hjønnevåg6d5fa942016-08-12 15:32:48 -0700701 EXPECT_EQ(sizeof(buf), (size_t)ret);
Riley Andrews06b01ad2014-12-18 12:10:08 -0800702 EXPECT_EQ(write_value, buf[0]);
703
704 waitForReadData(pipefd[0], 5000); /* wait for other proccess to close pipe */
705
706 ret = read(pipefd[0], buf, sizeof(buf));
707 EXPECT_EQ(0, ret);
708
709 close(pipefd[0]);
710}
711
712TEST_F(BinderLibTest, PromoteLocal) {
713 sp<IBinder> strong = new BBinder();
714 wp<IBinder> weak = strong;
715 sp<IBinder> strong_from_weak = weak.promote();
716 EXPECT_TRUE(strong != NULL);
717 EXPECT_EQ(strong, strong_from_weak);
718 strong = NULL;
719 strong_from_weak = NULL;
720 strong_from_weak = weak.promote();
721 EXPECT_TRUE(strong_from_weak == NULL);
722}
723
724TEST_F(BinderLibTest, PromoteRemote) {
725 int ret;
726 Parcel data, reply;
727 sp<IBinder> strong = new BBinder();
728 sp<IBinder> server = addServer();
729
730 ASSERT_TRUE(server != NULL);
731 ASSERT_TRUE(strong != NULL);
732
733 ret = data.writeWeakBinder(strong);
734 EXPECT_EQ(NO_ERROR, ret);
735
736 ret = server->transact(BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION, data, &reply);
737 EXPECT_GE(ret, 0);
738}
739
Arve Hjønnevåg70604312016-08-12 15:34:51 -0700740TEST_F(BinderLibTest, CheckHandleZeroBinderHighBitsZeroCookie) {
741 status_t ret;
742 Parcel data, reply;
743
744 ret = m_server->transact(BINDER_LIB_TEST_GET_SELF_TRANSACTION, data, &reply);
745 EXPECT_EQ(NO_ERROR, ret);
746
747 const flat_binder_object *fb = reply.readObject(false);
748 ASSERT_TRUE(fb != NULL);
749 EXPECT_EQ(fb->hdr.type, BINDER_TYPE_HANDLE);
750 EXPECT_EQ(ProcessState::self()->getStrongProxyForHandle(fb->handle), m_server);
751 EXPECT_EQ(fb->cookie, (binder_uintptr_t)0);
752 EXPECT_EQ(fb->binder >> 32, (binder_uintptr_t)0);
753}
754
Connor O'Brien52be2c92016-09-20 14:18:08 -0700755TEST_F(BinderLibTest, FreedBinder) {
756 status_t ret;
757
758 sp<IBinder> server = addServer();
759 ASSERT_TRUE(server != NULL);
760
761 __u32 freedHandle;
762 wp<IBinder> keepFreedBinder;
763 {
764 Parcel data, reply;
765 data.writeBool(false); /* request weak reference */
766 ret = server->transact(BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION, data, &reply);
767 ASSERT_EQ(NO_ERROR, ret);
768 struct flat_binder_object *freed = (struct flat_binder_object *)(reply.data());
769 freedHandle = freed->handle;
770 /* Add a weak ref to the freed binder so the driver does not
771 * delete its reference to it - otherwise the transaction
772 * fails regardless of whether the driver is fixed.
773 */
774 keepFreedBinder = reply.readWeakBinder();
775 }
776 {
777 Parcel data, reply;
778 data.writeStrongBinder(server);
779 /* Replace original handle with handle to the freed binder */
780 struct flat_binder_object *strong = (struct flat_binder_object *)(data.data());
781 __u32 oldHandle = strong->handle;
782 strong->handle = freedHandle;
783 ret = server->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply);
784 /* Returns DEAD_OBJECT (-32) if target crashes and
785 * FAILED_TRANSACTION if the driver rejects the invalid
786 * object.
787 */
788 EXPECT_EQ((status_t)FAILED_TRANSACTION, ret);
789 /* Restore original handle so parcel destructor does not use
790 * the wrong handle.
791 */
792 strong->handle = oldHandle;
793 }
794}
795
Riley Andrews06b01ad2014-12-18 12:10:08 -0800796class BinderLibTestService : public BBinder
797{
798 public:
799 BinderLibTestService(int32_t id)
800 : m_id(id)
801 , m_nextServerId(id + 1)
802 , m_serverStartRequested(false)
803 {
804 pthread_mutex_init(&m_serverWaitMutex, NULL);
805 pthread_cond_init(&m_serverWaitCond, NULL);
806 }
807 ~BinderLibTestService()
808 {
809 exit(EXIT_SUCCESS);
810 }
811 virtual status_t onTransact(uint32_t code,
812 const Parcel& data, Parcel* reply,
813 uint32_t flags = 0) {
814 //printf("%s: code %d\n", __func__, code);
815 (void)flags;
816
817 if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
818 return PERMISSION_DENIED;
819 }
820 switch (code) {
821 case BINDER_LIB_TEST_REGISTER_SERVER: {
822 int32_t id;
823 sp<IBinder> binder;
824 id = data.readInt32();
825 binder = data.readStrongBinder();
826 if (binder == NULL) {
827 return BAD_VALUE;
828 }
829
830 if (m_id != 0)
831 return INVALID_OPERATION;
832
833 pthread_mutex_lock(&m_serverWaitMutex);
834 if (m_serverStartRequested) {
835 m_serverStartRequested = false;
836 m_serverStarted = binder;
837 pthread_cond_signal(&m_serverWaitCond);
838 }
839 pthread_mutex_unlock(&m_serverWaitMutex);
840 return NO_ERROR;
841 }
842 case BINDER_LIB_TEST_ADD_SERVER: {
843 int ret;
844 uint8_t buf[1] = { 0 };
845 int serverid;
846
847 if (m_id != 0) {
848 return INVALID_OPERATION;
849 }
850 pthread_mutex_lock(&m_serverWaitMutex);
851 if (m_serverStartRequested) {
852 ret = -EBUSY;
853 } else {
854 serverid = m_nextServerId++;
855 m_serverStartRequested = true;
856
857 pthread_mutex_unlock(&m_serverWaitMutex);
858 ret = start_server_process(serverid);
859 pthread_mutex_lock(&m_serverWaitMutex);
860 }
861 if (ret > 0) {
862 if (m_serverStartRequested) {
Riley Andrews06b01ad2014-12-18 12:10:08 -0800863 struct timespec ts;
864 clock_gettime(CLOCK_REALTIME, &ts);
865 ts.tv_sec += 5;
866 ret = pthread_cond_timedwait(&m_serverWaitCond, &m_serverWaitMutex, &ts);
Riley Andrews06b01ad2014-12-18 12:10:08 -0800867 }
868 if (m_serverStartRequested) {
869 m_serverStartRequested = false;
870 ret = -ETIMEDOUT;
871 } else {
872 reply->writeStrongBinder(m_serverStarted);
873 reply->writeInt32(serverid);
874 m_serverStarted = NULL;
875 ret = NO_ERROR;
876 }
877 } else if (ret >= 0) {
878 m_serverStartRequested = false;
879 ret = UNKNOWN_ERROR;
880 }
881 pthread_mutex_unlock(&m_serverWaitMutex);
882 return ret;
883 }
884 case BINDER_LIB_TEST_NOP_TRANSACTION:
885 return NO_ERROR;
886 case BINDER_LIB_TEST_NOP_CALL_BACK: {
887 Parcel data2, reply2;
888 sp<IBinder> binder;
889 binder = data.readStrongBinder();
890 if (binder == NULL) {
891 return BAD_VALUE;
892 }
893 reply2.writeInt32(NO_ERROR);
894 binder->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
895 return NO_ERROR;
896 }
Arve Hjønnevåg70604312016-08-12 15:34:51 -0700897 case BINDER_LIB_TEST_GET_SELF_TRANSACTION:
898 reply->writeStrongBinder(this);
899 return NO_ERROR;
Riley Andrews06b01ad2014-12-18 12:10:08 -0800900 case BINDER_LIB_TEST_GET_ID_TRANSACTION:
901 reply->writeInt32(m_id);
902 return NO_ERROR;
903 case BINDER_LIB_TEST_INDIRECT_TRANSACTION: {
904 int32_t count;
905 uint32_t indirect_code;
906 sp<IBinder> binder;
907
908 count = data.readInt32();
909 reply->writeInt32(m_id);
910 reply->writeInt32(count);
911 for (int i = 0; i < count; i++) {
912 binder = data.readStrongBinder();
913 if (binder == NULL) {
914 return BAD_VALUE;
915 }
916 indirect_code = data.readInt32();
917 BinderLibTestBundle data2(&data);
918 if (!data2.isValid()) {
919 return BAD_VALUE;
920 }
921 BinderLibTestBundle reply2;
922 binder->transact(indirect_code, data2, &reply2);
923 reply2.appendTo(reply);
924 }
925 return NO_ERROR;
926 }
927 case BINDER_LIB_TEST_SET_ERROR_TRANSACTION:
928 reply->setError(data.readInt32());
929 return NO_ERROR;
930 case BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION:
931 reply->writeInt32(sizeof(void *));
932 return NO_ERROR;
933 case BINDER_LIB_TEST_GET_STATUS_TRANSACTION:
934 return NO_ERROR;
935 case BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION:
936 m_strongRef = data.readStrongBinder();
937 return NO_ERROR;
938 case BINDER_LIB_TEST_LINK_DEATH_TRANSACTION: {
939 int ret;
940 Parcel data2, reply2;
941 sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
942 sp<IBinder> target;
943 sp<IBinder> callback;
944
945 target = data.readStrongBinder();
946 if (target == NULL) {
947 return BAD_VALUE;
948 }
949 callback = data.readStrongBinder();
950 if (callback == NULL) {
951 return BAD_VALUE;
952 }
953 ret = target->linkToDeath(testDeathRecipient);
954 if (ret == NO_ERROR)
955 ret = testDeathRecipient->waitEvent(5);
956 data2.writeInt32(ret);
957 callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
958 return NO_ERROR;
959 }
960 case BINDER_LIB_TEST_WRITE_FILE_TRANSACTION: {
961 int ret;
962 int32_t size;
963 const void *buf;
964 int fd;
965
966 fd = data.readFileDescriptor();
967 if (fd < 0) {
968 return BAD_VALUE;
969 }
970 ret = data.readInt32(&size);
971 if (ret != NO_ERROR) {
972 return ret;
973 }
974 buf = data.readInplace(size);
975 if (buf == NULL) {
976 return BAD_VALUE;
977 }
978 ret = write(fd, buf, size);
979 if (ret != size)
980 return UNKNOWN_ERROR;
981 return NO_ERROR;
982 }
983 case BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION: {
984 int ret;
985 wp<IBinder> weak;
986 sp<IBinder> strong;
987 Parcel data2, reply2;
988 sp<IServiceManager> sm = defaultServiceManager();
989 sp<IBinder> server = sm->getService(binderLibTestServiceName);
990
991 weak = data.readWeakBinder();
992 if (weak == NULL) {
993 return BAD_VALUE;
994 }
995 strong = weak.promote();
996
997 ret = server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data2, &reply2);
998 if (ret != NO_ERROR)
999 exit(EXIT_FAILURE);
1000
1001 if (strong == NULL) {
1002 reply->setError(1);
1003 }
1004 return NO_ERROR;
1005 }
1006 case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION:
1007 alarm(10);
1008 return NO_ERROR;
1009 case BINDER_LIB_TEST_EXIT_TRANSACTION:
1010 while (wait(NULL) != -1 || errno != ECHILD)
1011 ;
1012 exit(EXIT_SUCCESS);
Connor O'Brien52be2c92016-09-20 14:18:08 -07001013 case BINDER_LIB_TEST_CREATE_BINDER_TRANSACTION: {
1014 bool strongRef = data.readBool();
1015 sp<IBinder> binder = new BBinder();
1016 if (strongRef) {
1017 reply->writeStrongBinder(binder);
1018 } else {
1019 reply->writeWeakBinder(binder);
1020 }
1021 return NO_ERROR;
1022 }
Riley Andrews06b01ad2014-12-18 12:10:08 -08001023 default:
1024 return UNKNOWN_TRANSACTION;
1025 };
1026 }
1027 private:
1028 int32_t m_id;
1029 int32_t m_nextServerId;
1030 pthread_mutex_t m_serverWaitMutex;
1031 pthread_cond_t m_serverWaitCond;
1032 bool m_serverStartRequested;
1033 sp<IBinder> m_serverStarted;
1034 sp<IBinder> m_strongRef;
1035};
1036
1037int run_server(int index, int readypipefd)
1038{
Connor O'Brien87c03cf2016-10-26 17:58:51 -07001039 binderLibTestServiceName += String16(binderserversuffix);
1040
Riley Andrews06b01ad2014-12-18 12:10:08 -08001041 status_t ret;
1042 sp<IServiceManager> sm = defaultServiceManager();
1043 {
1044 sp<BinderLibTestService> testService = new BinderLibTestService(index);
1045 if (index == 0) {
1046 ret = sm->addService(binderLibTestServiceName, testService);
1047 } else {
1048 sp<IBinder> server = sm->getService(binderLibTestServiceName);
1049 Parcel data, reply;
1050 data.writeInt32(index);
1051 data.writeStrongBinder(testService);
1052
1053 ret = server->transact(BINDER_LIB_TEST_REGISTER_SERVER, data, &reply);
1054 }
1055 }
1056 write(readypipefd, &ret, sizeof(ret));
1057 close(readypipefd);
1058 //printf("%s: ret %d\n", __func__, ret);
1059 if (ret)
1060 return 1;
1061 //printf("%s: joinThreadPool\n", __func__);
1062 ProcessState::self()->startThreadPool();
1063 IPCThreadState::self()->joinThreadPool();
1064 //printf("%s: joinThreadPool returned\n", __func__);
1065 return 1; /* joinThreadPool should not return */
1066}
1067
1068int main(int argc, char **argv) {
1069 int ret;
1070
Connor O'Brien87c03cf2016-10-26 17:58:51 -07001071 if (argc == 4 && !strcmp(argv[1], "--servername")) {
Riley Andrews06b01ad2014-12-18 12:10:08 -08001072 binderservername = argv[2];
1073 } else {
1074 binderservername = argv[0];
1075 }
1076
Connor O'Brien87c03cf2016-10-26 17:58:51 -07001077 if (argc == 5 && !strcmp(argv[1], binderserverarg)) {
1078 binderserversuffix = argv[4];
Riley Andrews06b01ad2014-12-18 12:10:08 -08001079 return run_server(atoi(argv[2]), atoi(argv[3]));
1080 }
Connor O'Brien87c03cf2016-10-26 17:58:51 -07001081 binderserversuffix = new char[16];
1082 snprintf(binderserversuffix, 16, "%d", getpid());
1083 binderLibTestServiceName += String16(binderserversuffix);
Riley Andrews06b01ad2014-12-18 12:10:08 -08001084
1085 ::testing::InitGoogleTest(&argc, argv);
1086 binder_env = AddGlobalTestEnvironment(new BinderLibTestEnv());
1087 ProcessState::self()->startThreadPool();
1088 return RUN_ALL_TESTS();
1089}
1090