diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
new file mode 100644
index 0000000..704a481
--- /dev/null
+++ b/libs/binder/IPCThreadState.cpp
@@ -0,0 +1,1030 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/IPCThreadState.h>
+
+#include <utils/Binder.h>
+#include <utils/BpBinder.h>
+#include <utils/Debug.h>
+#include <utils/Log.h>
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+
+#include <private/binder/binder_module.h>
+#include <private/binder/Static.h>
+
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifdef HAVE_PTHREADS
+#include <pthread.h>
+#include <sched.h>
+#include <sys/resource.h>
+#endif
+#ifdef HAVE_WIN32_THREADS
+#include <windows.h>
+#endif
+
+
+#if LOG_NDEBUG
+
+#define IF_LOG_TRANSACTIONS() if (false)
+#define IF_LOG_COMMANDS() if (false)
+#define LOG_REMOTEREFS(...) 
+#define IF_LOG_REMOTEREFS() if (false)
+#define LOG_THREADPOOL(...) 
+#define LOG_ONEWAY(...) 
+
+#else
+
+#define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
+#define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
+#define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
+#define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
+#define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
+#define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
+
+#endif
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+static const char* getReturnString(size_t idx);
+static const char* getCommandString(size_t idx);
+static const void* printReturnCommand(TextOutput& out, const void* _cmd);
+static const void* printCommand(TextOutput& out, const void* _cmd);
+
+// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
+// conditionals don't get stripped...  but that is probably what we want.
+#if !LOG_NDEBUG
+static const char *kReturnStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BR_OK",
+    "BR_TIMEOUT",
+    "BR_WAKEUP",
+    "BR_TRANSACTION",
+    "BR_REPLY",
+    "BR_ACQUIRE_RESULT",
+    "BR_DEAD_REPLY",
+    "BR_TRANSACTION_COMPLETE",
+    "BR_INCREFS",
+    "BR_ACQUIRE",
+    "BR_RELEASE",
+    "BR_DECREFS",
+    "BR_ATTEMPT_ACQUIRE",
+    "BR_EVENT_OCCURRED",
+    "BR_NOOP",
+    "BR_SPAWN_LOOPER",
+    "BR_FINISHED",
+    "BR_DEAD_BINDER",
+    "BR_CLEAR_DEATH_NOTIFICATION_DONE"
+#endif
+};
+
+static const char *kCommandStrings[] = {
+#if 1 /* TODO: error update strings */
+    "unknown",
+#else
+    "BC_NOOP",
+    "BC_TRANSACTION",
+    "BC_REPLY",
+    "BC_ACQUIRE_RESULT",
+    "BC_FREE_BUFFER",
+    "BC_TRANSACTION_COMPLETE",
+    "BC_INCREFS",
+    "BC_ACQUIRE",
+    "BC_RELEASE",
+    "BC_DECREFS",
+    "BC_INCREFS_DONE",
+    "BC_ACQUIRE_DONE",
+    "BC_ATTEMPT_ACQUIRE",
+    "BC_RETRIEVE_ROOT_OBJECT",
+    "BC_SET_THREAD_ENTRY",
+    "BC_REGISTER_LOOPER",
+    "BC_ENTER_LOOPER",
+    "BC_EXIT_LOOPER",
+    "BC_SYNC",
+    "BC_STOP_PROCESS",
+    "BC_STOP_SELF",
+    "BC_REQUEST_DEATH_NOTIFICATION",
+    "BC_CLEAR_DEATH_NOTIFICATION",
+    "BC_DEAD_BINDER_DONE"
+#endif
+};
+
+static const char* getReturnString(size_t idx)
+{
+    if (idx < sizeof(kReturnStrings) / sizeof(kReturnStrings[0]))
+        return kReturnStrings[idx];
+    else
+        return "unknown";
+}
+
+static const char* getCommandString(size_t idx)
+{
+    if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
+        return kCommandStrings[idx];
+    else
+        return "unknown";
+}
+
+static const void* printBinderTransactionData(TextOutput& out, const void* data)
+{
+    const binder_transaction_data* btd =
+        (const binder_transaction_data*)data;
+    out << "target=" << btd->target.ptr << " (cookie " << btd->cookie << ")" << endl
+        << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
+        << "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
+        << " bytes)" << endl
+        << "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
+        << " bytes)" << endl;
+    return btd+1;
+}
+
+static const void* printReturnCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code == BR_ERROR) {
+        out << "BR_ERROR: " << (void*)(*cmd++) << endl;
+        return cmd;
+    } else if (code < 0 || code >= N) {
+        out << "Unknown reply: " << code << endl;
+        return cmd;
+    }
+    
+    out << kReturnStrings[code];
+    switch (code) {
+        case BR_TRANSACTION:
+        case BR_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BR_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BR_INCREFS:
+        case BR_ACQUIRE:
+        case BR_RELEASE:
+        case BR_DECREFS: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+    
+        case BR_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c
+                << "), pri=" << p;
+        } break;
+
+        case BR_DEAD_BINDER:
+        case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+
+static const void* printCommand(TextOutput& out, const void* _cmd)
+{
+    static const int32_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
+    
+    const int32_t* cmd = (const int32_t*)_cmd;
+    int32_t code = *cmd++;
+    if (code < 0 || code >= N) {
+        out << "Unknown command: " << code << endl;
+        return cmd;
+    }
+    
+    out << kCommandStrings[code];
+    switch (code) {
+        case BC_TRANSACTION:
+        case BC_REPLY: {
+            out << ": " << indent;
+            cmd = (const int32_t *)printBinderTransactionData(out, cmd);
+            out << dedent;
+        } break;
+        
+        case BC_ACQUIRE_RESULT: {
+            const int32_t res = *cmd++;
+            out << ": " << res << (res ? " (SUCCESS)" : " (FAILURE)");
+        } break;
+        
+        case BC_FREE_BUFFER: {
+            const int32_t buf = *cmd++;
+            out << ": buffer=" << (void*)buf;
+        } break;
+        
+        case BC_INCREFS:
+        case BC_ACQUIRE:
+        case BC_RELEASE:
+        case BC_DECREFS: {
+            const int32_t d = *cmd++;
+            out << ": descriptor=" << (void*)d;
+        } break;
+    
+        case BC_INCREFS_DONE:
+        case BC_ACQUIRE_DONE: {
+            const int32_t b = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+        } break;
+        
+        case BC_ATTEMPT_ACQUIRE: {
+            const int32_t p = *cmd++;
+            const int32_t d = *cmd++;
+            out << ": decriptor=" << (void*)d << ", pri=" << p;
+        } break;
+        
+        case BC_REQUEST_DEATH_NOTIFICATION:
+        case BC_CLEAR_DEATH_NOTIFICATION: {
+            const int32_t h = *cmd++;
+            const int32_t c = *cmd++;
+            out << ": handle=" << h << " (death cookie " << (void*)c << ")";
+        } break;
+
+        case BC_DEAD_BINDER_DONE: {
+            const int32_t c = *cmd++;
+            out << ": death cookie " << (void*)c;
+        } break;
+    }
+    
+    out << endl;
+    return cmd;
+}
+#endif
+
+static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool gHaveTLS = false;
+static pthread_key_t gTLS = 0;
+static bool gShutdown = false;
+
+IPCThreadState* IPCThreadState::self()
+{
+    if (gHaveTLS) {
+restart:
+        const pthread_key_t k = gTLS;
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
+        if (st) return st;
+        return new IPCThreadState;
+    }
+    
+    if (gShutdown) return NULL;
+    
+    pthread_mutex_lock(&gTLSMutex);
+    if (!gHaveTLS) {
+        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
+            pthread_mutex_unlock(&gTLSMutex);
+            return NULL;
+        }
+        gHaveTLS = true;
+    }
+    pthread_mutex_unlock(&gTLSMutex);
+    goto restart;
+}
+
+void IPCThreadState::shutdown()
+{
+    gShutdown = true;
+    
+    if (gHaveTLS) {
+        // XXX Need to wait for all thread pool threads to exit!
+        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(gTLS);
+        if (st) {
+            delete st;
+            pthread_setspecific(gTLS, NULL);
+        }
+        gHaveTLS = false;
+    }
+}
+
+sp<ProcessState> IPCThreadState::process()
+{
+    return mProcess;
+}
+
+status_t IPCThreadState::clearLastError()
+{
+    const status_t err = mLastError;
+    mLastError = NO_ERROR;
+    return err;
+}
+
+int IPCThreadState::getCallingPid()
+{
+    return mCallingPid;
+}
+
+int IPCThreadState::getCallingUid()
+{
+    return mCallingUid;
+}
+
+int64_t IPCThreadState::clearCallingIdentity()
+{
+    int64_t token = ((int64_t)mCallingUid<<32) | mCallingPid;
+    clearCaller();
+    return token;
+}
+
+void IPCThreadState::restoreCallingIdentity(int64_t token)
+{
+    mCallingUid = (int)(token>>32);
+    mCallingPid = (int)token;
+}
+
+void IPCThreadState::clearCaller()
+{
+    if (mProcess->supportsProcesses()) {
+        mCallingPid = getpid();
+        mCallingUid = getuid();
+    } else {
+        mCallingPid = -1;
+        mCallingUid = -1;
+    }
+}
+
+void IPCThreadState::flushCommands()
+{
+    if (mProcess->mDriverFD <= 0)
+        return;
+    talkWithDriver(false);
+}
+
+void IPCThreadState::joinThreadPool(bool isMain)
+{
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
+
+    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
+    
+    status_t result;
+    do {
+        int32_t cmd;
+        
+        // When we've cleared the incoming command queue, process any pending derefs
+        if (mIn.dataPosition() >= mIn.dataSize()) {
+            size_t numPending = mPendingWeakDerefs.size();
+            if (numPending > 0) {
+                for (size_t i = 0; i < numPending; i++) {
+                    RefBase::weakref_type* refs = mPendingWeakDerefs[i];
+                    refs->decWeak(mProcess.get());
+                }
+                mPendingWeakDerefs.clear();
+            }
+
+            numPending = mPendingStrongDerefs.size();
+            if (numPending > 0) {
+                for (size_t i = 0; i < numPending; i++) {
+                    BBinder* obj = mPendingStrongDerefs[i];
+                    obj->decStrong(mProcess.get());
+                }
+                mPendingStrongDerefs.clear();
+            }
+        }
+
+        // now get the next command to be processed, waiting if necessary
+        result = talkWithDriver();
+        if (result >= NO_ERROR) {
+            size_t IN = mIn.dataAvail();
+            if (IN < sizeof(int32_t)) continue;
+            cmd = mIn.readInt32();
+            IF_LOG_COMMANDS() {
+                alog << "Processing top-level Command: "
+                    << getReturnString(cmd) << endl;
+            }
+            result = executeCommand(cmd);
+        }
+        
+        // Let this thread exit the thread pool if it is no longer
+        // needed and it is not the main process thread.
+        if(result == TIMED_OUT && !isMain) {
+            break;
+        }
+    } while (result != -ECONNREFUSED && result != -EBADF);
+
+    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
+        (void*)pthread_self(), getpid(), (void*)result);
+    
+    mOut.writeInt32(BC_EXIT_LOOPER);
+    talkWithDriver(false);
+}
+
+void IPCThreadState::stopProcess(bool immediate)
+{
+    //LOGI("**** STOPPING PROCESS");
+    flushCommands();
+    int fd = mProcess->mDriverFD;
+    mProcess->mDriverFD = -1;
+    close(fd);
+    //kill(getpid(), SIGKILL);
+}
+
+status_t IPCThreadState::transact(int32_t handle,
+                                  uint32_t code, const Parcel& data,
+                                  Parcel* reply, uint32_t flags)
+{
+    status_t err = data.errorCheck();
+
+    flags |= TF_ACCEPT_FDS;
+
+    IF_LOG_TRANSACTIONS() {
+        TextOutput::Bundle _b(alog);
+        alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
+            << handle << " / code " << TypeCode(code) << ": "
+            << indent << data << dedent << endl;
+    }
+    
+    if (err == NO_ERROR) {
+        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
+            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
+        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
+    }
+    
+    if (err != NO_ERROR) {
+        if (reply) reply->setError(err);
+        return (mLastError = err);
+    }
+    
+    if ((flags & TF_ONE_WAY) == 0) {
+        if (reply) {
+            err = waitForResponse(reply);
+        } else {
+            Parcel fakeReply;
+            err = waitForResponse(&fakeReply);
+        }
+        
+        IF_LOG_TRANSACTIONS() {
+            TextOutput::Bundle _b(alog);
+            alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
+                << handle << ": ";
+            if (reply) alog << indent << *reply << dedent << endl;
+            else alog << "(none requested)" << endl;
+        }
+    } else {
+        err = waitForResponse(NULL, NULL);
+    }
+    
+    return err;
+}
+
+void IPCThreadState::incStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_ACQUIRE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decStrongHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle);
+    mOut.writeInt32(BC_RELEASE);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::incWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_INCREFS);
+    mOut.writeInt32(handle);
+}
+
+void IPCThreadState::decWeakHandle(int32_t handle)
+{
+    LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle);
+    mOut.writeInt32(BC_DECREFS);
+    mOut.writeInt32(handle);
+}
+
+status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
+{
+    mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
+    mOut.writeInt32(0); // xxx was thread priority
+    mOut.writeInt32(handle);
+    status_t result = UNKNOWN_ERROR;
+    
+    waitForResponse(NULL, &result);
+    
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::attemptIncStrongHandle(%ld) = %s\n",
+        handle, result == NO_ERROR ? "SUCCESS" : "FAILURE");
+#endif
+    
+    return result;
+}
+
+void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
+{
+#if LOG_REFCOUNTS
+    printf("IPCThreadState::expungeHandle(%ld)\n", handle);
+#endif
+    self()->mProcess->expungeHandle(handle, binder);
+}
+
+status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
+{
+    mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
+    mOut.writeInt32((int32_t)handle);
+    mOut.writeInt32((int32_t)proxy);
+    return NO_ERROR;
+}
+
+IPCThreadState::IPCThreadState()
+    : mProcess(ProcessState::self())
+{
+    pthread_setspecific(gTLS, this);
+        clearCaller();
+    mIn.setDataCapacity(256);
+    mOut.setDataCapacity(256);
+}
+
+IPCThreadState::~IPCThreadState()
+{
+}
+
+status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
+{
+    status_t err;
+    status_t statusBuffer;
+    err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
+    if (err < NO_ERROR) return err;
+    
+    return waitForResponse(NULL, NULL);
+}
+
+status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
+{
+    int32_t cmd;
+    int32_t err;
+
+    while (1) {
+        if ((err=talkWithDriver()) < NO_ERROR) break;
+        err = mIn.errorCheck();
+        if (err < NO_ERROR) break;
+        if (mIn.dataAvail() == 0) continue;
+        
+        cmd = mIn.readInt32();
+        
+        IF_LOG_COMMANDS() {
+            alog << "Processing waitForResponse Command: "
+                << getReturnString(cmd) << endl;
+        }
+
+        switch (cmd) {
+        case BR_TRANSACTION_COMPLETE:
+            if (!reply && !acquireResult) goto finish;
+            break;
+        
+        case BR_DEAD_REPLY:
+            err = DEAD_OBJECT;
+            goto finish;
+
+        case BR_FAILED_REPLY:
+            err = FAILED_TRANSACTION;
+            goto finish;
+        
+        case BR_ACQUIRE_RESULT:
+            {
+                LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
+                const int32_t result = mIn.readInt32();
+                if (!acquireResult) continue;
+                *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
+            }
+            goto finish;
+        
+        case BR_REPLY:
+            {
+                binder_transaction_data tr;
+                err = mIn.read(&tr, sizeof(tr));
+                LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
+                if (err != NO_ERROR) goto finish;
+
+                if (reply) {
+                    if ((tr.flags & TF_STATUS_CODE) == 0) {
+                        reply->ipcSetDataReference(
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t),
+                            freeBuffer, this);
+                    } else {
+                        err = *static_cast<const status_t*>(tr.data.ptr.buffer);
+                        freeBuffer(NULL,
+                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                            tr.data_size,
+                            reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(size_t), this);
+                    }
+                } else {
+                    freeBuffer(NULL,
+                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                        tr.data_size,
+                        reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                        tr.offsets_size/sizeof(size_t), this);
+                    continue;
+                }
+            }
+            goto finish;
+
+        default:
+            err = executeCommand(cmd);
+            if (err != NO_ERROR) goto finish;
+            break;
+        }
+    }
+
+finish:
+    if (err != NO_ERROR) {
+        if (acquireResult) *acquireResult = err;
+        if (reply) reply->setError(err);
+        mLastError = err;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::talkWithDriver(bool doReceive)
+{
+    LOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
+    
+    binder_write_read bwr;
+    
+    // Is the read buffer empty?
+    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
+    
+    // We don't want to write anything if we are still reading
+    // from data left in the input buffer and the caller
+    // has requested to read the next data.
+    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
+    
+    bwr.write_size = outAvail;
+    bwr.write_buffer = (long unsigned int)mOut.data();
+
+    // This is what we'll read.
+    if (doReceive && needRead) {
+        bwr.read_size = mIn.dataCapacity();
+        bwr.read_buffer = (long unsigned int)mIn.data();
+    } else {
+        bwr.read_size = 0;
+    }
+    
+    IF_LOG_COMMANDS() {
+        TextOutput::Bundle _b(alog);
+        if (outAvail != 0) {
+            alog << "Sending commands to driver: " << indent;
+            const void* cmds = (const void*)bwr.write_buffer;
+            const void* end = ((const uint8_t*)cmds)+bwr.write_size;
+            alog << HexDump(cmds, bwr.write_size) << endl;
+            while (cmds < end) cmds = printCommand(alog, cmds);
+            alog << dedent;
+        }
+        alog << "Size of receive buffer: " << bwr.read_size
+            << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
+    }
+    
+    // Return immediately if there is nothing to do.
+    if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
+    
+    bwr.write_consumed = 0;
+    bwr.read_consumed = 0;
+    status_t err;
+    do {
+        IF_LOG_COMMANDS() {
+            alog << "About to read/write, write size = " << mOut.dataSize() << endl;
+        }
+#if defined(HAVE_ANDROID_OS)
+        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
+            err = NO_ERROR;
+        else
+            err = -errno;
+#else
+        err = INVALID_OPERATION;
+#endif
+        IF_LOG_COMMANDS() {
+            alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
+        }
+    } while (err == -EINTR);
+    
+    IF_LOG_COMMANDS() {
+        alog << "Our err: " << (void*)err << ", write consumed: "
+            << bwr.write_consumed << " (of " << mOut.dataSize()
+			<< "), read consumed: " << bwr.read_consumed << endl;
+    }
+
+    if (err >= NO_ERROR) {
+        if (bwr.write_consumed > 0) {
+            if (bwr.write_consumed < (ssize_t)mOut.dataSize())
+                mOut.remove(0, bwr.write_consumed);
+            else
+                mOut.setDataSize(0);
+        }
+        if (bwr.read_consumed > 0) {
+            mIn.setDataSize(bwr.read_consumed);
+            mIn.setDataPosition(0);
+        }
+        IF_LOG_COMMANDS() {
+            TextOutput::Bundle _b(alog);
+            alog << "Remaining data size: " << mOut.dataSize() << endl;
+            alog << "Received commands from driver: " << indent;
+            const void* cmds = mIn.data();
+            const void* end = mIn.data() + mIn.dataSize();
+            alog << HexDump(cmds, mIn.dataSize()) << endl;
+            while (cmds < end) cmds = printReturnCommand(alog, cmds);
+            alog << dedent;
+        }
+        return NO_ERROR;
+    }
+    
+    return err;
+}
+
+status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
+    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
+{
+    binder_transaction_data tr;
+
+    tr.target.handle = handle;
+    tr.code = code;
+    tr.flags = binderFlags;
+    
+    const status_t err = data.errorCheck();
+    if (err == NO_ERROR) {
+        tr.data_size = data.ipcDataSize();
+        tr.data.ptr.buffer = data.ipcData();
+        tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
+        tr.data.ptr.offsets = data.ipcObjects();
+    } else if (statusBuffer) {
+        tr.flags |= TF_STATUS_CODE;
+        *statusBuffer = err;
+        tr.data_size = sizeof(status_t);
+        tr.data.ptr.buffer = statusBuffer;
+        tr.offsets_size = 0;
+        tr.data.ptr.offsets = NULL;
+    } else {
+        return (mLastError = err);
+    }
+    
+    mOut.writeInt32(cmd);
+    mOut.write(&tr, sizeof(tr));
+    
+    return NO_ERROR;
+}
+
+sp<BBinder> the_context_object;
+
+void setTheContextObject(sp<BBinder> obj)
+{
+    the_context_object = obj;
+}
+
+status_t IPCThreadState::executeCommand(int32_t cmd)
+{
+    BBinder* obj;
+    RefBase::weakref_type* refs;
+    status_t result = NO_ERROR;
+    
+    switch (cmd) {
+    case BR_ERROR:
+        result = mIn.readInt32();
+        break;
+        
+    case BR_OK:
+        break;
+        
+    case BR_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        obj->incStrong(mProcess.get());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
+            obj->printRefs();
+        }
+        mOut.writeInt32(BC_ACQUIRE_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_RELEASE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        LOG_ASSERT(refs->refBase() == obj,
+                   "BR_RELEASE: object %p does not match cookie %p (expected %p)",
+                   refs, obj, refs->refBase());
+        IF_LOG_REMOTEREFS() {
+            LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
+            obj->printRefs();
+        }
+        mPendingStrongDerefs.push(obj);
+        break;
+        
+    case BR_INCREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        refs->incWeak(mProcess.get());
+        mOut.writeInt32(BC_INCREFS_DONE);
+        mOut.writeInt32((int32_t)refs);
+        mOut.writeInt32((int32_t)obj);
+        break;
+        
+    case BR_DECREFS:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+        // NOTE: This assertion is not valid, because the object may no
+        // longer exist (thus the (BBinder*)cast above resulting in a different
+        // memory address).
+        //LOG_ASSERT(refs->refBase() == obj,
+        //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
+        //           refs, obj, refs->refBase());
+        mPendingWeakDerefs.push(refs);
+        break;
+        
+    case BR_ATTEMPT_ACQUIRE:
+        refs = (RefBase::weakref_type*)mIn.readInt32();
+        obj = (BBinder*)mIn.readInt32();
+         
+        {
+            const bool success = refs->attemptIncStrong(mProcess.get());
+            LOG_ASSERT(success && refs->refBase() == obj,
+                       "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
+                       refs, obj, refs->refBase());
+            
+            mOut.writeInt32(BC_ACQUIRE_RESULT);
+            mOut.writeInt32((int32_t)success);
+        }
+        break;
+    
+    case BR_TRANSACTION:
+        {
+            binder_transaction_data tr;
+            result = mIn.read(&tr, sizeof(tr));
+            LOG_ASSERT(result == NO_ERROR,
+                "Not enough command data for brTRANSACTION");
+            if (result != NO_ERROR) break;
+            
+            Parcel buffer;
+            buffer.ipcSetDataReference(
+                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
+                tr.data_size,
+                reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
+                tr.offsets_size/sizeof(size_t), freeBuffer, this);
+            
+            const pid_t origPid = mCallingPid;
+            const uid_t origUid = mCallingUid;
+            
+            mCallingPid = tr.sender_pid;
+            mCallingUid = tr.sender_euid;
+            
+            //LOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
+            
+            Parcel reply;
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BR_TRANSACTION thr " << (void*)pthread_self()
+                    << " / obj " << tr.target.ptr << " / code "
+                    << TypeCode(tr.code) << ": " << indent << buffer
+                    << dedent << endl
+                    << "Data addr = "
+                    << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
+                    << ", offsets addr="
+                    << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
+            }
+            if (tr.target.ptr) {
+                sp<BBinder> b((BBinder*)tr.cookie);
+                const status_t error = b->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+                
+            } else {
+                const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+                if (error < NO_ERROR) reply.setError(error);
+            }
+            
+            //LOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
+            //     mCallingPid, origPid, origUid);
+            
+            if ((tr.flags & TF_ONE_WAY) == 0) {
+                LOG_ONEWAY("Sending reply to %d!", mCallingPid);
+                sendReply(reply, 0);
+            } else {
+                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
+            }
+            
+            mCallingPid = origPid;
+            mCallingUid = origUid;
+            
+            IF_LOG_TRANSACTIONS() {
+                TextOutput::Bundle _b(alog);
+                alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
+                    << tr.target.ptr << ": " << indent << reply << dedent << endl;
+            }
+            
+        }
+        break;
+    
+    case BR_DEAD_BINDER:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->sendObituary();
+            mOut.writeInt32(BC_DEAD_BINDER_DONE);
+            mOut.writeInt32((int32_t)proxy);
+        } break;
+        
+    case BR_CLEAR_DEATH_NOTIFICATION_DONE:
+        {
+            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            proxy->getWeakRefs()->decWeak(proxy);
+        } break;
+        
+    case BR_FINISHED:
+        result = TIMED_OUT;
+        break;
+        
+    case BR_NOOP:
+        break;
+        
+    case BR_SPAWN_LOOPER:
+        mProcess->spawnPooledThread(false);
+        break;
+        
+    default:
+        printf("*** BAD COMMAND %d received from Binder driver\n", cmd);
+        result = UNKNOWN_ERROR;
+        break;
+    }
+
+    if (result != NO_ERROR) {
+        mLastError = result;
+    }
+    
+    return result;
+}
+
+void IPCThreadState::threadDestructor(void *st)
+{
+	IPCThreadState* const self = static_cast<IPCThreadState*>(st);
+	if (self) {
+		self->flushCommands();
+#if defined(HAVE_ANDROID_OS)
+        ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
+#endif
+		delete self;
+	}
+}
+
+
+void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
+                                const size_t* objects, size_t objectsSize,
+                                void* cookie)
+{
+    //LOGI("Freeing parcel %p", &parcel);
+    IF_LOG_COMMANDS() {
+        alog << "Writing BC_FREE_BUFFER for " << data << endl;
+    }
+    LOG_ASSERT(data != NULL, "Called with NULL data");
+    if (parcel != NULL) parcel->closeFileDescriptors();
+    IPCThreadState* state = self();
+    state->mOut.writeInt32(BC_FREE_BUFFER);
+    state->mOut.writeInt32((int32_t)data);
+}
+
+}; // namespace android
