IPCThreadState.cpp revision d43b194b69fca6c81023effc921fcc7576bad496
1/*
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 <binder/IPCThreadState.h>
18
19#include <binder/Binder.h>
20#include <binder/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/binder/binder_module.h>
27#include <private/binder/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    mCallingPid = getpid();
370    mCallingUid = getuid();
371}
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
1026