Sanity check IMemory access versus underlying mmap am: 94b0d4e3ab
am: ef6908e2b3

* commit 'ef6908e2b3e6ee6514620acc338b458ade7c3640':
  Sanity check IMemory access versus underlying mmap
diff --git a/Android.mk b/Android.mk
index f3f8daf..79decfe 100644
--- a/Android.mk
+++ b/Android.mk
@@ -21,6 +21,7 @@
     Debug.cpp \
     IAppOpsCallback.cpp \
     IAppOpsService.cpp \
+    IBatteryStats.cpp \
     IInterface.cpp \
     IMemory.cpp \
     IPCThreadState.cpp \
@@ -38,15 +39,25 @@
 LOCAL_PATH:= $(call my-dir)
 
 include $(CLEAR_VARS)
-LOCAL_LDLIBS += -lpthread
 LOCAL_MODULE := libbinder
 LOCAL_SHARED_LIBRARIES := liblog libcutils libutils
 LOCAL_SRC_FILES := $(sources)
+ifneq ($(TARGET_USES_64_BIT_BINDER),true)
+ifneq ($(TARGET_IS_64_BIT),true)
+LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1
+endif
+endif
+LOCAL_CFLAGS += -Werror
 include $(BUILD_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
-LOCAL_LDLIBS += -lpthread
 LOCAL_MODULE := libbinder
 LOCAL_STATIC_LIBRARIES += libutils
 LOCAL_SRC_FILES := $(sources)
+ifneq ($(TARGET_USES_64_BIT_BINDER),true)
+ifneq ($(TARGET_IS_64_BIT),true)
+LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1
+endif
+endif
+LOCAL_CFLAGS += -Werror
 include $(BUILD_STATIC_LIBRARY)
diff --git a/Binder.cpp b/Binder.cpp
index 1f21f9c..2554351 100644
--- a/Binder.cpp
+++ b/Binder.cpp
@@ -16,7 +16,7 @@
 
 #include <binder/Binder.h>
 
-#include <utils/Atomic.h>
+#include <stdatomic.h>
 #include <utils/misc.h>
 #include <binder/BpBinder.h>
 #include <binder/IInterface.h>
@@ -39,7 +39,7 @@
 
 // ---------------------------------------------------------------------------
 
-sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
+sp<IInterface>  IBinder::queryLocalInterface(const String16& /*descriptor*/)
 {
     return NULL;
 }
@@ -71,8 +71,8 @@
 // ---------------------------------------------------------------------------
 
 BBinder::BBinder()
-    : mExtras(NULL)
 {
+    atomic_init(&mExtras, 0);
 }
 
 bool BBinder::isBinderAlive() const
@@ -117,19 +117,20 @@
 }
 
 status_t BBinder::linkToDeath(
-    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags)
+    const sp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
+    uint32_t /*flags*/)
 {
     return INVALID_OPERATION;
 }
 
 status_t BBinder::unlinkToDeath(
-    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,
-    wp<DeathRecipient>* outRecipient)
+    const wp<DeathRecipient>& /*recipient*/, void* /*cookie*/,
+    uint32_t /*flags*/, wp<DeathRecipient>* /*outRecipient*/)
 {
     return INVALID_OPERATION;
 }
 
-status_t BBinder::dump(int fd, const Vector<String16>& args)
+    status_t BBinder::dump(int /*fd*/, const Vector<String16>& /*args*/)
 {
     return NO_ERROR;
 }
