Add support for sending and receiving ParcelFileDescriptors from native Binder code

Change-Id: I7f308e28ebac0755628e19c9b4d0d7399341b435
This commit is contained in:
Mike Lockwood 2013-09-05 08:41:06 -07:00
parent 31344a6d4d
commit cbe36fe1ec
2 changed files with 53 additions and 0 deletions

View File

@ -124,6 +124,11 @@ public:
// 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.
@ -183,6 +188,11 @@ public:
// 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;

View File

@ -750,6 +750,32 @@ status_t Parcel::writeDupFileDescriptor(int fd)
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;
@ -1148,6 +1174,23 @@ int Parcel::readFileDescriptor() const
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;