Merge "Add support for unique_fds and vectors of file descriptors"
am: b1819fc295

* commit 'b1819fc295811ca3a005042a80149c8d0655211f':
  Add support for unique_fds and vectors of file descriptors
diff --git a/Parcel.cpp b/Parcel.cpp
index 7859826..92b80e9 100644
--- a/Parcel.cpp
+++ b/Parcel.cpp
@@ -96,7 +96,7 @@
 };
 
 void acquire_object(const sp<ProcessState>& proc,
-    const flat_binder_object& obj, const void* who)
+    const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
 {
     switch (obj.type) {
         case BINDER_TYPE_BINDER:
@@ -123,8 +123,15 @@
             return;
         }
         case BINDER_TYPE_FD: {
-            // intentionally blank -- nothing to do to acquire this, but we do
-            // recognize it as a legitimate object type.
+            if (obj.cookie != 0) {
+                if (outAshmemSize != NULL) {
+                    // If we own an ashmem fd, keep track of how much memory it refers to.
+                    int size = ashmem_get_size_region(obj.handle);
+                    if (size > 0) {
+                        *outAshmemSize += size;
+                    }
+                }
+            }
             return;
         }
     }
@@ -132,9 +139,15 @@
     ALOGD("Invalid object type 0x%08x", obj.type);
 }
 
-void release_object(const sp<ProcessState>& proc,
+void acquire_object(const sp<ProcessState>& proc,
     const flat_binder_object& obj, const void* who)
 {
+    acquire_object(proc, obj, who, NULL);
+}
+
+static void release_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who, size_t* outAshmemSize)
+{
     switch (obj.type) {
         case BINDER_TYPE_BINDER:
             if (obj.binder) {
@@ -160,7 +173,16 @@
             return;
         }
         case BINDER_TYPE_FD: {
-            if (obj.cookie != 0) close(obj.handle);
+            if (outAshmemSize != NULL) {
+                if (obj.cookie != 0) {
+                    int size = ashmem_get_size_region(obj.handle);
+                    if (size > 0) {
+                        *outAshmemSize -= size;
+                    }
+
+                    close(obj.handle);
+                }
+            }
             return;
         }
     }
@@ -168,6 +190,12 @@
     ALOGE("Invalid object type 0x%08x", obj.type);
 }
 
+void release_object(const sp<ProcessState>& proc,
+    const flat_binder_object& obj, const void* who)
+{
+    release_object(proc, obj, who, NULL);
+}
+
 inline static status_t finish_flatten_binder(
     const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
 {
@@ -537,7 +565,7 @@
 
             flat_binder_object* flat
                 = reinterpret_cast<flat_binder_object*>(mData + off);
-            acquire_object(proc, *flat, this);
+            acquire_object(proc, *flat, this, &mOpenAshmemSize);
 
             if (flat->type == BINDER_TYPE_FD) {
                 // If this is a file descriptor, we need to dup it so the
@@ -1086,8 +1114,6 @@
     int fd = ashmem_create_region("Parcel Blob", len);
     if (fd < 0) return NO_MEMORY;
 
-    mBlobAshmemSize += len;
-
     int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE);
     if (result < 0) {
         status = result;
@@ -1189,7 +1215,7 @@
         // Need to write meta-data?
         if (nullMetaData || val.binder != 0) {
             mObjects[mObjectsSize] = mDataPos;
-            acquire_object(ProcessState::self(), val, this);
+            acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
             mObjectsSize++;
         }
 
@@ -1927,7 +1953,7 @@
         i--;
         const flat_binder_object* flat
             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
-        release_object(proc, *flat, this);
+        release_object(proc, *flat, this, &mOpenAshmemSize);
     }
 }
 
@@ -1941,7 +1967,7 @@
         i--;
         const flat_binder_object* flat
             = reinterpret_cast<flat_binder_object*>(data+objects[i]);
-        acquire_object(proc, *flat, this);
+        acquire_object(proc, *flat, this, &mOpenAshmemSize);
     }
 }
 
@@ -2129,7 +2155,7 @@
                     // will need to rescan because we may have lopped off the only FDs
                     mFdsKnown = false;
                 }
-                release_object(proc, *flat, this);
+                release_object(proc, *flat, this, &mOpenAshmemSize);
             }
             binder_size_t* objects =
                 (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t));
@@ -2215,7 +2241,7 @@
     mFdsKnown = true;
     mAllowFds = true;
     mOwner = NULL;
-    mBlobAshmemSize = 0;
+    mOpenAshmemSize = 0;
 }
 
 void Parcel::scanForFds() const
@@ -2235,7 +2261,15 @@
 
 size_t Parcel::getBlobAshmemSize() const
 {
-    return mBlobAshmemSize;
+    // This used to return the size of all blobs that were written to ashmem, now we're returning
+    // the ashmem currently referenced by this Parcel, which should be equivalent.
+    // TODO: Remove method once ABI can be changed.
+    return mOpenAshmemSize;
+}
+
+size_t Parcel::getOpenAshmemSize() const
+{
+    return mOpenAshmemSize;
 }
 
 // --- Parcel::Blob ---
diff --git a/include/hwbinder/Parcel.h b/include/hwbinder/Parcel.h
index 778f9aa..ed30239 100644
--- a/include/hwbinder/Parcel.h
+++ b/include/hwbinder/Parcel.h
@@ -402,10 +402,12 @@
     };
 
 private:
-    size_t mBlobAshmemSize;
+    size_t mOpenAshmemSize;
 
 public:
+    // TODO: Remove once ABI can be changed.
     size_t getBlobAshmemSize() const;
+    size_t getOpenAshmemSize() const;
 };
 
 // ---------------------------------------------------------------------------