@@ -138,14 +139,19 @@
     const void* objectID, void* object, void* cleanupCookie,
     object_cleanup_func func)
 {
-    Extras* e = mExtras;
+    Extras* e = reinterpret_cast<Extras*>(
+                    atomic_load_explicit(&mExtras, memory_order_acquire));
 
     if (!e) {
         e = new Extras;
-        if (android_atomic_cmpxchg(0, reinterpret_cast<int32_t>(e),
-                reinterpret_cast<volatile int32_t*>(&mExtras)) != 0) {
+        uintptr_t expected = 0;
+        if (!atomic_compare_exchange_strong_explicit(
+                                        &mExtras, &expected,
+                                        reinterpret_cast<uintptr_t>(e),
+                                        memory_order_release,
+                                        memory_order_acquire)) {
             delete e;
-            e = mExtras;
+            e = reinterpret_cast<Extras*>(expected);  // Filled in by CAS
         }
         if (e == 0) return; // out of memory
     }
@@ -156,7 +162,8 @@
 
 void* BBinder::findObject(const void* objectID) const
 {
-    Extras* e = mExtras;
+    Extras* e = reinterpret_cast<Extras*>(
+                    atomic_load_explicit(&mExtras, memory_order_acquire));
     if (!e) return NULL;
 
     AutoMutex _l(e->mLock);
@@ -165,7 +172,8 @@
 
 void BBinder::detachObject(const void* objectID)
 {
-    Extras* e = mExtras;
+    Extras* e = reinterpret_cast<Extras*>(
+                    atomic_load_explicit(&mExtras, memory_order_acquire));
     if (!e) return;
 
     AutoMutex _l(e->mLock);
@@ -179,12 +187,14 @@
 
 BBinder::~BBinder()
 {
-    if (mExtras) delete mExtras;
+    Extras* e = reinterpret_cast<Extras*>(
+                    atomic_load_explicit(&mExtras, memory_order_relaxed));
+    if (e) delete e;
 }
 
 
 status_t BBinder::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t /*flags*/)
 {
     switch (code) {
         case INTERFACE_TRANSACTION:
@@ -246,14 +256,14 @@
     android_atomic_or(kRemoteAcquired, &mState);
 }
 
-void BpRefBase::onLastStrongRef(const void* id)
+void BpRefBase::onLastStrongRef(const void* /*id*/)
 {
     if (mRemote) {
         mRemote->decStrong(this);
     }
 }
 
-bool BpRefBase::onIncStrongAttempted(uint32_t flags, const void* id)
+bool BpRefBase::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
 {
     return mRemote ? mRefs->attemptIncStrong(this) : false;
 }
diff --git a/BpBinder.cpp b/BpBinder.cpp
index 47a62db..101de7e 100644
--- a/BpBinder.cpp
+++ b/BpBinder.cpp
@@ -73,7 +73,7 @@
 void BpBinder::ObjectManager::kill()
 {
     const size_t N = mObjects.size();
-    ALOGV("Killing %d objects in manager %p", N, this);
+    ALOGV("Killing %zu objects in manager %p", N, this);
     for (size_t i=0; i<N; i++) {
         const entry_t& e = mObjects.valueAt(i);
         if (e.func != NULL) {
@@ -119,11 +119,11 @@
                 mDescriptorCache = res;
         }
     }
-    
+
     // we're returning a reference to a non-static object here. Usually this
-    // is not something smart to do, however, with binder objects it is 
+    // is not something smart to do, however, with binder objects it is
     // (usually) safe because they are reference-counted.
-    
+
     return mDescriptorCache;
 }
 
@@ -260,8 +260,8 @@
     mObitsSent = 1;
     mLock.unlock();
 
-    ALOGV("Reporting death of proxy %p for %d recipients\n",
-        this, obits ? obits->size() : 0);
+    ALOGV("Reporting death of proxy %p for %zu recipients\n",
+        this, obits ? obits->size() : 0U);
 
     if (obits != NULL) {
         const size_t N = obits->size();
@@ -343,7 +343,7 @@
     if (ipc) ipc->incStrongHandle(mHandle);
 }
 
-void BpBinder::onLastStrongRef(const void* id)
+void BpBinder::onLastStrongRef(const void* /*id*/)
 {
     ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
     IF_ALOGV() {
@@ -353,7 +353,7 @@
     if (ipc) ipc->decStrongHandle(mHandle);
 }
 
-bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
+bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/)
 {
     ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
     IPCThreadState* ipc = IPCThreadState::self();
diff --git a/Debug.cpp b/Debug.cpp
index a8b6e83..0ffafbb 100644
--- a/Debug.cpp
+++ b/Debug.cpp
@@ -38,7 +38,7 @@
 
 // ---------------------------------------------------------------------
 
-static void defaultPrintFunc(void* cookie, const char* txt)
+static void defaultPrintFunc(void* /*cookie*/, const char* txt)
 {
     printf("%s", txt);
 }
diff --git a/IAppOpsCallback.cpp b/IAppOpsCallback.cpp
index e0aad23..2aaf566 100644
--- a/IAppOpsCallback.cpp
+++ b/IAppOpsCallback.cpp
@@ -18,7 +18,6 @@
 
 #include <binder/IAppOpsCallback.h>
 
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <binder/Parcel.h>
 #include <utils/String8.h>
diff --git a/IAppOpsService.cpp b/IAppOpsService.cpp
index 471e3e9..f58a352 100644
--- a/IAppOpsService.cpp
+++ b/IAppOpsService.cpp
@@ -18,7 +18,6 @@
 
 #include <binder/IAppOpsService.h>
 
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <binder/Parcel.h>
 #include <utils/String8.h>
diff --git a/IBatteryStats.cpp b/IBatteryStats.cpp
new file mode 100644
index 0000000..8f3b7b4
--- /dev/null
+++ b/IBatteryStats.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013 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 <binder/IBatteryStats.h>
+
+#include <utils/Log.h>
+#include <binder/Parcel.h>
+#include <utils/String8.h>
+
+#include <private/binder/Static.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class BpBatteryStats : public BpInterface<IBatteryStats>
+{
+public:
+    BpBatteryStats(const sp<IBinder>& impl)
+        : BpInterface<IBatteryStats>(impl)
+    {
+    }
+
+    virtual void noteStartSensor(int uid, int sensor) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        data.writeInt32(sensor);
+        remote()->transact(NOTE_START_SENSOR_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteStopSensor(int uid, int sensor) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        data.writeInt32(sensor);
+        remote()->transact(NOTE_STOP_SENSOR_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteStartVideo(int uid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        remote()->transact(NOTE_START_VIDEO_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteStopVideo(int uid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        remote()->transact(NOTE_STOP_VIDEO_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteStartAudio(int uid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        remote()->transact(NOTE_START_AUDIO_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteStopAudio(int uid) {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        data.writeInt32(uid);
+        remote()->transact(NOTE_STOP_AUDIO_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteResetVideo() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        remote()->transact(NOTE_RESET_VIDEO_TRANSACTION, data, &reply);
+    }
+
+    virtual void noteResetAudio() {
+        Parcel data, reply;
+        data.writeInterfaceToken(IBatteryStats::getInterfaceDescriptor());
+        remote()->transact(NOTE_RESET_AUDIO_TRANSACTION, data, &reply);
+    }
+};
+
+IMPLEMENT_META_INTERFACE(BatteryStats, "com.android.internal.app.IBatteryStats");
+
+// ----------------------------------------------------------------------
+
+status_t BnBatteryStats::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case NOTE_START_SENSOR_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            int sensor = data.readInt32();
+            noteStartSensor(uid, sensor);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_STOP_SENSOR_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            int sensor = data.readInt32();
+            noteStopSensor(uid, sensor);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_START_VIDEO_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            noteStartVideo(uid);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_STOP_VIDEO_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            noteStopVideo(uid);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_START_AUDIO_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            noteStartAudio(uid);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_STOP_AUDIO_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            int uid = data.readInt32();
+            noteStopAudio(uid);
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_RESET_VIDEO_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            noteResetVideo();
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        case NOTE_RESET_AUDIO_TRANSACTION: {
+            CHECK_INTERFACE(IBatteryStats, data, reply);
+            noteResetAudio();
+            reply->writeNoException();
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+}; // namespace android
diff --git a/IMemory.cpp b/IMemory.cpp
index 99df06d..b9a8bce 100644
--- a/IMemory.cpp
+++ b/IMemory.cpp
@@ -256,7 +256,7 @@
                 sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
 
                 if (VERBOSE) {
-                    ALOGD("UNMAPPING binder=%p, heap=%p, size=%d, fd=%d",
+                    ALOGD("UNMAPPING binder=%p, heap=%p, size=%zu, fd=%d",
                             binder.get(), this, mSize, mHeapId);
                     CallStack stack(LOG_TAG);
                 }
@@ -308,11 +308,11 @@
         uint32_t flags = reply.readInt32();
         uint32_t offset = reply.readInt32();
 
-        ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%ld, err=%d (%s)",
+        ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%zd, err=%d (%s)",
                 asBinder().get(), parcel_fd, size, err, strerror(-err));
 
         int fd = dup( parcel_fd );
-        ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%ld, err=%d (%s)",
+        ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)",
                 parcel_fd, size, err, strerror(errno));
 
         int access = PROT_READ;
@@ -325,7 +325,7 @@
             mRealHeap = true;
             mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
             if (mBase == MAP_FAILED) {
-                ALOGE("cannot map BpMemoryHeap (binder=%p), size=%ld, fd=%d (%s)",
+                ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)",
                         asBinder().get(), size, fd, strerror(errno));
                 close(fd);
             } else {
@@ -414,7 +414,7 @@
     if (i>=0) {
         heap_info_t& info = mHeapCache.editValueAt(i);
         ALOGD_IF(VERBOSE,
-                "found binder=%p, heap=%p, size=%d, fd=%d, count=%d",
+                "found binder=%p, heap=%p, size=%zu, fd=%d, count=%d",
                 binder.get(), info.heap.get(),
                 static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
                 static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
@@ -447,7 +447,7 @@
             int32_t c = android_atomic_dec(&info.count);
             if (c == 1) {
                 ALOGD_IF(VERBOSE,
-                        "removing binder=%p, heap=%p, size=%d, fd=%d, count=%d",
+                        "removing binder=%p, heap=%p, size=%zu, fd=%d, count=%d",
                         binder.unsafe_get(), info.heap.get(),
                         static_cast<BpMemoryHeap*>(info.heap.get())->mSize,
                         static_cast<BpMemoryHeap*>(info.heap.get())->mHeapId,
@@ -478,7 +478,7 @@
     for (int i=0 ; i<c ; i++) {
         const heap_info_t& info = mHeapCache.valueAt(i);
         BpMemoryHeap const* h(static_cast<BpMemoryHeap const *>(info.heap.get()));
-        ALOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%d)",
+        ALOGD("hey=%p, heap=%p, count=%d, (fd=%d, base=%p, size=%zu)",
                 mHeapCache.keyAt(i).unsafe_get(),
                 info.heap.get(), info.count,
                 h->mHeapId, h->mBase, h->mSize);
diff --git a/IPCThreadState.cpp b/IPCThreadState.cpp
index 5951a3f..dd04dcf 100644
--- a/IPCThreadState.cpp
+++ b/IPCThreadState.cpp
@@ -23,7 +23,6 @@
 #include <binder/TextOutput.h>
 
 #include <cutils/sched_policy.h>
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/threads.h>
 
@@ -533,7 +532,7 @@
     return result;
 }
 
-void IPCThreadState::stopProcess(bool immediate)
+void IPCThreadState::stopProcess(bool /*immediate*/)
 {
     //ALOGI("**** STOPPING PROCESS");
     flushCommands();
@@ -635,6 +634,7 @@
 
 status_t IPCThreadState::attemptIncStrongHandle(int32_t handle)
 {
+#if HAS_BC_ATTEMPT_ACQUIRE
     LOG_REMOTEREFS("IPCThreadState::attemptIncStrongHandle(%d)\n", handle);
     mOut.writeInt32(BC_ATTEMPT_ACQUIRE);
     mOut.writeInt32(0); // xxx was thread priority
@@ -649,6 +649,11 @@
 #endif
     
     return result;
+#else
+    (void)handle;
+    ALOGE("%s(%d): Not supported\n", __func__, handle);
+    return INVALID_OPERATION;
+#endif
 }
 
 void IPCThreadState::expungeHandle(int32_t handle, IBinder* binder)
@@ -663,7 +668,7 @@
 {
     mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);
     mOut.writeInt32((int32_t)handle);
-    mOut.writeInt32((int32_t)proxy);
+    mOut.writePointer((uintptr_t)proxy);
     return NO_ERROR;
 }
 
@@ -671,7 +676,7 @@
 {
     mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);
     mOut.writeInt32((int32_t)handle);
-    mOut.writeInt32((int32_t)proxy);
+    mOut.writePointer((uintptr_t)proxy);
     return NO_ERROR;
 }
 
@@ -753,23 +758,23 @@
                         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),
+                            reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(binder_size_t),
                             freeBuffer, this);
                     } else {
-                        err = *static_cast<const status_t*>(tr.data.ptr.buffer);
+                        err = *reinterpret_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);
+                            reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
+                            tr.offsets_size/sizeof(binder_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);
+                        reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
+                        tr.offsets_size/sizeof(binder_size_t), this);
                     continue;
                 }
             }
@@ -809,12 +814,12 @@
     const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
     
     bwr.write_size = outAvail;
-    bwr.write_buffer = (long unsigned int)mOut.data();
+    bwr.write_buffer = (uintptr_t)mOut.data();
 
     // This is what we'll read.
     if (doReceive && needRead) {
         bwr.read_size = mIn.dataCapacity();
-        bwr.read_buffer = (long unsigned int)mIn.data();
+        bwr.read_buffer = (uintptr_t)mIn.data();
     } else {
         bwr.read_size = 0;
         bwr.read_buffer = 0;
@@ -861,14 +866,14 @@
     } while (err == -EINTR);
 
     IF_LOG_COMMANDS() {
-        alog << "Our err: " << (void*)err << ", write consumed: "
+        alog << "Our err: " << (void*)(intptr_t)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())
+            if (bwr.write_consumed < mOut.dataSize())
                 mOut.remove(0, bwr.write_consumed);
             else
                 mOut.setDataSize(0);
@@ -898,6 +903,7 @@
 {
     binder_transaction_data tr;
 
+    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
     tr.target.handle = handle;
     tr.code = code;
     tr.flags = binderFlags;
@@ -909,15 +915,15 @@
     if (err == NO_ERROR) {
         tr.data_size = data.ipcDataSize();
         tr.data.ptr.buffer = data.ipcData();
-        tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);
+        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_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.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
         tr.offsets_size = 0;
-        tr.data.ptr.offsets = NULL;
+        tr.data.ptr.offsets = 0;
     } else {
         return (mLastError = err);
     }
@@ -950,8 +956,8 @@
         break;
         
     case BR_ACQUIRE:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         ALOG_ASSERT(refs->refBase() == obj,
                    "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
                    refs, obj, refs->refBase());
@@ -961,13 +967,13 @@
             obj->printRefs();
         }
         mOut.writeInt32(BC_ACQUIRE_DONE);
-        mOut.writeInt32((int32_t)refs);
-        mOut.writeInt32((int32_t)obj);
+        mOut.writePointer((uintptr_t)refs);
+        mOut.writePointer((uintptr_t)obj);
         break;
         
     case BR_RELEASE:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         ALOG_ASSERT(refs->refBase() == obj,
                    "BR_RELEASE: object %p does not match cookie %p (expected %p)",
                    refs, obj, refs->refBase());
@@ -979,17 +985,17 @@
         break;
         
     case BR_INCREFS:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         refs->incWeak(mProcess.get());
         mOut.writeInt32(BC_INCREFS_DONE);
-        mOut.writeInt32((int32_t)refs);
-        mOut.writeInt32((int32_t)obj);
+        mOut.writePointer((uintptr_t)refs);
+        mOut.writePointer((uintptr_t)obj);
         break;
         
     case BR_DECREFS:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
         // NOTE: This assertion is not valid, because the object may no
         // longer exist (thus the (BBinder*)cast above resulting in a different
         // memory address).
@@ -1000,8 +1006,8 @@
         break;
         
     case BR_ATTEMPT_ACQUIRE:
-        refs = (RefBase::weakref_type*)mIn.readInt32();
-        obj = (BBinder*)mIn.readInt32();
+        refs = (RefBase::weakref_type*)mIn.readPointer();
+        obj = (BBinder*)mIn.readPointer();
          
         {
             const bool success = refs->attemptIncStrong(mProcess.get());
@@ -1026,15 +1032,18 @@
             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);
+                reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
+                tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
             
             const pid_t origPid = mCallingPid;
             const uid_t origUid = mCallingUid;
-            
+            const int32_t origStrictModePolicy = mStrictModePolicy;
+            const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
+
             mCallingPid = tr.sender_pid;
             mCallingUid = tr.sender_euid;
-            
+            mLastTransactionBinderFlags = tr.flags;
+
             int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
             if (gDisableBackgroundScheduling) {
                 if (curPrio > ANDROID_PRIORITY_NORMAL) {
@@ -1056,8 +1065,9 @@
             }
 
             //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
-            
+
             Parcel reply;
+            status_t error;
             IF_LOG_TRANSACTIONS() {
                 TextOutput::Bundle _b(alog);
                 alog << "BR_TRANSACTION thr " << (void*)pthread_self()
@@ -1071,19 +1081,18 @@
             }
             if (tr.target.ptr) {
                 sp<BBinder> b((BBinder*)tr.cookie);
-                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
-                if (error < NO_ERROR) reply.setError(error);
+                error = b->transact(tr.code, buffer, &reply, tr.flags);
 
             } else {
-                const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
-                if (error < NO_ERROR) reply.setError(error);
+                error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
             }
-            
+
             //ALOGI("<<<< 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);
+                if (error < NO_ERROR) reply.setError(error);
                 sendReply(reply, 0);
             } else {
                 LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
@@ -1091,6 +1100,8 @@
             
             mCallingPid = origPid;
             mCallingUid = origUid;
+            mStrictModePolicy = origStrictModePolicy;
+            mLastTransactionBinderFlags = origTransactionBinderFlags;
 
             IF_LOG_TRANSACTIONS() {
                 TextOutput::Bundle _b(alog);
@@ -1103,15 +1114,15 @@
     
     case BR_DEAD_BINDER:
         {
-            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            BpBinder *proxy = (BpBinder*)mIn.readPointer();
             proxy->sendObituary();
             mOut.writeInt32(BC_DEAD_BINDER_DONE);
-            mOut.writeInt32((int32_t)proxy);
+            mOut.writePointer((uintptr_t)proxy);
         } break;
         
     case BR_CLEAR_DEATH_NOTIFICATION_DONE:
         {
-            BpBinder *proxy = (BpBinder*)mIn.readInt32();
+            BpBinder *proxy = (BpBinder*)mIn.readPointer();
             proxy->getWeakRefs()->decWeak(proxy);
         } break;
         
@@ -1154,9 +1165,10 @@
 }
 
 
-void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, size_t dataSize,
-                                const size_t* objects, size_t objectsSize,
-                                void* cookie)
+void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data,
+                                size_t /*dataSize*/,
+                                const binder_size_t* /*objects*/,
+                                size_t /*objectsSize*/, void* /*cookie*/)
 {
     //ALOGI("Freeing parcel %p", &parcel);
     IF_LOG_COMMANDS() {
@@ -1166,7 +1178,7 @@
     if (parcel != NULL) parcel->closeFileDescriptors();
     IPCThreadState* state = self();
     state->mOut.writeInt32(BC_FREE_BUFFER);
-    state->mOut.writeInt32((int32_t)data);
+    state->mOut.writePointer((uintptr_t)data);
 }
 
 }; // namespace android
diff --git a/IPermissionController.cpp b/IPermissionController.cpp
index e13036f..437113d 100644
--- a/IPermissionController.cpp
+++ b/IPermissionController.cpp
@@ -18,7 +18,6 @@
 
 #include <binder/IPermissionController.h>
 
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <binder/Parcel.h>
 #include <utils/String8.h>
diff --git a/IServiceManager.cpp b/IServiceManager.cpp
index a341ca8..7b1b0e7 100644
--- a/IServiceManager.cpp
+++ b/IServiceManager.cpp
@@ -18,7 +18,6 @@
 
 #include <binder/IServiceManager.h>
 
-#include <utils/Debug.h>
 #include <utils/Log.h>
 #include <binder/IPCThreadState.h>
 #include <binder/Parcel.h>
diff --git a/MemoryDealer.cpp b/MemoryDealer.cpp
index 8d0e0a7..8739625 100644
--- a/MemoryDealer.cpp
+++ b/MemoryDealer.cpp
@@ -210,7 +210,7 @@
 #ifdef MADV_REMOVE
             if (size) {
                 int err = madvise(start_ptr, size, MADV_REMOVE);
-                ALOGW_IF(err, "madvise(%p, %u, MADV_REMOVE) returned %s",
+                ALOGW_IF(err, "madvise(%p, %zu, MADV_REMOVE) returned %s",
                         start_ptr, size, err<0 ? strerror(errno) : "Ok");
             }
 #endif
@@ -225,8 +225,8 @@
 
 // ----------------------------------------------------------------------------
 
-MemoryDealer::MemoryDealer(size_t size, const char* name)
-    : mHeap(new MemoryHeapBase(size, 0, name)),
+MemoryDealer::MemoryDealer(size_t size, const char* name, uint32_t flags)
+    : mHeap(new MemoryHeapBase(size, flags, name)),
     mAllocator(new SimpleBestFitAllocator(size))
 {    
 }
@@ -445,8 +445,8 @@
         int np = ((cur->next) && cur->next->prev != cur) ? 1 : 0;
         int pn = ((cur->prev) && cur->prev->next != cur) ? 2 : 0;
 
-        snprintf(buffer, SIZE, "  %3u: %08x | 0x%08X | 0x%08X | %s %s\n",
-            i, int(cur), int(cur->start*kMemoryAlign),
+        snprintf(buffer, SIZE, "  %3u: %p | 0x%08X | 0x%08X | %s %s\n",
+            i, cur, int(cur->start*kMemoryAlign),
             int(cur->size*kMemoryAlign),
                     int(cur->free) ? "F" : "A",
                     errs[np|pn]);
diff --git a/Parcel.cpp b/Parcel.cpp
index 0464e93..a24621b 100644
--- a/Parcel.cpp
+++ b/Parcel.cpp
@@ -25,6 +25,8 @@
 #include <binder/ProcessState.h>
 #include <binder/TextOutput.h>
 
+#include <errno.h>
+#include <utils/CallStack.h>
 #include <utils/Debug.h>
 #include <utils/Log.h>
 #include <utils/String8.h>
@@ -35,6 +37,7 @@
 
 #include <private/binder/binder_module.h>
 
+#include <fcntl.h>
 #include <inttypes.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -78,12 +81,12 @@
         case BINDER_TYPE_BINDER:
             if (obj.binder) {
                 LOG_REFS("Parcel %p acquiring reference on local %p", who, obj.cookie);
-                static_cast<IBinder*>(obj.cookie)->incStrong(who);
+                reinterpret_cast<IBinder*>(obj.cookie)->incStrong(who);
             }
             return;
         case BINDER_TYPE_WEAK_BINDER:
             if (obj.binder)
-                static_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
+                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->incWeak(who);
             return;
         case BINDER_TYPE_HANDLE: {
             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
@@ -105,7 +108,7 @@
         }
     }
 
-    ALOGD("Invalid object type 0x%08lx", obj.type);
+    ALOGD("Invalid object type 0x%08x", obj.type);
 }
 
 void release_object(const sp<ProcessState>& proc,
@@ -115,12 +118,12 @@
         case BINDER_TYPE_BINDER:
             if (obj.binder) {
                 LOG_REFS("Parcel %p releasing reference on local %p", who, obj.cookie);
-                static_cast<IBinder*>(obj.cookie)->decStrong(who);
+                reinterpret_cast<IBinder*>(obj.cookie)->decStrong(who);
             }
             return;
         case BINDER_TYPE_WEAK_BINDER:
             if (obj.binder)
-                static_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
+                reinterpret_cast<RefBase::weakref_type*>(obj.binder)->decWeak(who);
             return;
         case BINDER_TYPE_HANDLE: {
             const sp<IBinder> b = proc->getStrongProxyForHandle(obj.handle);
@@ -136,25 +139,25 @@
             return;
         }
         case BINDER_TYPE_FD: {
-            if (obj.cookie != (void*)0) close(obj.handle);
+            if (obj.cookie != 0) close(obj.handle);
             return;
         }
     }
 
-    ALOGE("Invalid object type 0x%08lx", obj.type);
+    ALOGE("Invalid object type 0x%08x", obj.type);
 }
 
 inline static status_t finish_flatten_binder(
-    const sp<IBinder>& binder, const flat_binder_object& flat, Parcel* out)
+    const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
 {
     return out->writeObject(flat, false);
 }
 
-status_t flatten_binder(const sp<ProcessState>& proc,
+status_t flatten_binder(const sp<ProcessState>& /*proc*/,
     const sp<IBinder>& binder, Parcel* out)
 {
     flat_binder_object obj;
-    
+
     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
     if (binder != NULL) {
         IBinder *local = binder->localBinder();
@@ -165,27 +168,28 @@
             }
             const int32_t handle = proxy ? proxy->handle() : 0;
             obj.type = BINDER_TYPE_HANDLE;
+            obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
             obj.handle = handle;
-            obj.cookie = NULL;
+            obj.cookie = 0;
         } else {
             obj.type = BINDER_TYPE_BINDER;
-            obj.binder = local->getWeakRefs();
-            obj.cookie = local;
+            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
+            obj.cookie = reinterpret_cast<uintptr_t>(local);
         }
     } else {
         obj.type = BINDER_TYPE_BINDER;
-        obj.binder = NULL;
-        obj.cookie = NULL;
+        obj.binder = 0;
+        obj.cookie = 0;
     }
-    
+
     return finish_flatten_binder(binder, obj, out);
 }
 
-status_t flatten_binder(const sp<ProcessState>& proc,
+status_t flatten_binder(const sp<ProcessState>& /*proc*/,
     const wp<IBinder>& binder, Parcel* out)
 {
     flat_binder_object obj;
-    
+
     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
     if (binder != NULL) {
         sp<IBinder> real = binder.promote();
@@ -198,16 +202,17 @@
                 }
                 const int32_t handle = proxy ? proxy->handle() : 0;
                 obj.type = BINDER_TYPE_WEAK_HANDLE;
+                obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
                 obj.handle = handle;
-                obj.cookie = NULL;
+                obj.cookie = 0;
             } else {
                 obj.type = BINDER_TYPE_WEAK_BINDER;
-                obj.binder = binder.get_refs();
-                obj.cookie = binder.unsafe_get();
+                obj.binder = reinterpret_cast<uintptr_t>(binder.get_refs());
+                obj.cookie = reinterpret_cast<uintptr_t>(binder.unsafe_get());
             }
             return finish_flatten_binder(real, obj, out);
         }
-        
+
         // XXX How to deal?  In order to flatten the given binder,
         // we need to probe it for information, which requires a primary
         // reference...  but we don't have one.
@@ -217,39 +222,40 @@
         // implementation we are using.
         ALOGE("Unable to unflatten Binder weak reference!");
         obj.type = BINDER_TYPE_BINDER;
-        obj.binder = NULL;
-        obj.cookie = NULL;
+        obj.binder = 0;
+        obj.cookie = 0;
         return finish_flatten_binder(NULL, obj, out);
-    
+
     } else {
         obj.type = BINDER_TYPE_BINDER;
-        obj.binder = NULL;
-        obj.cookie = NULL;
+        obj.binder = 0;
+        obj.cookie = 0;
         return finish_flatten_binder(NULL, obj, out);
     }
 }
 
 inline static status_t finish_unflatten_binder(
-    BpBinder* proxy, const flat_binder_object& flat, const Parcel& in)
+    BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
+    const Parcel& /*in*/)
 {
     return NO_ERROR;
 }
-    
+
 status_t unflatten_binder(const sp<ProcessState>& proc,
     const Parcel& in, sp<IBinder>* out)
 {
     const flat_binder_object* flat = in.readObject(false);
-    
+
     if (flat) {
         switch (flat->type) {
             case BINDER_TYPE_BINDER:
-                *out = static_cast<IBinder*>(flat->cookie);
+                *out = reinterpret_cast<IBinder*>(flat->cookie);
                 return finish_unflatten_binder(NULL, *flat, in);
             case BINDER_TYPE_HANDLE:
                 *out = proc->getStrongProxyForHandle(flat->handle);
                 return finish_unflatten_binder(
                     static_cast<BpBinder*>(out->get()), *flat, in);
-        }        
+        }
     }
     return BAD_TYPE;
 }
