From fe031c88cd51614638f23806e8f61bf993ef46f6 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Fri, 16 Nov 2018 10:47:35 -0800 Subject: libbinder_ndk: parcel_utils for SpAIBinder. binder_parcel_utils.h was originally designed to be convenience wrappers for C++ code, but the AIBinder object methods being added there were using C types. Bug: 111445392 Test: atest android.binder.cts Change-Id: Ice812427104bbb41cc50d070f44dccfa02706ce8 --- .../ndk/include_ndk/android/binder_parcel_utils.h | 42 ++++++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) 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 a478ee0f0c..42e2ae5d9e 100644 --- a/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h +++ b/libs/binder/ndk/include_ndk/android/binder_parcel_utils.h @@ -26,6 +26,7 @@ #pragma once +#include #include #include @@ -151,24 +152,51 @@ static inline void AParcel_nullableStdVectorSetter(void* vectorData, size_t inde vec->value()[index] = value; } +/** + * Convenience method to write a nullable strong binder. + */ +static inline binder_status_t AParcel_writeNullableStrongBinder(AParcel* parcel, + const SpAIBinder& binder) { + return AParcel_writeStrongBinder(parcel, binder.get()); +} + +/** + * Convenience method to read a nullable strong binder. + */ +static inline binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, + SpAIBinder* binder) { + AIBinder* readBinder; + binder_status_t status = AParcel_readStrongBinder(parcel, &readBinder); + if (status == STATUS_OK) { + binder->set(readBinder); + } + return status; +} + /** * Convenience method to write a strong binder but return an error if it is null. */ -static inline binder_status_t AParcel_writeRequiredStrongBinder(AParcel* parcel, AIBinder* binder) { - if (binder == nullptr) { +static inline binder_status_t AParcel_writeRequiredStrongBinder(AParcel* parcel, + const SpAIBinder& binder) { + if (binder.get() == nullptr) { return STATUS_UNEXPECTED_NULL; } - return AParcel_writeStrongBinder(parcel, binder); + return AParcel_writeStrongBinder(parcel, binder.get()); } /** * Convenience method to read a strong binder but return an error if it is null. */ static inline binder_status_t AParcel_readRequiredStrongBinder(const AParcel* parcel, - AIBinder** binder) { - binder_status_t ret = AParcel_readStrongBinder(parcel, binder); - if (ret == STATUS_OK && *binder == nullptr) { - return STATUS_UNEXPECTED_NULL; + SpAIBinder* binder) { + AIBinder* readBinder; + binder_status_t ret = AParcel_readStrongBinder(parcel, &readBinder); + if (ret == STATUS_OK) { + if (readBinder == nullptr) { + return STATUS_UNEXPECTED_NULL; + } + + binder->set(readBinder); } return ret; } -- cgit v1.2.3-59-g8ed1b From 4ce59c78ea8a9f238f440ea7cff455a6dca00db8 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Fri, 16 Nov 2018 15:21:15 -0800 Subject: libbinder_ndk: null ParcelFileDescriptor -1 <=> nullptr Bug: 111445392 Test: atest android.binder.cts Change-Id: I1047ab7f6997672278988ef0079927c1d8a773f5 --- .../binder/ndk/include_ndk/android/binder_parcel.h | 5 ++- .../ndk/include_ndk/android/binder_parcel_utils.h | 48 ++++++++++++++++++++++ libs/binder/ndk/parcel.cpp | 28 ++++++++++--- 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 @@ -201,6 +201,54 @@ static inline binder_status_t AParcel_readRequiredStrongBinder(const AParcel* pa return ret; } +/** + * 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 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(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 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; } -- cgit v1.2.3-59-g8ed1b