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