@@ -258,17 +264,17 @@
     const Parcel& in, wp<IBinder>* out)
 {
     const flat_binder_object* flat = in.readObject(false);
-    
+
     if (flat) {
         switch (flat->type) {
             case BINDER_TYPE_BINDER:
-                *out = static_cast<IBinder*>(flat->cookie);
+                *out = reinterpret_cast<IBinder*>(flat->cookie);
                 return finish_unflatten_binder(NULL, *flat, in);
             case BINDER_TYPE_WEAK_BINDER:
-                if (flat->binder != NULL) {
+                if (flat->binder != 0) {
                     out->set_object_and_refs(
-                        static_cast<IBinder*>(flat->cookie),
-                        static_cast<RefBase::weakref_type*>(flat->binder));
+                        reinterpret_cast<IBinder*>(flat->cookie),
+                        reinterpret_cast<RefBase::weakref_type*>(flat->binder));
                 } else {
                     *out = NULL;
                 }
@@ -332,7 +338,7 @@
     err = continueWrite(size);
     if (err == NO_ERROR) {
         mDataSize = size;
-        ALOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
+        ALOGV("setDataSize Setting data size of %p to %zu", this, mDataSize);
     }
     return err;
 }
@@ -365,7 +371,7 @@
     const sp<ProcessState> proc(ProcessState::self());
     status_t err;
     const uint8_t *data = parcel->mData;
-    const size_t *objects = parcel->mObjects;
+    const binder_size_t *objects = parcel->mObjects;
     size_t size = parcel->mObjectsSize;
     int startPos = mDataPos;
     int firstIndex = -1, lastIndex = -2;
@@ -412,15 +418,15 @@
         // grow objects
         if (mObjectsCapacity < mObjectsSize + numObjects) {
             int newSize = ((mObjectsSize + numObjects)*3)/2;
-            size_t *objects =
-                (size_t*)realloc(mObjects, newSize*sizeof(size_t));
-            if (objects == (size_t*)0) {
+            binder_size_t *objects =
+                (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
+            if (objects == (binder_size_t*)0) {
                 return NO_MEMORY;
             }
             mObjects = objects;
             mObjectsCapacity = newSize;
         }
-        
+
         // append and acquire objects
         int idx = mObjectsSize;
         for (int i = firstIndex; i <= lastIndex; i++) {
@@ -437,7 +443,7 @@
                 // new Parcel now owns its own fd, and can declare that we
                 // officially know we have fds.
                 flat->handle = dup(flat->handle);
-                flat->cookie = (void*)1;
+                flat->cookie = 1;
                 mHasFds = mFdsKnown = true;
                 if (!mAllowFds) {
                     err = FDS_NOT_ALLOWED;
@@ -506,13 +512,13 @@
     if (str == interface) {
         return true;
     } else {
-        ALOGW("**** enforceInterface() expected '%s' but read '%s'\n",
+        ALOGW("**** enforceInterface() expected '%s' but read '%s'",
                 String8(interface).string(), String8(str).string());
         return false;
     }
 }
 
-const size_t* Parcel::objects() const
+const binder_size_t* Parcel::objects() const
 {
     return mObjects;
 }
@@ -536,10 +542,10 @@
 {
     //printf("Finish write of %d\n", len);
     mDataPos += len;
-    ALOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
+    ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos);
     if (mDataPos > mDataSize) {
         mDataSize = mDataPos;
-        ALOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
+        ALOGV("finishWrite Setting data size of %p to %zu", this, mDataSize);
     }
     //printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
     return NO_ERROR;
@@ -644,6 +650,11 @@
     return writeAligned(val);
 }
 
+status_t Parcel::writePointer(uintptr_t val)
+{
+    return writeAligned<binder_uintptr_t>(val);
+}
+
 status_t Parcel::writeFloat(float val)
 {
     return writeAligned(val);
@@ -670,11 +681,6 @@
 
 #endif
 
-status_t Parcel::writeIntPtr(intptr_t val)
-{
-    return writeAligned(val);
-}
-
 status_t Parcel::writeCString(const char* str)
 {
     return write(str, strlen(str)+1);
@@ -700,7 +706,7 @@
 status_t Parcel::writeString16(const char16_t* str, size_t len)
 {
     if (str == NULL) return writeInt32(-1);
-    
+
     status_t err = writeInt32(len);
     if (err == NO_ERROR) {
         len *= sizeof(char16_t);
@@ -753,14 +759,38 @@
     flat_binder_object obj;
     obj.type = BINDER_TYPE_FD;
     obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
+    obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
     obj.handle = fd;
-    obj.cookie = (void*) (takeOwnership ? 1 : 0);
+    obj.cookie = takeOwnership ? 1 : 0;
     return writeObject(obj, true);
 }
 
 status_t Parcel::writeDupFileDescriptor(int fd)
 {
     int dupFd = dup(fd);
+
+    {   // Temporary extra debug validation for b/17477219: a Parcel recipient is
+        // getting a positive but invalid fd unexpectedly. Trying to track down
+        // where it's coming from.
+        int dupErrno = dupFd < 0 ? errno : 0;
+        int fdFlags = fcntl(fd, F_GETFD);
+        int fdFlagsErrno = fdFlags == -1 ? errno : 0;
+        int dupFlags = fcntl(dupFd, F_GETFD);
+        int dupFlagsErrno = dupFlags == -1 ? errno : 0;
+        if (dupFd < 0 || fdFlags == -1 || dupFlags == -1) {
+            ALOGE("Parcel::writeDupFileDescriptor failed:\n"
+                    "  fd=%d flags=%d err=%d(%s)\n"
+                    "  dupFd=%d dupErr=%d(%s) flags=%d err=%d(%s)",
+                    fd, fdFlags, fdFlagsErrno, strerror(fdFlagsErrno),
+                    dupFd, dupErrno, strerror(dupErrno),
+                    dupFlags, dupFlagsErrno, strerror(dupFlagsErrno));
+            if (fd < 0 || fdFlags == -1) {
+                CallStack(LOG_TAG);
+            }
+            return -errno;
+        }
+    }
+
     if (dupFd < 0) {
         return -errno;
     }
@@ -771,6 +801,32 @@
     return err;
 }
 
+// WARNING: This method must stay in sync with
+// Parcelable.Creator<ParcelFileDescriptor> CREATOR
+// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
+status_t Parcel::writeParcelFileDescriptor(int fd, int commChannel) {
+    status_t status;
+
+    if (fd < 0) {
+        status = writeInt32(0); // ParcelFileDescriptor is null
+        if (status) return status;
+    } else {
+        status = writeInt32(1); // ParcelFileDescriptor is not null
+        if (status) return status;
+        status = writeDupFileDescriptor(fd);
+        if (status) return status;
+        if (commChannel < 0) {
+            status = writeInt32(0); // commChannel is null
+            if (status) return status;
+        } else {
+            status = writeInt32(1); // commChannel is not null
+            if (status) return status;
+            status = writeDupFileDescriptor(commChannel);
+        }
+    }
+    return status;
+}
+
 status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
 {
     status_t status;
@@ -862,14 +918,14 @@
     if (enoughData && enoughObjects) {
 restart_write:
         *reinterpret_cast<flat_binder_object*>(mData+mDataPos) = val;
-        
+
         // Need to write meta-data?
-        if (nullMetaData || val.binder != NULL) {
+        if (nullMetaData || val.binder != 0) {
             mObjects[mObjectsSize] = mDataPos;
             acquire_object(ProcessState::self(), val, this);
             mObjectsSize++;
         }
-        
+
         // remember if it's a file descriptor
         if (val.type == BINDER_TYPE_FD) {
             if (!mAllowFds) {
@@ -887,12 +943,12 @@
     }
     if (!enoughObjects) {
         size_t newSize = ((mObjectsSize+2)*3)/2;
-        size_t* objects = (size_t*)realloc(mObjects, newSize*sizeof(size_t));
+        binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
         if (objects == NULL) return NO_MEMORY;
         mObjects = objects;
         mObjectsCapacity = newSize;
     }
-    
+
     goto restart_write;
 }
 
@@ -901,7 +957,7 @@
     return writeInt32(0);
 }
 
-void Parcel::remove(size_t start, size_t amt)
+void Parcel::remove(size_t /*start*/, size_t /*amt*/)
 {
     LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
 }
@@ -912,7 +968,7 @@
             && len <= PAD_SIZE(len)) {
         memcpy(outData, mData+mDataPos, len);
         mDataPos += PAD_SIZE(len);
-        ALOGV("read Setting data pos of %p to %d\n", this, mDataPos);
+        ALOGV("read Setting data pos of %p to %zu", this, mDataPos);
         return NO_ERROR;
     }
     return NOT_ENOUGH_DATA;
@@ -924,7 +980,7 @@
             && len <= PAD_SIZE(len)) {
         const void* data = mData+mDataPos;
         mDataPos += PAD_SIZE(len);
-        ALOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
+        ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos);
         return data;
     }
     return NULL;
@@ -991,6 +1047,22 @@
     return readAligned<int64_t>();
 }
 
+status_t Parcel::readPointer(uintptr_t *pArg) const
+{
+    status_t ret;
+    binder_uintptr_t ptr;
+    ret = readAligned(&ptr);
+    if (!ret)
+        *pArg = ptr;
+    return ret;
+}
+
+uintptr_t Parcel::readPointer() const
+{
+    return readAligned<binder_uintptr_t>();
+}
+
+
 status_t Parcel::readFloat(float *pArg) const
 {
     return readAligned(pArg);
@@ -1010,6 +1082,7 @@
       double d;
       unsigned long long ll;
     } u;
+    u.d = 0;
     status_t status;
     status = readAligned(&u.ll);
     *pArg = u.d;
@@ -1062,7 +1135,7 @@
         if (eos) {
             const size_t len = eos - str;
             mDataPos += PAD_SIZE(len+1);
-            ALOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
+            ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos);
             return str;
         }
     }
@@ -1168,13 +1241,30 @@
     if (flat) {
         switch (flat->type) {
             case BINDER_TYPE_FD:
-                //ALOGI("Returning file descriptor %ld from parcel %p\n", flat->handle, this);
+                //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this);
                 return flat->handle;
-        }        
+        }
     }
     return BAD_TYPE;
 }
 
+// WARNING: This method must stay in sync with writeToParcel()
+// in frameworks/base/core/java/android/os/ParcelFileDescriptor.java
+int Parcel::readParcelFileDescriptor(int& outCommChannel) const {
+    int fd;
+    outCommChannel = -1;
+
+    if (readInt32() == 0) {
+        fd = -1;
+    } else {
+        fd = readFileDescriptor();
+        if (fd >= 0 && readInt32() != 0) {
+            outCommChannel = readFileDescriptor();
+        }
+    }
+    return fd;
+}
+
 status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
 {
     int32_t useAshmem;
@@ -1195,7 +1285,7 @@
     if (fd == int(BAD_TYPE)) return BAD_VALUE;
 
     void* ptr = ::mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0);
-    if (!ptr) return NO_MEMORY;
+    if (ptr == MAP_FAILED) return NO_MEMORY;
 
     outBlob->init(true /*mapped*/, ptr, len);
     return NO_ERROR;
@@ -1219,8 +1309,24 @@
 
     status_t err = NO_ERROR;
     for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
-        fds[i] = dup(this->readFileDescriptor());
-        if (fds[i] < 0) err = BAD_VALUE;
+        int oldfd = this->readFileDescriptor();
+        fds[i] = dup(oldfd);
+        if (fds[i] < 0) {
+            int dupErrno = errno;
+            err = BAD_VALUE;
+            int flags = fcntl(oldfd, F_GETFD);
+            int fcntlErrno = errno;
+            const flat_binder_object* flat = readObject(true);
+            ALOGE("dup failed in Parcel::read, fd %zu of %zu\n"
+                "  dup(%d) = %d [errno: %d (%s)]\n"
+                "  fcntl(%d, F_GETFD) = %d [errno: %d (%s)]\n"
+                "  flat %p type %d",
+                i, fd_count,
+                oldfd, fds[i], dupErrno, strerror(dupErrno),
+                oldfd, flags, fcntlErrno, strerror(fcntlErrno),
+                flat, flat ? flat->type : 0);
+            CallStack(LOG_TAG);
+        }
     }
 
     if (err == NO_ERROR) {
@@ -1240,23 +1346,23 @@
         const flat_binder_object* obj
                 = reinterpret_cast<const flat_binder_object*>(mData+DPOS);
         mDataPos = DPOS + sizeof(flat_binder_object);
-        if (!nullMetaData && (obj->cookie == NULL && obj->binder == NULL)) {
+        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
             // When transferring a NULL object, we don't write it into
             // the object list, so we don't want to check for it when
             // reading.
-            ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+            ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
             return obj;
         }
-        
+
         // Ensure that this object is valid...
-        size_t* const OBJS = mObjects;
+        binder_size_t* const OBJS = mObjects;
         const size_t N = mObjectsSize;
         size_t opos = mNextObjectHint;
-        
+
         if (N > 0) {
-            ALOGV("Parcel %p looking for obj at %d, hint=%d\n",
+            ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
                  this, DPOS, opos);
-            
+
             // Start at the current hint position, looking for an object at
             // the current data position.
             if (opos < N) {
@@ -1268,27 +1374,27 @@
             }
             if (OBJS[opos] == DPOS) {
                 // Found it!
-                ALOGV("Parcel found obj %d at index %d with forward search",
+                ALOGV("Parcel %p found obj %zu at index %zu with forward search",
                      this, DPOS, opos);
                 mNextObjectHint = opos+1;
-                ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
                 return obj;
             }
-        
+
             // Look backwards for it...
             while (opos > 0 && OBJS[opos] > DPOS) {
                 opos--;
             }
             if (OBJS[opos] == DPOS) {
                 // Found it!
-                ALOGV("Parcel found obj %d at index %d with backward search",
+                ALOGV("Parcel %p found obj %zu at index %zu with backward search",
                      this, DPOS, opos);
                 mNextObjectHint = opos+1;
-                ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
                 return obj;
             }
         }
-        ALOGW("Attempt to read object from Parcel %p at offset %d that is not in the object list",
+        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
              this, DPOS);
     }
     return NULL;
@@ -1298,22 +1404,22 @@
 {
     size_t i = mObjectsSize;
     if (i > 0) {
-        //ALOGI("Closing file descriptors for %d objects...", mObjectsSize);
+        //ALOGI("Closing file descriptors for %zu objects...", i);
     }
     while (i > 0) {
         i--;
         const flat_binder_object* flat
             = reinterpret_cast<flat_binder_object*>(mData+mObjects[i]);
         if (flat->type == BINDER_TYPE_FD) {
-            //ALOGI("Closing fd: %ld\n", flat->handle);
+            //ALOGI("Closing fd: %ld", flat->handle);
             close(flat->handle);
         }
     }
 }
 
-const uint8_t* Parcel::ipcData() const
+uintptr_t Parcel::ipcData() const
 {
-    return mData;
+    return reinterpret_cast<uintptr_t>(mData);
 }
 
 size_t Parcel::ipcDataSize() const
@@ -1321,9 +1427,9 @@
     return (mDataSize > mDataPos ? mDataSize : mDataPos);
 }
 
-const size_t* Parcel::ipcObjects() const
+uintptr_t Parcel::ipcObjects() const
 {
-    return mObjects;
+    return reinterpret_cast<uintptr_t>(mObjects);
 }
 
 size_t Parcel::ipcObjectsCount() const
@@ -1332,26 +1438,26 @@
 }
 
 void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
-    const size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
+    const binder_size_t* objects, size_t objectsCount, release_func relFunc, void* relCookie)
 {
-    size_t minOffset = 0;
+    binder_size_t minOffset = 0;
     freeDataNoInit();
     mError = NO_ERROR;
     mData = const_cast<uint8_t*>(data);
     mDataSize = mDataCapacity = dataSize;
-    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
+    //ALOGI("setDataReference Setting data size of %p to %lu (pid=%d)", this, mDataSize, getpid());
     mDataPos = 0;
-    ALOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
-    mObjects = const_cast<size_t*>(objects);
+    ALOGV("setDataReference Setting data pos of %p to %zu", this, mDataPos);
+    mObjects = const_cast<binder_size_t*>(objects);
     mObjectsSize = mObjectsCapacity = objectsCount;
     mNextObjectHint = 0;
     mOwner = relFunc;
     mOwnerCookie = relCookie;
     for (size_t i = 0; i < mObjectsSize; i++) {
-        size_t offset = mObjects[i];
+        binder_size_t offset = mObjects[i];
         if (offset < minOffset) {
-            ALOGE("%s: bad object offset %zu < %zu\n",
-                  __func__, offset, minOffset);
+            ALOGE("%s: bad object offset %"PRIu64" < %"PRIu64"\n",
+                  __func__, (uint64_t)offset, (uint64_t)minOffset);
             mObjectsSize = 0;
             break;
         }
@@ -1360,17 +1466,17 @@
     scanForFds();
 }
 
-void Parcel::print(TextOutput& to, uint32_t flags) const
+void Parcel::print(TextOutput& to, uint32_t /*flags*/) const
 {
     to << "Parcel(";
-    
+
     if (errorCheck() != NO_ERROR) {
         const status_t err = errorCheck();
-        to << "Error: " << (void*)err << " \"" << strerror(-err) << "\"";
+        to << "Error: " << (void*)(intptr_t)err << " \"" << strerror(-err) << "\"";
     } else if (dataSize() > 0) {
         const uint8_t* DATA = data();
         to << indent << HexDump(DATA, dataSize()) << dedent;
-        const size_t* OBJS = objects();
+        const binder_size_t* OBJS = objects();
         const size_t N = objectsCount();
         for (size_t i=0; i<N; i++) {
             const flat_binder_object* flat
@@ -1382,7 +1488,7 @@
     } else {
         to << "NULL";
     }
-    
+
     to << ")";
 }
 
@@ -1391,7 +1497,7 @@
     const sp<ProcessState> proc(ProcessState::self());
     size_t i = mObjectsSize;
     uint8_t* const data = mData;
-    size_t* const objects = mObjects;
+    binder_size_t* const objects = mObjects;
     while (i > 0) {
         i--;
         const flat_binder_object* flat
@@ -1405,7 +1511,7 @@
     const sp<ProcessState> proc(ProcessState::self());
     size_t i = mObjectsSize;
     uint8_t* const data = mData;
-    size_t* const objects = mObjects;
+    binder_size_t* const objects = mObjects;
     while (i > 0) {
         i--;
         const flat_binder_object* flat
@@ -1423,7 +1529,7 @@
 void Parcel::freeDataNoInit()
 {
     if (mOwner) {
-        //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
     } else {
         releaseObjects();
@@ -1446,24 +1552,24 @@
         freeData();
         return continueWrite(desired);
     }
-    
+
     uint8_t* data = (uint8_t*)realloc(mData, desired);
     if (!data && desired > mDataCapacity) {
         mError = NO_MEMORY;
         return NO_MEMORY;
     }
-    
+
     releaseObjects();
-    
+
     if (data) {
         mData = data;
         mDataCapacity = desired;
     }
-    
+
     mDataSize = mDataPos = 0;
-    ALOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
-    ALOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
-        
+    ALOGV("restartWrite Setting data size of %p to %zu", this, mDataSize);
+    ALOGV("restartWrite Setting data pos of %p to %zu", this, mDataPos);
+
     free(mObjects);
     mObjects = NULL;
     mObjectsSize = mObjectsCapacity = 0;
@@ -1471,7 +1577,7 @@
     mHasFds = false;
     mFdsKnown = true;
     mAllowFds = true;
-    
+
     return NO_ERROR;
 }
 
@@ -1491,7 +1597,7 @@
             }
         }
     }
-    
+
     if (mOwner) {
         // If the size is going to zero, just release the owner's data.
         if (desired == 0) {
@@ -1506,10 +1612,10 @@
             mError = NO_MEMORY;
             return NO_MEMORY;
         }
-        size_t* objects = NULL;
-        
+        binder_size_t* objects = NULL;
+
         if (objectsSize) {
-            objects = (size_t*)malloc(objectsSize*sizeof(size_t));
+            objects = (binder_size_t*)malloc(objectsSize*sizeof(binder_size_t));
             if (!objects) {
                 free(data);
 
@@ -1524,21 +1630,21 @@
             acquireObjects();
             mObjectsSize = oldObjectsSize;
         }
-        
+
         if (mData) {
             memcpy(data, mData, mDataSize < desired ? mDataSize : desired);
         }
         if (objects && mObjects) {
-            memcpy(objects, mObjects, objectsSize*sizeof(size_t));
+            memcpy(objects, mObjects, objectsSize*sizeof(binder_size_t));
         }
-        //ALOGI("Freeing data ref of %p (pid=%d)\n", this, getpid());
+        //ALOGI("Freeing data ref of %p (pid=%d)", this, getpid());
         mOwner(this, mData, mDataSize, mObjects, mObjectsSize, mOwnerCookie);
         mOwner = NULL;
 
         mData = data;
         mObjects = objects;
         mDataSize = (mDataSize < desired) ? mDataSize : desired;
-        ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
         mDataCapacity = desired;
         mObjectsSize = mObjectsCapacity = objectsSize;
         mNextObjectHint = 0;
@@ -1556,8 +1662,8 @@
                 }
                 release_object(proc, *flat, this);
             }
-            size_t* objects =
-                (size_t*)realloc(mObjects, objectsSize*sizeof(size_t));
+            binder_size_t* objects =
+                (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
             if (objects) {
                 mObjects = objects;
             }
@@ -1578,14 +1684,14 @@
         } else {
             if (mDataSize > desired) {
                 mDataSize = desired;
-                ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+                ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
             }
             if (mDataPos > desired) {
                 mDataPos = desired;
-                ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+                ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
             }
         }
-        
+
     } else {
         // This is the first data.  Easy!
         uint8_t* data = (uint8_t*)malloc(desired);
@@ -1596,13 +1702,13 @@
 
         if(!(mDataCapacity == 0 && mObjects == NULL
              && mObjectsCapacity == 0)) {
-            ALOGE("continueWrite: %d/%p/%d/%d", mDataCapacity, mObjects, mObjectsCapacity, desired);
+            ALOGE("continueWrite: %zu/%p/%zu/%zu", mDataCapacity, mObjects, mObjectsCapacity, desired);
         }
-        
+
         mData = data;
         mDataSize = mDataPos = 0;
-        ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
-        ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+        ALOGV("continueWrite Setting data size of %p to %zu", this, mDataSize);
+        ALOGV("continueWrite Setting data pos of %p to %zu", this, mDataPos);
         mDataCapacity = desired;
     }
 
