blob: c371a23b85f48ddaf94210b9c969ac6846378e6d [file] [log] [blame]
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -08001/*
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
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070017#include <binder/IPCThreadState.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080018
Mathias Agopianc5b2c0b2009-05-19 19:08:10 -070019#include <binder/Binder.h>
20#include <binder/BpBinder.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080021#include <utils/Debug.h>
22#include <utils/Log.h>
23#include <utils/TextOutput.h>
24#include <utils/threads.h>
25
Mathias Agopian208059f2009-05-18 15:08:03 -070026#include <private/binder/binder_module.h>
27#include <private/binder/Static.h>
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -080028
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{
Marco Nelissend43b1942009-07-17 07:59:17 -0700369 mCallingPid = getpid();
370 mCallingUid = getuid();
The Android Open Source Projectedbf3b62009-03-03 19:31:44 -0800371}
372
373void IPCThreadState::flushCommands()
374{
375 if (mProcess->mDriverFD <= 0)
376 return;
377 talkWithDriver(false);
378}
379
380void IPCThreadState::joinThreadPool(bool isMain)
381{
382 LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
383
384 mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
385
386 status_t result;
387 do {
388 int32_t cmd;
389
390 // When we've cleared the incoming command queue, process any pending derefs
391 if (mIn.dataPosition() >= mIn.dataSize()) {
392 size_t numPending = mPendingWeakDerefs.size();
393 if (numPending > 0) {
394 for (size_t i = 0; i < numPending; i++) {
395 RefBase::weakref_type* refs = mPendingWeakDerefs[i];
396 refs->decWeak(mProcess.get());
397 }
398 mPendingWeakDerefs.clear();
399 }
400
401 numPending = mPendingStrongDerefs.size();
402 if (numPending > 0) {
403 for (size_t i = 0; i < numPending; i++) {
404 BBinder* obj = mPendingStrongDerefs[i];
405 obj->decStrong(mProcess.get());
406 }
407 mPendingStrongDerefs.clear();
408 }
409 }
410
411 // now get the next command to be processed, waiting if necessary
412 result = talkWithDriver();
413 if (result >= NO_ERROR) {
414 size_t IN = mIn.dataAvail();
415 if (IN < sizeof(int32_t)) continue;
416 cmd = mIn.readInt32();
417 IF_LOG_COMMANDS() {
418 alog << "Processing top-level Command: "
419 << getReturnString(cmd) << endl;
420 }
421 result = executeCommand(cmd);
422 }
423
424 // Let this thread exit the thread pool if it is no longer
425 // needed and it is not the main process thread.
426 if(result == TIMED_OUT && !isMain) {
427 break;
428 }
429 } while (result != -ECONNREFUSED && result != -EBADF);
430
431 LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
432 (void*)pthread_self(), getpid(), (void*)result);
433
434 mOut.writeInt32(BC_EXIT_LOOPER);
435 talkWithDriver(false);
436}
437
438void IPCThreadState::stopProcess(bool immediate)
439{
440 //LOGI("**** STOPPING PROCESS");
441 flushCommands();
442 int fd = mProcess->mDriverFD;
443 mProcess->mDriverFD = -1;
444 close(fd);
445 //kill(getpid(), SIGKILL);
446}
447
448status_t IPCThreadState::transact(int32_t handle,
449 uint32_t code, const Parcel& data,
450 Parcel* reply, uint32_t flags)
451{
452 status_t err = data.errorCheck();
453
454 flags |= TF_ACCEPT_FDS;
455
456 IF_LOG_TRANSACTIONS() {
457 TextOutput::Bundle _b(alog);
458 alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
459 << handle << " / code " << TypeCode(code) << ": "
460 << indent << data << dedent << endl;
461 }
462
463 if (err == NO_ERROR) {
464 LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
465 (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
466 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
467 }
468
469 if (err != NO_ERROR) {
470 if (reply) reply->setError(err);
471 return (mLastError = err);
472 }
473
474 if ((flags & TF_ONE_WAY) == 0) {
475 if (reply) {
476 err = waitForResponse(reply);
477 } else {
478 Parcel fakeReply;
479 err = waitForResponse(&fakeReply);
480 }
481
482 IF_LOG_TRANSACTIONS() {
483 TextOutput::Bundle _b(alog);
484 alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
485 << handle << ": ";
486 if (reply) alog << indent << *reply << dedent << endl;
487 else alog << "(none requested)" << endl;
488 }
489 } else {
490 err = waitForResponse(NULL, NULL);
491 }
492
493 return err;
494}
495
496void IPCThreadState::incStrongHandle(int32_t handle)
497{
498 LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
499 mOut.writeInt32(BC_ACQUIRE);
500 mOut.writeInt32(handle);
501}
502
503void IPCThreadState::decStrongHandle(int32_t handle)
504{
505 LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
506 mOut.writeInt32(BC_RELEASE);
507 mOut.writeInt32(handle);
508}
509
510void IPCThreadState::incWeakHandle(int32_t handle)
511{
512 LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
513 mOut.writeInt32(BC_INCREFS);
514 mOut.writeInt32(handle);
515}
516
517void IPCThreadState::decWeakHandle(int32_t handle)
518{
519 LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
520 mOut.writeInt32(BC_DECREFS);
521 mOut.writeInt32(handle);
522}
523
524status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
525{
526 mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
527 mOut.writeInt32(0); // xxx was thread priority
528 mOut.writeInt32(handle);
529 status_t result = UNKNOWN_ERROR;
530
531 waitForResponse(NULL, &result);
532
533#if LOG_REFCOUNTS
534 printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
535 handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
536#endif
537
538 return result;
539}
540
541void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
542{
543#if LOG_REFCOUNTS
544 printf("IPCThreadState::expungeHandle(%ld)\n", handle);
545#endif
546 self()->mProcess->expungeHandle(handle, binder);
547}
548
549status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
550{
551 mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
552 mOut.writeInt32((int32_t)handle);
553 mOut.writeInt32((int32_t)proxy);
554 return NO_ERROR;
555}
556
557status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
558{
559 mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
560 mOut.writeInt32((int32_t)handle);
561 mOut.writeInt32((int32_t)proxy);
562 return NO_ERROR;
563}
564
565IPCThreadState::IPCThreadState()
566 : mProcess(ProcessState::self())
567{
568 pthread_setspecific(gTLS, this);
569 clearCaller();
570 mIn.setDataCapacity(256);
571 mOut.setDataCapacity(256);
572}
573
574IPCThreadState::~IPCThreadState()
575{
576}
577
578status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
579{
580 status_t err;
581 status_t statusBuffer;
582 err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
583 if (err < NO_ERROR) return err;
584
585 return waitForResponse(NULL, NULL);
586}
587
588status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
589{
590 int32_t cmd;
591 int32_t err;
592
593 while (1) {
594 if ((err=talkWithDriver()) < NO_ERROR) break;
595 err = mIn.errorCheck();
596 if (err < NO_ERROR) break;
597 if (mIn.dataAvail() == 0) continue;
598
599 cmd = mIn.readInt32();
600
601 IF_LOG_COMMANDS() {
602 alog << "Processing waitForResponse Command: "
603 << getReturnString(cmd) << endl;
604 }
605
606 switch (cmd) {
607 case BR_TRANSACTION_COMPLETE:
608 if (!reply && !acquireResult) goto finish;
609 break;
610
611 case BR_DEAD_REPLY:
612 err = DEAD_OBJECT;
613 goto finish;
614
615 case BR_FAILED_REPLY:
616 err = FAILED_TRANSACTION;
617 goto finish;
618
619 case BR_ACQUIRE_RESULT:
620 {
621 LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
622 const int32_t result = mIn.readInt32();
623 if (!acquireResult) continue;
624 *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
625 }
626 goto finish;
627
628 case BR_REPLY:
629 {
630 binder_transaction_data tr;
631 err = mIn.read(&tr, sizeof(tr));
632 LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
633 if (err != NO_ERROR) goto finish;
634
635 if (reply) {
636 if ((tr.flags & TF_STATUS_CODE) == 0) {
637 reply->ipcSetDataReference(
638 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
639 tr.data_size,
640 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
641 tr.offsets_size/sizeof(size_t),
642 freeBuffer, this);
643 } else {
644 err = *static_cast<const status_t*>(tr.data.ptr.buffer);
645 freeBuffer(NULL,
646 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
647 tr.data_size,
648 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
649 tr.offsets_size/sizeof(size_t), this);
650 }
651 } else {
652 freeBuffer(NULL,
653 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
654 tr.data_size,
655 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
656 tr.offsets_size/sizeof(size_t), this);
657 continue;
658 }
659 }
660 goto finish;
661
662 default:
663 err = executeCommand(cmd);
664 if (err != NO_ERROR) goto finish;
665 break;
666 }
667 }
668
669finish:
670 if (err != NO_ERROR) {
671 if (acquireResult) *acquireResult = err;
672 if (reply) reply->setError(err);
673 mLastError = err;
674 }
675
676 return err;
677}
678
679status_t IPCThreadState::talkWithDriver(bool doReceive)
680{
681 LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
682
683 binder_write_read bwr;
684
685 // Is the read buffer empty?
686 const bool needRead = mIn.dataPosition() >= mIn.dataSize();
687
688 // We don't want to write anything if we are still reading
689 // from data left in the input buffer and the caller
690 // has requested to read the next data.
691 const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
692
693 bwr.write_size = outAvail;
694 bwr.write_buffer = (long unsigned int)mOut.data();
695
696 // This is what we'll read.
697 if (doReceive && needRead) {
698 bwr.read_size = mIn.dataCapacity();
699 bwr.read_buffer = (long unsigned int)mIn.data();
700 } else {
701 bwr.read_size = 0;
702 }
703
704 IF_LOG_COMMANDS() {
705 TextOutput::Bundle _b(alog);
706 if (outAvail != 0) {
707 alog << "Sending commands to driver: " << indent;
708 const void* cmds = (const void*)bwr.write_buffer;
709 const void* end = ((const uint8_t*)cmds)+bwr.write_size;
710 alog << HexDump(cmds, bwr.write_size) << endl;
711 while (cmds < end) cmds = printCommand(alog, cmds);
712 alog << dedent;
713 }
714 alog << "Size of receive buffer: " << bwr.read_size
715 << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
716 }
717
718 // Return immediately if there is nothing to do.
719 if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
720
721 bwr.write_consumed = 0;
722 bwr.read_consumed = 0;
723 status_t err;
724 do {
725 IF_LOG_COMMANDS() {
726 alog << "About to read/write, write size = " << mOut.dataSize() << endl;
727 }
728#if defined(HAVE_ANDROID_OS)
729 if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
730 err = NO_ERROR;
731 else
732 err = -errno;
733#else
734 err = INVALID_OPERATION;
735#endif
736 IF_LOG_COMMANDS() {
737 alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
738 }
739 } while (err == -EINTR);
740
741 IF_LOG_COMMANDS() {
742 alog << "Our err: " << (void*)err << ", write consumed: "
743 << bwr.write_consumed << " (of " << mOut.dataSize()
744 << "), read consumed: " << bwr.read_consumed << endl;
745 }
746
747 if (err >= NO_ERROR) {
748 if (bwr.write_consumed > 0) {
749 if (bwr.write_consumed < (ssize_t)mOut.dataSize())
750 mOut.remove(0, bwr.write_consumed);
751 else
752 mOut.setDataSize(0);
753 }
754 if (bwr.read_consumed > 0) {
755 mIn.setDataSize(bwr.read_consumed);
756 mIn.setDataPosition(0);
757 }
758 IF_LOG_COMMANDS() {
759 TextOutput::Bundle _b(alog);
760 alog << "Remaining data size: " << mOut.dataSize() << endl;
761 alog << "Received commands from driver: " << indent;
762 const void* cmds = mIn.data();
763 const void* end = mIn.data() + mIn.dataSize();
764 alog << HexDump(cmds, mIn.dataSize()) << endl;
765 while (cmds < end) cmds = printReturnCommand(alog, cmds);
766 alog << dedent;
767 }
768 return NO_ERROR;
769 }
770
771 return err;
772}
773
774status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
775 int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
776{
777 binder_transaction_data tr;
778
779 tr.target.handle = handle;
780 tr.code = code;
781 tr.flags = binderFlags;
782
783 const status_t err = data.errorCheck();
784 if (err == NO_ERROR) {
785 tr.data_size = data.ipcDataSize();
786 tr.data.ptr.buffer = data.ipcData();
787 tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
788 tr.data.ptr.offsets = data.ipcObjects();
789 } else if (statusBuffer) {
790 tr.flags |= TF_STATUS_CODE;
791 *statusBuffer = err;
792 tr.data_size = sizeof(status_t);
793 tr.data.ptr.buffer = statusBuffer;
794 tr.offsets_size = 0;
795 tr.data.ptr.offsets = NULL;
796 } else {
797 return (mLastError = err);
798 }
799
800 mOut.writeInt32(cmd);
801 mOut.write(&tr, sizeof(tr));
802
803 return NO_ERROR;
804}
805
806sp<BBinder> the_context_object;
807
808void setTheContextObject(sp<BBinder> obj)
809{
810 the_context_object = obj;
811}
812
813status_t IPCThreadState::executeCommand(int32_t cmd)
814{
815 BBinder* obj;
816 RefBase::weakref_type* refs;
817 status_t result = NO_ERROR;
818
819 switch (cmd) {
820 case BR_ERROR:
821 result = mIn.readInt32();
822 break;
823
824 case BR_OK:
825 break;
826
827 case BR_ACQUIRE:
828 refs = (RefBase::weakref_type*)mIn.readInt32();
829 obj = (BBinder*)mIn.readInt32();
830 LOG_ASSERT(refs->refBase() == obj,
831 "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
832 refs, obj, refs->refBase());
833 obj->incStrong(mProcess.get());
834 IF_LOG_REMOTEREFS() {
835 LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
836 obj->printRefs();
837 }
838 mOut.writeInt32(BC_ACQUIRE_DONE);
839 mOut.writeInt32((int32_t)refs);
840 mOut.writeInt32((int32_t)obj);
841 break;
842
843 case BR_RELEASE:
844 refs = (RefBase::weakref_type*)mIn.readInt32();
845 obj = (BBinder*)mIn.readInt32();
846 LOG_ASSERT(refs->refBase() == obj,
847 "BR_RELEASE: object %p does not match cookie %p (expected %p)",
848 refs, obj, refs->refBase());
849 IF_LOG_REMOTEREFS() {
850 LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
851 obj->printRefs();
852 }
853 mPendingStrongDerefs.push(obj);
854 break;
855
856 case BR_INCREFS:
857 refs = (RefBase::weakref_type*)mIn.readInt32();
858 obj = (BBinder*)mIn.readInt32();
859 refs->incWeak(mProcess.get());
860 mOut.writeInt32(BC_INCREFS_DONE);
861 mOut.writeInt32((int32_t)refs);
862 mOut.writeInt32((int32_t)obj);
863 break;
864
865 case BR_DECREFS:
866 refs = (RefBase::weakref_type*)mIn.readInt32();
867 obj = (BBinder*)mIn.readInt32();
868 // NOTE: This assertion is not valid, because the object may no
869 // longer exist (thus the (BBinder*)cast above resulting in a different
870 // memory address).
871 //LOG_ASSERT(refs->refBase() == obj,
872 // "BR_DECREFS: object %p does not match cookie %p (expected %p)",
873 // refs, obj, refs->refBase());
874 mPendingWeakDerefs.push(refs);
875 break;
876
877 case BR_ATTEMPT_ACQUIRE:
878 refs = (RefBase::weakref_type*)mIn.readInt32();
879 obj = (BBinder*)mIn.readInt32();
880
881 {
882 const bool success = refs->attemptIncStrong(mProcess.get());
883 LOG_ASSERT(success && refs->refBase() == obj,
884 "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
885 refs, obj, refs->refBase());
886
887 mOut.writeInt32(BC_ACQUIRE_RESULT);
888 mOut.writeInt32((int32_t)success);
889 }
890 break;
891
892 case BR_TRANSACTION:
893 {
894 binder_transaction_data tr;
895 result = mIn.read(&tr, sizeof(tr));
896 LOG_ASSERT(result == NO_ERROR,
897 "Not enough command data for brTRANSACTION");
898 if (result != NO_ERROR) break;
899
900 Parcel buffer;
901 buffer.ipcSetDataReference(
902 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
903 tr.data_size,
904 reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
905 tr.offsets_size/sizeof(size_t), freeBuffer, this);
906
907 const pid_t origPid = mCallingPid;
908 const uid_t origUid = mCallingUid;
909
910 mCallingPid = tr.sender_pid;
911 mCallingUid = tr.sender_euid;
912
913 //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
914
915 Parcel reply;
916 IF_LOG_TRANSACTIONS() {
917 TextOutput::Bundle _b(alog);
918 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
919 << " / obj " << tr.target.ptr << " / code "
920 << TypeCode(tr.code) << ": " << indent << buffer
921 << dedent << endl
922 << "Data addr = "
923 << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
924 << ", offsets addr="
925 << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
926 }
927 if (tr.target.ptr) {
928 sp<BBinder> b((BBinder*)tr.cookie);
929 const status_t error = b->transact(tr.code, buffer, &reply, 0);
930 if (error < NO_ERROR) reply.setError(error);
931
932 } else {
933 const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
934 if (error < NO_ERROR) reply.setError(error);
935 }
936
937 //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
938 // mCallingPid, origPid, origUid);
939
940 if ((tr.flags & TF_ONE_WAY) == 0) {
941 LOG_ONEWAY("Sending reply to %d!", mCallingPid);
942 sendReply(reply, 0);
943 } else {
944 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
945 }
946
947 mCallingPid = origPid;
948 mCallingUid = origUid;
949
950 IF_LOG_TRANSACTIONS() {
951 TextOutput::Bundle _b(alog);
952 alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
953 << tr.target.ptr << ": " << indent << reply << dedent << endl;
954 }
955
956 }
957 break;
958
959 case BR_DEAD_BINDER:
960 {
961 BpBinder *proxy = (BpBinder*)mIn.readInt32();
962 proxy->sendObituary();
963 mOut.writeInt32(BC_DEAD_BINDER_DONE);
964 mOut.writeInt32((int32_t)proxy);
965 } break;
966
967 case BR_CLEAR_DEATH_NOTIFICATION_DONE:
968 {
969 BpBinder *proxy = (BpBinder*)mIn.readInt32();
970 proxy->getWeakRefs()->decWeak(proxy);
971 } break;
972
973 case BR_FINISHED:
974 result = TIMED_OUT;
975 break;
976
977 case BR_NOOP:
978 break;
979
980 case BR_SPAWN_LOOPER:
981 mProcess->spawnPooledThread(false);
982 break;
983
984 default:
985 printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
986 result = UNKNOWN_ERROR;
987 break;
988 }
989
990 if (result != NO_ERROR) {
991 mLastError = result;
992 }
993
994 return result;
995}
996
997void IPCThreadState::threadDestructor(void *st)
998{
999 IPCThreadState* const self = static_cast<IPCThreadState*>(st);
1000 if (self) {
1001 self->flushCommands();
1002#if defined(HAVE_ANDROID_OS)
1003 ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
1004#endif
1005 delete self;
1006 }
1007}
1008
1009
1010void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
1011 const size_t* objects, size_t objectsSize,
1012 void* cookie)
1013{
1014 //LOGI("Freeing parcel %p", &parcel);
1015 IF_LOG_COMMANDS() {
1016 alog << "Writing BC_FREE_BUFFER for " << data << endl;
1017 }
1018 LOG_ASSERT(data != NULL, "Called with NULL data");
1019 if (parcel != NULL) parcel->closeFileDescriptors();
1020 IPCThreadState* state = self();
1021 state->mOut.writeInt32(BC_FREE_BUFFER);
1022 state->mOut.writeInt32((int32_t)data);
1023}
1024
1025}; // namespace android