blob: ca49d9a5b0afd15d03ccbe9a59e2bb5b51293178 [file] [log] [blame]
The Android Open Source Project7c1b96a2008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2005 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 <utils/IPCThreadState.h>
18
19#include <utils/Binder.h>
20#include <utils/BpBinder.h>
21#include <utils/Debug.h>
22#include <utils/Log.h>
23#include <utils/TextOutput.h>
24#include <utils/threads.h>
25
26#include <private/utils/binder_module.h>
27#include <private/utils/Static.h>
28
29#include <sys/ioctl.h>
30#include <signal.h>
31#include <errno.h>
32#include <stdio.h>
33#include <unistd.h>
34
35#ifdef HAVE_PTHREADS
36#include <pthread.h>
37#include <sched.h>
38#include <sys/resource.h>
39#endif
40#ifdef HAVE_WIN32_THREADS
41#include <windows.h>
42#endif
43
44
45#if LOG_NDEBUG
46
47#define IF_LOG_TRANSACTIONS() if (false)
48#define IF_LOG_COMMANDS() if (false)
49#define LOG_REMOTEREFS(...)
50#define IF_LOG_REMOTEREFS() if (false)
51#define LOG_THREADPOOL(...)
52#define LOG_ONEWAY(...)
53
54#else
55
56#define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
57#define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
58#define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
59#define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
60#define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
61#define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
62
63#endif
64
65// ---------------------------------------------------------------------------
66
67namespace android {
68
69static const char* getReturnString(size_t idx);
70static const char* getCommandString(size_t idx);
71static const void* printReturnCommand(TextOutput& out, const void* _cmd);
72static const void* printCommand(TextOutput& out, const void* _cmd);
73
74// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
75// conditionals don't get stripped... but that is probably what we want.
76#if !LOG_NDEBUG
77static const char *kReturnStrings[] = {
78#if 1 /* TODO: error update strings */
79 "unknown",
80#else
81 "BR_OK",
82 "BR_TIMEOUT",
83 "BR_WAKEUP",
84 "BR_TRANSACTION",
85 "BR_REPLY",
86 "BR_ACQUIRE_RESULT",
87 "BR_DEAD_REPLY",
88 "BR_TRANSACTION_COMPLETE",
89 "BR_INCREFS",
90 "BR_ACQUIRE",
91 "BR_RELEASE",
92 "BR_DECREFS",
93 "BR_ATTEMPT_ACQUIRE",
94 "BR_EVENT_OCCURRED",
95 "BR_NOOP",
96 "BR_SPAWN_LOOPER",
97 "BR_FINISHED",
98 "BR_DEAD_BINDER",
99 "BR_CLEAR_DEATH_NOTIFICATION_DONE"
100#endif
101};
102
103static const char *kCommandStrings[] = {
104#if 1 /* TODO: error update strings */
105 "unknown",
106#else
107 "BC_NOOP",
108 "BC_TRANSACTION",
109 "BC_REPLY",
110 "BC_ACQUIRE_RESULT",
111 "BC_FREE_BUFFER",
112 "BC_TRANSACTION_COMPLETE",
113 "BC_INCREFS",
114 "BC_ACQUIRE",
115 "BC_RELEASE",
116 "BC_DECREFS",
117 "BC_INCREFS_DONE",
118 "BC_ACQUIRE_DONE",
119 "BC_ATTEMPT_ACQUIRE",
120 "BC_RETRIEVE_ROOT_OBJECT",
121 "BC_SET_THREAD_ENTRY",
122 "BC_REGISTER_LOOPER",
123 "BC_ENTER_LOOPER",
124 "BC_EXIT_LOOPER",
125 "BC_SYNC",
126 "BC_STOP_PROCESS",
127 "BC_STOP_SELF",
128 "BC_REQUEST_DEATH_NOTIFICATION",
129 "BC_CLEAR_DEATH_NOTIFICATION",
130 "BC_DEAD_BINDER_DONE"
131#endif
132};
133
134static const char* getReturnString(size_t idx)
135{
136 if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
137 return kReturnStrings[idx];
138 else
139 return "unknown";
140}
141
142static const char* getCommandString(size_t idx)
143{
144 if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
145 return kCommandStrings[idx];
146 else
147 return "unknown";
148}
149
150static const void* printBinderTransactionData(TextOutput& out, const void* data)
151{
152 const binder_transaction_data* btd =
153 (const binder_transaction_data*)data;
154 out << "target=" << btd->target.ptr << " (cookie " << btd->cookie << ")" << endl
155 << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
156 << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
157 << " bytes)" << endl
158 << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
159 << " bytes)" << endl;
160 return btd+1;
161}
162
163static const void* printReturnCommand(TextOutput& out, const void* _cmd)
164{
165 static const int32_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
166
167 const int32_t* cmd = (const int32_t*)_cmd;
168 int32_t code = *cmd++;
169 if (code == BR_ERROR) {
170 out << "BR_ERROR: " << (void*)(*cmd++) << endl;
171 return cmd;
172 } else if (code < 0 || code >= N) {
173 out << "Unknown reply: " << code << endl;
174 return cmd;
175 }
176
177 out << kReturnStrings[code];
178 switch (code) {
179 case BR_TRANSACTION:
180 case BR_REPLY: {
181 out << ": " << indent;
182 cmd = (const int32_t *)printBinderTransactionData(out, cmd);
183 out << dedent;
184 } break;
185
186 case BR_ACQUIRE_RESULT: {
187 const int32_t res = *cmd++;
188 out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
189 } break;
190
191 case BR_INCREFS:
192 case BR_ACQUIRE:
193 case BR_RELEASE:
194 case BR_DECREFS: {
195 const int32_t b = *cmd++;
196 const int32_t c = *cmd++;
197 out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
198 } break;
199
200 case BR_ATTEMPT_ACQUIRE: {
201 const int32_t p = *cmd++;
202 const int32_t b = *cmd++;
203 const int32_t c = *cmd++;
204 out << ": target=" << (void*)b << " (cookie " << (void*)c
205 << "), pri=" << p;
206 } break;
207
208 case BR_DEAD_BINDER:
209 case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
210 const int32_t c = *cmd++;
211 out << ": death cookie " << (void*)c;
212 } break;
213 }
214
215 out << endl;
216 return cmd;
217}
218
219static const void* printCommand(TextOutput& out, const void* _cmd)
220{
221 static const int32_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
222
223 const int32_t* cmd = (const int32_t*)_cmd;
224 int32_t code = *cmd++;
225 if (code < 0 || code >= N) {
226 out << "Unknown command: " << code << endl;
227 return cmd;
228 }
229
230 out << kCommandStrings[code];
231 switch (code) {
232 case BC_TRANSACTION:
233 case BC_REPLY: {
234 out << ": " << indent;
235 cmd = (const int32_t *)printBinderTransactionData(out, cmd);
236 out << dedent;
237 } break;
238
239 case BC_ACQUIRE_RESULT: {
240 const int32_t res = *cmd++;
241 out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
242 } break;
243
244 case BC_FREE_BUFFER: {
245 const int32_t buf = *cmd++;
246 out << ": buffer=" << (void*)buf;
247 } break;
248
249 case BC_INCREFS:
250 case BC_ACQUIRE:
251 case BC_RELEASE:
252 case BC_DECREFS: {
253 const int32_t d = *cmd++;
254 out << ": descriptor=" << (void*)d;
255 } break;
256
257 case BC_INCREFS_DONE:
258 case BC_ACQUIRE_DONE: {
259 const int32_t b = *cmd++;
260 const int32_t c = *cmd++;
261 out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
262 } break;
263
264 case BC_ATTEMPT_ACQUIRE: {
265 const int32_t p = *cmd++;
266 const int32_t d = *cmd++;
267 out << ": decriptor=" << (void*)d << ", pri=" << p;
268 } break;
269
270 case BC_REQUEST_DEATH_NOTIFICATION:
271 case BC_CLEAR_DEATH_NOTIFICATION: {
272 const int32_t h = *cmd++;
273 const int32_t c = *cmd++;
274 out << ": handle=" << h << " (death cookie " << (void*)c << ")";
275 } break;
276
277 case BC_DEAD_BINDER_DONE: {
278 const int32_t c = *cmd++;
279 out << ": death cookie " << (void*)c;
280 } break;
281 }
282
283 out << endl;
284 return cmd;
285}
286#endif
287
288static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
289static bool gHaveTLS = false;
290static pthread_key_t gTLS = 0;
291static bool gShutdown = false;
292
293IPCThreadState* IPCThreadState::self()
294{
295 if (gHaveTLS) {
296restart:
297 const pthread_key_t k = gTLS;
298 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
299 if (st) return st;
300 return new IPCThreadState;
301 }
302
303 if (gShutdown) return NULL;
304
305 pthread_mutex_lock(&gTLSMutex);
306 if (!gHaveTLS) {
307 if (pthread_key_create(&gTLS, threadDestructor) != 0) {
308 pthread_mutex_unlock(&gTLSMutex);
309 return NULL;
310 }
311 gHaveTLS = true;
312 }
313 pthread_mutex_unlock(&gTLSMutex);
314 goto restart;
315}
316
317void IPCThreadState::shutdown()
318{
319 gShutdown = true;
320
321 if (gHaveTLS) {
322 // XXX Need to wait for all thread pool threads to exit!
323 IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
324 if (st) {
325 delete st;
326 pthread_setspecific(gTLS, NULL);
327 }
328 gHaveTLS = false;
329 }
330}
331
332sp<ProcessState> IPCThreadState::process()
333{
334 return mProcess;
335}
336
337status_t IPCThreadState::clearLastError()
338{
339 const status_t err = mLastError;
340 mLastError = NO_ERROR;
341 return err;
342}
343
344int IPCThreadState::getCallingPid()
345{
346 return mCallingPid;
347}
348
349int IPCThreadState::getCallingUid()
350{
351 return mCallingUid;
352}
353
354int64_t IPCThreadState::clearCallingIdentity()
355{
356 int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
357 clearCaller();
358 return token;
359}
360
361void IPCThreadState::restoreCallingIdentity(int64_t token)
362{
363 mCallingUid = (int)(token>>32);
364 mCallingPid = (int)token;
365}
366
367void IPCThreadState::clearCaller()
368{
369 if (mProcess->supportsProcesses()) {
370 mCallingPid = getpid();
371 mCallingUid = getuid();
372 } else {
373 mCallingPid = -1;
374 mCallingUid = -1;
375 }
376}
377
378void IPCThreadState::flushCommands()
379{
380 if (mProcess->mDriverFD <= 0)
381 return;
382 talkWithDriver(false);
383}
384
385void IPCThreadState::joinThreadPool(bool isMain)
386{
387 LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
388
389 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
390
391 status_t result;
392 do {
393 int32_t cmd;
394 result = talkWithDriver();
395 if (result >= NO_ERROR) {
396 size_t IN = mIn.dataAvail();
397 if (IN < sizeof(int32_t)) continue;
398 cmd = mIn.readInt32();
399 IF_LOG_COMMANDS() {
400 alog << "Processing top-level Command: "
401 << getReturnString(cmd) << endl;
402 }
403 result = executeCommand(cmd);
404 }
405
406 // Let this thread exit the thread pool if it is no longer
407 // needed and it is not the main process thread.
408 if(result == TIMED_OUT && !isMain) {
409 break;
410 }
411 } while (result != -ECONNREFUSED && result != -EBADF);
412
413 LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
414 (void*)pthread_self(), getpid(), (void*)result);
415
416 mOut.writeInt32(BC_EXIT_LOOPER);
417 talkWithDriver(false);
418}
419
420void IPCThreadState::stopProcess(bool immediate)
421{
422 //LOGI("**** STOPPING PROCESS");
423 flushCommands();
424 int fd = mProcess->mDriverFD;
425 mProcess->mDriverFD = -1;
426 close(fd);
427 //kill(getpid(), SIGKILL);
428}
429
430status_t IPCThreadState::transact(int32_t handle,
431 uint32_t code, const Parcel& data,
432 Parcel* reply, uint32_t flags)
433{
434 status_t err = data.errorCheck();
435
436 flags |= TF_ACCEPT_FDS;
437
438 IF_LOG_TRANSACTIONS() {
439 TextOutput::Bundle _b(alog);
440 alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
441 << handle << " / code " << TypeCode(code) << ": "
442 << indent << data << dedent << endl;
443 }
444
445 if (err == NO_ERROR) {
446 LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
447 (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
448 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
449 }
450
451 if (err != NO_ERROR) {
452 if (reply) reply->setError(err);
453 return (mLastError = err);
454 }
455
456 if ((flags & TF_ONE_WAY) == 0) {
457 if (reply) {
458 err = waitForResponse(reply);
459 } else {
460 Parcel fakeReply;
461 err = waitForResponse(&fakeReply);
462 }
463
464 IF_LOG_TRANSACTIONS() {
465 TextOutput::Bundle _b(alog);
466 alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
467 << handle << ": ";
468 if (reply) alog << indent << *reply << dedent << endl;
469 else alog << "(none requested)" << endl;
470 }
471 } else {
472 err = waitForResponse(NULL, NULL);
473 }
474
475 return err;
476}
477
478void IPCThreadState::incStrongHandle(int32_t handle)
479{
480 LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
481 mOut.writeInt32(BC_ACQUIRE);
482 mOut.writeInt32(handle);
483}
484
485void IPCThreadState::decStrongHandle(int32_t handle)
486{
487 LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
488 mOut.writeInt32(BC_RELEASE);
489 mOut.writeInt32(handle);
490}
491
492void IPCThreadState::incWeakHandle(int32_t handle)
493{
494 LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
495 mOut.writeInt32(BC_INCREFS);
496 mOut.writeInt32(handle);
497}
498
499void IPCThreadState::decWeakHandle(int32_t handle)
500{
501 LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
502 mOut.writeInt32(BC_DECREFS);
503 mOut.writeInt32(handle);
504}
505
506status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
507{
508 mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
509 mOut.writeInt32(0); // xxx was thread priority
510 mOut.writeInt32(handle);
511 status_t result = UNKNOWN_ERROR;
512
513 waitForResponse(NULL, &result);
514
515#if LOG_REFCOUNTS
516 printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
517 handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
518#endif
519
520 return result;
521}
522
523void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
524{
525#if LOG_REFCOUNTS
526 printf("IPCThreadState::expungeHandle(%ld)\n", handle);
527#endif
528 self()->mProcess->expungeHandle(handle, binder);
529}
530
531status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
532{
533 mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
534 mOut.writeInt32((int32_t)handle);
535 mOut.writeInt32((int32_t)proxy);
536 return NO_ERROR;
537}
538
539status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
540{
541 mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
542 mOut.writeInt32((int32_t)handle);
543 mOut.writeInt32((int32_t)proxy);
544 return NO_ERROR;
545}
546
547IPCThreadState::IPCThreadState()
548 : mProcess(ProcessState::self())
549{
550 pthread_setspecific(gTLS, this);
551 clearCaller();
552 mIn.setDataCapacity(256);
553 mOut.setDataCapacity(256);
554}
555
556IPCThreadState::~IPCThreadState()
557{
558}
559
560status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
561{
562 status_t err;
563 status_t statusBuffer;
564 err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
565 if (err < NO_ERROR) return err;
566
567 return waitForResponse(NULL, NULL);
568}
569
570status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
571{
572 int32_t cmd;
573 int32_t err;
574
575 while (1) {
576 if ((err=talkWithDriver()) < NO_ERROR) break;
577 err = mIn.errorCheck();
578 if (err < NO_ERROR) break;
579 if (mIn.dataAvail() == 0) continue;
580
581 cmd = mIn.readInt32();
582
583 IF_LOG_COMMANDS() {
584 alog << "Processing waitForResponse Command: "
585 << getReturnString(cmd) << endl;
586 }
587
588 switch (cmd) {
589 case BR_TRANSACTION_COMPLETE:
590 if (!reply && !acquireResult) goto finish;
591 break;
592
593 case BR_DEAD_REPLY:
594 err = DEAD_OBJECT;
595 goto finish;
596
597 case BR_FAILED_REPLY:
598 err = FAILED_TRANSACTION;
599 goto finish;
600
601 case BR_ACQUIRE_RESULT:
602 {
603 LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
604 const int32_t result = mIn.readInt32();
605 if (!acquireResult) continue;
606 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
607 }
608 goto finish;
609
610 case BR_REPLY:
611 {
612 binder_transaction_data tr;
613 err = mIn.read(&tr, sizeof(tr));
614 LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
615 if (err != NO_ERROR) goto finish;
616
617 if (reply) {
618 if ((tr.flags & TF_STATUS_CODE) == 0) {
619 reply->ipcSetDataReference(
620 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
621 tr.data_size,
622 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
623 tr.offsets_size/sizeof(size_t),
624 freeBuffer, this);
625 } else {
626 err = *static_cast<const status_t*>(tr.data.ptr.buffer);
627 freeBuffer(NULL,
628 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
629 tr.data_size,
630 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
631 tr.offsets_size/sizeof(size_t), this);
632 }
633 } else {
634 freeBuffer(NULL,
635 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
636 tr.data_size,
637 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
638 tr.offsets_size/sizeof(size_t), this);
639 continue;
640 }
641 }
642 goto finish;
643
644 default:
645 err = executeCommand(cmd);
646 if (err != NO_ERROR) goto finish;
647 break;
648 }
649 }
650
651finish:
652 if (err != NO_ERROR) {
653 if (acquireResult) *acquireResult = err;
654 if (reply) reply->setError(err);
655 mLastError = err;
656 }
657
658 return err;
659}
660
661status_t IPCThreadState::talkWithDriver(bool doReceive)
662{
663 LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
664
665 binder_write_read bwr;
666
667 // Is the read buffer empty?
668 const bool needRead = mIn.dataPosition() >= mIn.dataSize();
669
670 // We don't want to write anything if we are still reading
671 // from data left in the input buffer and the caller
672 // has requested to read the next data.
673 const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
674
675 bwr.write_size = outAvail;
676 bwr.write_buffer = (long unsigned int)mOut.data();
677
678 // This is what we'll read.
679 if (doReceive && needRead) {
680 bwr.read_size = mIn.dataCapacity();
681 bwr.read_buffer = (long unsigned int)mIn.data();
682 } else {
683 bwr.read_size = 0;
684 }
685
686 IF_LOG_COMMANDS() {
687 TextOutput::Bundle _b(alog);
688 if (outAvail != 0) {
689 alog << "Sending commands to driver: " << indent;
690 const void* cmds = (const void*)bwr.write_buffer;
691 const void* end = ((const uint8_t*)cmds)+bwr.write_size;
692 alog << HexDump(cmds, bwr.write_size) << endl;
693 while (cmds < end) cmds = printCommand(alog, cmds);
694 alog << dedent;
695 }
696 alog << "Size of receive buffer: " << bwr.read_size
697 << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
698 }
699
700 // Return immediately if there is nothing to do.
701 if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
702
703 bwr.write_consumed = 0;
704 bwr.read_consumed = 0;
705 status_t err;
706 do {
707 IF_LOG_COMMANDS() {
708 alog << "About to read/write, write size = " << mOut.dataSize() << endl;
709 }
710#if defined(HAVE_ANDROID_OS)
711 if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
712 err = NO_ERROR;
713 else
714 err = -errno;
715#else
716 err = INVALID_OPERATION;
717#endif
718 IF_LOG_COMMANDS() {
719 alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
720 }
721 } while (err == -EINTR);
722
723 IF_LOG_COMMANDS() {
724 alog << "Our err: " << (void*)err << ", write consumed: "
725 << bwr.write_consumed << " (of " << mOut.dataSize()
726 << "), read consumed: " << bwr.read_consumed << endl;
727 }
728
729 if (err >= NO_ERROR) {
730 if (bwr.write_consumed > 0) {
731 if (bwr.write_consumed < (ssize_t)mOut.dataSize())
732 mOut.remove(0, bwr.write_consumed);
733 else
734 mOut.setDataSize(0);
735 }
736 if (bwr.read_consumed > 0) {
737 mIn.setDataSize(bwr.read_consumed);
738 mIn.setDataPosition(0);
739 }
740 IF_LOG_COMMANDS() {
741 TextOutput::Bundle _b(alog);
742 alog << "Remaining data size: " << mOut.dataSize() << endl;
743 alog << "Received commands from driver: " << indent;
744 const void* cmds = mIn.data();
745 const void* end = mIn.data() + mIn.dataSize();
746 alog << HexDump(cmds, mIn.dataSize()) << endl;
747 while (cmds < end) cmds = printReturnCommand(alog, cmds);
748 alog << dedent;
749 }
750 return NO_ERROR;
751 }
752
753 return err;
754}
755
756status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
757 int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
758{
759 binder_transaction_data tr;
760
761 tr.target.handle = handle;
762 tr.code = code;
763 tr.flags = binderFlags;
764
765 const status_t err = data.errorCheck();
766 if (err == NO_ERROR) {
767 tr.data_size = data.ipcDataSize();
768 tr.data.ptr.buffer = data.ipcData();
769 tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
770 tr.data.ptr.offsets = data.ipcObjects();
771 } else if (statusBuffer) {
772 tr.flags |= TF_STATUS_CODE;
773 *statusBuffer = err;
774 tr.data_size = sizeof(status_t);
775 tr.data.ptr.buffer = statusBuffer;
776 tr.offsets_size = 0;
777 tr.data.ptr.offsets = NULL;
778 } else {
779 return (mLastError = err);
780 }
781
782 mOut.writeInt32(cmd);
783 mOut.write(&tr, sizeof(tr));
784
785 return NO_ERROR;
786}
787
788sp<BBinder> the_context_object;
789
790void setTheContextObject(sp<BBinder> obj)
791{
792 the_context_object = obj;
793}
794
795status_t IPCThreadState::executeCommand(int32_t cmd)
796{
797 BBinder* obj;
798 RefBase::weakref_type* refs;
799 status_t result = NO_ERROR;
800
801 switch (cmd) {
802 case BR_ERROR:
803 result = mIn.readInt32();
804 break;
805
806 case BR_OK:
807 break;
808
809 case BR_ACQUIRE:
810 refs = (RefBase::weakref_type*)mIn.readInt32();
811 obj = (BBinder*)mIn.readInt32();
812 LOG_ASSERT(refs->refBase() == obj,
813 "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
814 refs, obj, refs->refBase());
815 obj->incStrong(mProcess.get());
816 IF_LOG_REMOTEREFS() {
817 LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
818 obj->printRefs();
819 }
820 mOut.writeInt32(BC_ACQUIRE_DONE);
821 mOut.writeInt32((int32_t)refs);
822 mOut.writeInt32((int32_t)obj);
823 break;
824
825 case BR_RELEASE:
826 refs = (RefBase::weakref_type*)mIn.readInt32();
827 obj = (BBinder*)mIn.readInt32();
828 LOG_ASSERT(refs->refBase() == obj,
829 "BR_RELEASE: object %p does not match cookie %p (expected %p)",
830 refs, obj, refs->refBase());
831 IF_LOG_REMOTEREFS() {
832 LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
833 obj->printRefs();
834 }
835 obj->decStrong(mProcess.get());
836 break;
837
838 case BR_INCREFS:
839 refs = (RefBase::weakref_type*)mIn.readInt32();
840 obj = (BBinder*)mIn.readInt32();
841 refs->incWeak(mProcess.get());
842 mOut.writeInt32(BC_INCREFS_DONE);
843 mOut.writeInt32((int32_t)refs);
844 mOut.writeInt32((int32_t)obj);
845 break;
846
847 case BR_DECREFS:
848 refs = (RefBase::weakref_type*)mIn.readInt32();
849 obj = (BBinder*)mIn.readInt32();
850 // NOTE: This assertion is not valid, because the object may no
851 // longer exist (thus the (BBinder*)cast above resulting in a different
852 // memory address).
853 //LOG_ASSERT(refs->refBase() == obj,
854 // "BR_DECREFS: object %p does not match cookie %p (expected %p)",
855 // refs, obj, refs->refBase());
856 refs->decWeak(mProcess.get());
857 break;
858
859 case BR_ATTEMPT_ACQUIRE:
860 refs = (RefBase::weakref_type*)mIn.readInt32();
861 obj = (BBinder*)mIn.readInt32();
862
863 {
864 const bool success = refs->attemptIncStrong(mProcess.get());
865 LOG_ASSERT(success && refs->refBase() == obj,
866 "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
867 refs, obj, refs->refBase());
868
869 mOut.writeInt32(BC_ACQUIRE_RESULT);
870 mOut.writeInt32((int32_t)success);
871 }
872 break;
873
874 case BR_TRANSACTION:
875 {
876 binder_transaction_data tr;
877 result = mIn.read(&tr, sizeof(tr));
878 LOG_ASSERT(result == NO_ERROR,
879 "Not enough command data for brTRANSACTION");
880 if (result != NO_ERROR) break;
881
882 Parcel buffer;
883 buffer.ipcSetDataReference(
884 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
885 tr.data_size,
886 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
887 tr.offsets_size/sizeof(size_t), freeBuffer, this);
888
889 const pid_t origPid = mCallingPid;
890 const uid_t origUid = mCallingUid;
891
892 mCallingPid = tr.sender_pid;
893 mCallingUid = tr.sender_euid;
894
895 //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
896
897 Parcel reply;
898 IF_LOG_TRANSACTIONS() {
899 TextOutput::Bundle _b(alog);
900 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
901 << " / obj " << tr.target.ptr << " / code "
902 << TypeCode(tr.code) << ": " << indent << buffer
903 << dedent << endl
904 << "Data addr = "
905 << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
906 << ", offsets addr="
907 << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
908 }
909 if (tr.target.ptr) {
910 sp<BBinder> b((BBinder*)tr.cookie);
911 const status_t error = b->transact(tr.code, buffer, &reply, 0);
912 if (error < NO_ERROR) reply.setError(error);
913
914 } else {
915 const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
916 if (error < NO_ERROR) reply.setError(error);
917 }
918
919 //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
920 // mCallingPid, origPid, origUid);
921
922 if ((tr.flags & TF_ONE_WAY) == 0) {
923 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
924 sendReply(reply, 0);
925 } else {
926 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
927 }
928
929 mCallingPid = origPid;
930 mCallingUid = origUid;
931
932 IF_LOG_TRANSACTIONS() {
933 TextOutput::Bundle _b(alog);
934 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
935 << tr.target.ptr << ": " << indent << reply << dedent << endl;
936 }
937
938 }
939 break;
940
941 case BR_DEAD_BINDER:
942 {
943 BpBinder *proxy = (BpBinder*)mIn.readInt32();
944 proxy->sendObituary();
945 mOut.writeInt32(BC_DEAD_BINDER_DONE);
946 mOut.writeInt32((int32_t)proxy);
947 } break;
948
949 case BR_CLEAR_DEATH_NOTIFICATION_DONE:
950 {
951 BpBinder *proxy = (BpBinder*)mIn.readInt32();
952 proxy->getWeakRefs()->decWeak(proxy);
953 } break;
954
955 case BR_FINISHED:
956 result = TIMED_OUT;
957 break;
958
959 case BR_NOOP:
960 break;
961
962 case BR_SPAWN_LOOPER:
963 mProcess->spawnPooledThread(false);
964 break;
965
966 default:
967 printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
968 result = UNKNOWN_ERROR;
969 break;
970 }
971
972 if (result != NO_ERROR) {
973 mLastError = result;
974 }
975
976 return result;
977}
978
979void IPCThreadState::threadDestructor(void *st)
980{
981 IPCThreadState* const self = static_cast<IPCThreadState*>(st);
982 if (self) {
983 self->flushCommands();
984#if defined(HAVE_ANDROID_OS)
985 ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
986#endif
987 delete self;
988 }
989}
990
991
992void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
993 const size_t* objects, size_t objectsSize,
994 void* cookie)
995{
996 //LOGI("Freeing parcel %p", &parcel);
997 IF_LOG_COMMANDS() {
998 alog << "Writing BC_FREE_BUFFER for " << data << endl;
999 }
1000 LOG_ASSERT(data != NULL, "Called with NULL data");
1001 if (parcel != NULL) parcel->closeFileDescriptors();
1002 IPCThreadState* state = self();
1003 state->mOut.writeInt32(BC_FREE_BUFFER);
1004 state->mOut.writeInt32((int32_t)data);
1005}
1006
1007}; // namespace android