@@ -1616,8 +1722,8 @@
     mDataSize = 0;
     mDataCapacity = 0;
     mDataPos = 0;
-    ALOGV("initState Setting data size of %p to %d\n", this, mDataSize);
-    ALOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
+    ALOGV("initState Setting data size of %p to %zu", this, mDataSize);
+    ALOGV("initState Setting data pos of %p to %zu", this, mDataPos);
     mObjects = NULL;
     mObjectsSize = 0;
     mObjectsCapacity = 0;
diff --git a/ProcessState.cpp b/ProcessState.cpp
index c1e49bc..303d6cf 100644
--- a/ProcessState.cpp
+++ b/ProcessState.cpp
@@ -48,11 +48,6 @@
 
 namespace android {
  
-// Global variables
-int                 mArgC;
-const char* const*  mArgV;
-int                 mArgLen;
-
 class PoolThread : public Thread
 {
 public:
@@ -86,7 +81,7 @@
     setContextObject(object, String16("default"));
 }
 
-sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
+sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
 {
     return getStrongProxyForHandle(0);
 }
@@ -280,36 +275,6 @@
     if (e && e->binder == binder) e->binder = NULL;
 }
 
-void ProcessState::setArgs(int argc, const char* const argv[])
-{
-    mArgC = argc;
-    mArgV = (const char **)argv;
-
-    mArgLen = 0;
-    for (int i=0; i<argc; i++) {
-        mArgLen += strlen(argv[i]) + 1;
-    }
-    mArgLen--;
-}
-
-int ProcessState::getArgC() const
-{
-    return mArgC;
-}
-
-const char* const* ProcessState::getArgV() const
-{
-    return mArgV;
-}
-
-void ProcessState::setArgV0(const char* txt)
-{
-    if (mArgV != NULL) {
-        strncpy((char*)mArgV[0], txt, mArgLen);
-        set_process_name(txt);
-    }
-}
-
 String8 ProcessState::makeBinderThreadName() {
     int32_t s = android_atomic_add(1, &mThreadPoolSeq);
     String8 name;
@@ -345,7 +310,7 @@
     int fd = open("/dev/binder", O_RDWR);
     if (fd >= 0) {
         fcntl(fd, F_SETFD, FD_CLOEXEC);
-        int vers;
+        int vers = 0;
         status_t result = ioctl(fd, BINDER_VERSION, &vers);
         if (result == -1) {
             ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
diff --git a/include/hwbinder/Binder.h b/include/hwbinder/Binder.h
index ba3ac4b..86628a0 100644
--- a/include/hwbinder/Binder.h
+++ b/include/hwbinder/Binder.h
@@ -17,6 +17,8 @@
 #ifndef ANDROID_BINDER_H
 #define ANDROID_BINDER_H
 
+#include <stdatomic.h>
+#include <stdint.h>
 #include <binder/IBinder.h>
 
 // ---------------------------------------------------------------------------
@@ -69,7 +71,7 @@
 
     class Extras;
 
-            Extras*     mExtras;
+    atomic_uintptr_t    mExtras;  // should be atomic<Extras *>
             void*       mReserved0;
 };
 
diff --git a/include/hwbinder/IBatteryStats.h b/include/hwbinder/IBatteryStats.h
new file mode 100644
index 0000000..7ddac57
--- /dev/null
+++ b/include/hwbinder/IBatteryStats.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#ifndef ANDROID_IBATTERYSTATS_H
+#define ANDROID_IBATTERYSTATS_H
+
+#include <binder/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IBatteryStats : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(BatteryStats);
+
+    virtual void noteStartSensor(int uid, int sensor) = 0;
+    virtual void noteStopSensor(int uid, int sensor) = 0;
+    virtual void noteStartVideo(int uid) = 0;
+    virtual void noteStopVideo(int uid) = 0;
+    virtual void noteStartAudio(int uid) = 0;
+    virtual void noteStopAudio(int uid) = 0;
+    virtual void noteResetVideo() = 0;
+    virtual void noteResetAudio() = 0;
+
+    enum {
+        NOTE_START_SENSOR_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+        NOTE_STOP_SENSOR_TRANSACTION,
+        NOTE_START_VIDEO_TRANSACTION,
+        NOTE_STOP_VIDEO_TRANSACTION,
+        NOTE_START_AUDIO_TRANSACTION,
+        NOTE_STOP_AUDIO_TRANSACTION,
+        NOTE_RESET_VIDEO_TRANSACTION,
+        NOTE_RESET_AUDIO_TRANSACTION,
+    };
+};
+
+// ----------------------------------------------------------------------
+
+class BnBatteryStats : public BnInterface<IBatteryStats>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IBATTERYSTATS_H
diff --git a/include/hwbinder/IBinder.h b/include/hwbinder/IBinder.h
index 8b84951..43b6543 100644
--- a/include/hwbinder/IBinder.h
+++ b/include/hwbinder/IBinder.h
@@ -81,14 +81,6 @@
                                         Parcel* reply,
                                         uint32_t flags = 0) = 0;
 
