summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteven Moreland <smoreland@google.com>2018-11-16 15:21:15 -0800
committerSteven Moreland <smoreland@google.com>2018-11-16 15:21:15 -0800
commit4ce59c78ea8a9f238f440ea7cff455a6dca00db8 (patch)
tree4ede778542661346736ab060c5ed6429121a6c14
parentfe031c88cd51614638f23806e8f61bf993ef46f6 (diff)
downloadnative-4ce59c78ea8a9f238f440ea7cff455a6dca00db8.tar.gz
libbinder_ndk: null ParcelFileDescriptor
-1 <=> nullptr Bug: 111445392 Test: atest android.binder.cts Change-Id: I1047ab7f6997672278988ef0079927c1d8a773f5
-rw-r--r--libs/binder/ndk/include_ndk/android/binder_parcel.h5
-rw-r--r--libs/binder/ndk/include_ndk/android/binder_parcel_utils.h48
-rw-r--r--libs/binder/ndk/parcel.cpp28
3 files changed, 73 insertions, 8 deletions
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index b021c23610..3594349021 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -347,7 +347,7 @@ binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binde
* This corresponds to the SDK's android.os.ParcelFileDescriptor.
*
* \param parcel the parcel to write to.
- * \param fd the value to write to the parcel.
+ * \param fd the value to write to the parcel (-1 to represent a null ParcelFileDescriptor).
*
* \return STATUS_OK on successful write.
*/
@@ -361,7 +361,8 @@ binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd);
* This corresponds to the SDK's android.os.ParcelFileDescriptor.
*
* \param parcel the parcel to read from.
- * \param binder the out parameter for what is read from the parcel.
+ * \param fd the out parameter for what is read from the parcel (or -1 to represent a null
+ * ParcelFileDescriptor)
*
* \return STATUS_OK on successful write.
*/
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
index 42e2ae5d9e..f99c3a92e2 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h
@@ -202,6 +202,54 @@ static inline binder_status_t AParcel_readRequiredStrongBinder(const AParcel* pa
}
/**
+ * Convenience method to write a ParcelFileDescriptor where -1 represents a null value.
+ */
+static inline binder_status_t AParcel_writeNullableParcelFileDescriptor(
+ AParcel* parcel, const ScopedFileDescriptor& fd) {
+ return AParcel_writeParcelFileDescriptor(parcel, fd.get());
+}
+
+/**
+ * Convenience method to read a ParcelFileDescriptor where -1 represents a null value.
+ */
+static inline binder_status_t AParcel_readNullableParcelFileDescriptor(const AParcel* parcel,
+ ScopedFileDescriptor* fd) {
+ int readFd;
+ binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
+ if (status == STATUS_OK) {
+ fd->set(readFd);
+ }
+ return status;
+}
+
+/**
+ * Convenience method to write a valid ParcelFileDescriptor.
+ */
+static inline binder_status_t AParcel_writeRequiredParcelFileDescriptor(
+ AParcel* parcel, const ScopedFileDescriptor& fd) {
+ if (fd.get() < 0) {
+ return STATUS_UNEXPECTED_NULL;
+ }
+ return AParcel_writeParcelFileDescriptor(parcel, fd.get());
+}
+
+/**
+ * Convenience method to read a valid ParcelFileDescriptor.
+ */
+static inline binder_status_t AParcel_readRequiredParcelFileDescriptor(const AParcel* parcel,
+ ScopedFileDescriptor* fd) {
+ int readFd;
+ binder_status_t status = AParcel_readParcelFileDescriptor(parcel, &readFd);
+ if (status == STATUS_OK) {
+ if (readFd < 0) {
+ return STATUS_UNEXPECTED_NULL;
+ }
+ fd->set(readFd);
+ }
+ return status;
+}
+
+/**
* Allocates a std::string to length and returns the underlying buffer. For use with
* AParcel_readString. See use below in AParcel_readString(const AParcel*, std::string*).
*/
diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp
index b1a295584a..3c321009f8 100644
--- a/libs/binder/ndk/parcel.cpp
+++ b/libs/binder/ndk/parcel.cpp
@@ -229,23 +229,39 @@ binder_status_t AParcel_readStrongBinder(const AParcel* parcel, AIBinder** binde
}
binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) {
- ParcelFileDescriptor parcelFd((unique_fd(fd)));
+ std::unique_ptr<ParcelFileDescriptor> parcelFd;
- status_t status = parcel->get()->writeParcelable(parcelFd);
+ if (fd < 0) {
+ if (fd != -1) {
+ return STATUS_UNKNOWN_ERROR;
+ }
+ // parcelFd = nullptr
+ } else { // fd >= 0
+ parcelFd = std::make_unique<ParcelFileDescriptor>(unique_fd(fd));
+ }
+
+ status_t status = parcel->get()->writeNullableParcelable(parcelFd);
// ownership is retained by caller
- (void)parcelFd.release().release();
+ if (parcelFd != nullptr) {
+ (void)parcelFd->release().release();
+ }
return PruneStatusT(status);
}
binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd) {
- ParcelFileDescriptor parcelFd;
- // status_t status = parcelFd.readFromParcel(parcel->get());
+ std::unique_ptr<ParcelFileDescriptor> parcelFd;
+
status_t status = parcel->get()->readParcelable(&parcelFd);
if (status != STATUS_OK) return PruneStatusT(status);
- *fd = parcelFd.release().release();
+ if (parcelFd) {
+ *fd = parcelFd->release().release();
+ } else {
+ *fd = -1;
+ }
+
return STATUS_OK;
}