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