-    /**
-     * This method allows you to add data that is transported through
-     * IPC along with your IBinder pointer.  When implementing a Binder
-     * object, override it to write your desired data in to @a outData.
-     * You can then call getConstantData() on your IBinder to retrieve
-     * that data, from any process.  You MUST return the number of bytes
-     * written in to the parcel (including padding).
-     */
     class DeathRecipient : public virtual RefBase
     {
     public:
diff --git a/include/hwbinder/IPCThreadState.h b/include/hwbinder/IPCThreadState.h
index 5bc123e..6e0c01b 100644
--- a/include/hwbinder/IPCThreadState.h
+++ b/include/hwbinder/IPCThreadState.h
@@ -107,7 +107,7 @@
     static  void                threadDestructor(void *st);
     static  void                freeBuffer(Parcel* parcel,
                                            const uint8_t* data, size_t dataSize,
-                                           const size_t* objects, size_t objectsSize,
+                                           const binder_size_t* objects, size_t objectsSize,
                                            void* cookie);
     
     const   sp<ProcessState>    mProcess;
diff --git a/include/hwbinder/MemoryDealer.h b/include/hwbinder/MemoryDealer.h
index 170f20d..aa415d5 100644
--- a/include/hwbinder/MemoryDealer.h
+++ b/include/hwbinder/MemoryDealer.h
@@ -34,7 +34,8 @@
 class MemoryDealer : public RefBase
 {
 public:
-    MemoryDealer(size_t size, const char* name = 0);
+    MemoryDealer(size_t size, const char* name = 0,
+            uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ );
 
     virtual sp<IMemory> allocate(size_t size);
     virtual void        deallocate(size_t offset);
diff --git a/include/hwbinder/Parcel.h b/include/hwbinder/Parcel.h
index 98f20de..2ee99f8 100644
--- a/include/hwbinder/Parcel.h
+++ b/include/hwbinder/Parcel.h
@@ -23,6 +23,7 @@
 #include <utils/String16.h>
 #include <utils/Vector.h>
 #include <utils/Flattenable.h>
+#include <linux/binder.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
@@ -35,9 +36,8 @@
 class String8;
 class TextOutput;
 
-struct flat_binder_object;  // defined in support_p/binder_module.h
-
 class Parcel {
+    friend class IPCThreadState;
 public:
     class ReadableBlob;
     class WritableBlob;
@@ -81,7 +81,10 @@
 
     void                freeData();
 
-    const size_t*       objects() const;
+private:
+    const binder_size_t* objects() const;
+
+public:
     size_t              objectsCount() const;
     
     status_t            errorCheck() const;
@@ -94,7 +97,6 @@
     status_t            writeInt64(int64_t val);
     status_t            writeFloat(float val);
     status_t            writeDouble(double val);
-    status_t            writeIntPtr(intptr_t val);
     status_t            writeCString(const char* str);
     status_t            writeString8(const String8& str);
     status_t            writeString16(const String16& str);
@@ -126,6 +128,11 @@
     // will be closed once the parcel is destroyed.
     status_t            writeDupFileDescriptor(int fd);
 
+    // Writes a raw fd and optional comm channel fd to the parcel as a ParcelFileDescriptor.
+    // A dup's of the fds are made, which will be closed once the parcel is destroyed.
+    // Null values are passed as -1.
+    status_t            writeParcelFileDescriptor(int fd, int commChannel = -1);
+
     // Writes a blob to the parcel.
     // If the blob is small, then it is stored in-place, otherwise it is
     // transferred by way of an anonymous shared memory region.
@@ -185,6 +192,11 @@
     // in the parcel, which you do not own -- use dup() to get your own copy.
     int                 readFileDescriptor() const;
 
+    // Reads a ParcelFileDescriptor from the parcel.  Returns the raw fd as
+    // the result, and the optional comm channel fd in outCommChannel.
+    // Null values are returned as -1.
+    int                 readParcelFileDescriptor(int& outCommChannel) const;
+
     // Reads a blob from the parcel.
     // The caller should call release() on the blob after reading its contents.
     status_t            readBlob(size_t len, ReadableBlob* outBlob) const;
@@ -194,19 +206,21 @@
     // Explicitly close all file descriptors in the parcel.
     void                closeFileDescriptors();
     
+private:
     typedef void        (*release_func)(Parcel* parcel,
                                         const uint8_t* data, size_t dataSize,
-                                        const size_t* objects, size_t objectsSize,
+                                        const binder_size_t* objects, size_t objectsSize,
                                         void* cookie);
                         
-    const uint8_t*      ipcData() const;
+    uintptr_t           ipcData() const;
     size_t              ipcDataSize() const;
-    const size_t*       ipcObjects() const;
+    uintptr_t           ipcObjects() const;
     size_t              ipcObjectsCount() const;
     void                ipcSetDataReference(const uint8_t* data, size_t dataSize,
-                                            const size_t* objects, size_t objectsCount,
+                                            const binder_size_t* objects, size_t objectsCount,
                                             release_func relFunc, void* relCookie);
     
+public:
     void                print(TextOutput& to, uint32_t flags = 0) const;
 
 private:
@@ -219,6 +233,9 @@
     status_t            growData(size_t len);
     status_t            restartWrite(size_t desired);
     status_t            continueWrite(size_t desired);
+    status_t            writePointer(uintptr_t val);
+    status_t            readPointer(uintptr_t *pArg) const;
+    uintptr_t           readPointer() const;
     void                freeDataNoInit();
     void                initState();
     void                scanForFds() const;
@@ -236,7 +253,7 @@
     size_t              mDataSize;
     size_t              mDataCapacity;
     mutable size_t      mDataPos;
-    size_t*             mObjects;
+    binder_size_t*      mObjects;
     size_t              mObjectsSize;
     size_t              mObjectsCapacity;
     mutable size_t      mNextObjectHint;
diff --git a/include/hwbinder/ProcessState.h b/include/hwbinder/ProcessState.h
index e63a0d0..3bc978d 100644
--- a/include/hwbinder/ProcessState.h
+++ b/include/hwbinder/ProcessState.h
@@ -27,11 +27,6 @@
 // ---------------------------------------------------------------------------
 namespace android {
 
-// Global variables
-extern int                 mArgC;
-extern const char* const*  mArgV;
-extern int                 mArgLen;
-
 class IPCThreadState;
 
 class ProcessState : public virtual RefBase
@@ -62,12 +57,6 @@
             wp<IBinder>         getWeakProxyForHandle(int32_t handle);
             void                expungeHandle(int32_t handle, IBinder* binder);
 
-            void                setArgs(int argc, const char* const argv[]);
-            int                 getArgC() const;
-            const char* const*  getArgV() const;
-
-            void                setArgV0(const char* txt);
-
             void                spawnPooledThread(bool isMain);
             
             status_t            setThreadPoolMaxThreadCount(size_t maxThreads);