diff options
| author | 2018-10-18 12:49:11 -0700 | |
|---|---|---|
| committer | 2018-10-30 17:42:16 -0700 | |
| commit | 063f236689aa009bde8e20e221be07c8dd67c906 (patch) | |
| tree | 2f6de3faaded0cdfa1288063d9af03473662bd98 | |
| parent | eddf8dd3601f3c78f5112d0a8ccb68b23887f86a (diff) | |
libbinder_ndk: read/write ParcelFileDescriptor
Bug: 115607973
Test: atest android.binder.cts
Change-Id: Ic9ef70cba95a12f3765573d24d87fd15021ab7a9
| -rw-r--r-- | libs/binder/ndk/include_ndk/android/binder_auto_utils.h | 40 | ||||
| -rw-r--r-- | libs/binder/ndk/include_ndk/android/binder_parcel.h | 17 | ||||
| -rw-r--r-- | libs/binder/ndk/libbinder_ndk.map.txt | 2 | ||||
| -rw-r--r-- | libs/binder/ndk/parcel.cpp | 26 |
4 files changed, 73 insertions, 12 deletions
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h index cc0a29d18a..e52a1d69ae 100644 --- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h +++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h @@ -31,6 +31,7 @@ #include <android/binder_status.h> #include <assert.h> +#include <unistd.h> #ifdef __cplusplus @@ -113,23 +114,23 @@ private: /** * This baseclass owns a single object, used to make various classes RAII. */ -template <typename T, void (*Destroy)(T*)> +template <typename T, typename R, R (*Destroy)(T), T DEFAULT> class ScopedAResource { public: /** * Takes ownership of t. */ - explicit ScopedAResource(T* t = nullptr) : mT(t) {} + explicit ScopedAResource(T t = DEFAULT) : mT(t) {} /** * This deletes the underlying object if it exists. See set. */ - ~ScopedAResource() { set(nullptr); } + ~ScopedAResource() { set(DEFAULT); } /** * Takes ownership of t. */ - void set(T* t) { + void set(T t) { Destroy(mT); mT = t; } @@ -137,12 +138,12 @@ public: /** * This returns the underlying object to be modified but does not affect ownership. */ - T* get() { return mT; } + T get() { return mT; } /** * This returns the const underlying object but does not affect ownership. */ - const T* get() const { return mT; } + const T get() const { return mT; } /** * This allows the value in this class to be set from beneath it. If you call this method and @@ -156,7 +157,7 @@ public: * Other usecases are discouraged. * */ - T** getR() { return &mT; } + T* getR() { return &mT; } // copy-constructing, or move/copy assignment is disallowed ScopedAResource(const ScopedAResource&) = delete; @@ -167,13 +168,13 @@ public: ScopedAResource(ScopedAResource&&) = default; private: - T* mT; + T mT; }; /** * Convenience wrapper. See AParcel. */ -class ScopedAParcel : public ScopedAResource<AParcel, AParcel_delete> { +class ScopedAParcel : public ScopedAResource<AParcel*, void, AParcel_delete, nullptr> { public: /** * Takes ownership of a. @@ -186,7 +187,7 @@ public: /** * Convenience wrapper. See AStatus. */ -class ScopedAStatus : public ScopedAResource<AStatus, AStatus_delete> { +class ScopedAStatus : public ScopedAResource<AStatus*, void, AStatus_delete, nullptr> { public: /** * Takes ownership of a. @@ -205,7 +206,8 @@ public: * Convenience wrapper. See AIBinder_DeathRecipient. */ class ScopedAIBinder_DeathRecipient - : public ScopedAResource<AIBinder_DeathRecipient, AIBinder_DeathRecipient_delete> { + : public ScopedAResource<AIBinder_DeathRecipient*, void, AIBinder_DeathRecipient_delete, + nullptr> { public: /** * Takes ownership of a. @@ -219,7 +221,8 @@ public: /** * Convenience wrapper. See AIBinder_Weak. */ -class ScopedAIBinder_Weak : public ScopedAResource<AIBinder_Weak, AIBinder_Weak_delete> { +class ScopedAIBinder_Weak + : public ScopedAResource<AIBinder_Weak*, void, AIBinder_Weak_delete, nullptr> { public: /** * Takes ownership of a. @@ -234,6 +237,19 @@ public: SpAIBinder promote() { return SpAIBinder(AIBinder_Weak_promote(get())); } }; +/** + * Convenience wrapper for a file descriptor. + */ +class ScopedFileDescriptor : public ScopedAResource<int, int, close, -1> { +public: + /** + * Takes ownership of a. + */ + explicit ScopedFileDescriptor(int a = -1) : ScopedAResource(a) {} + ~ScopedFileDescriptor() {} + ScopedFileDescriptor(ScopedFileDescriptor&&) = default; +}; + } // namespace ndk #endif // __cplusplus diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h index d36b3c06f3..0c0400180a 100644 --- a/libs/binder/ndk/include_ndk/android/binder_parcel.h +++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h @@ -163,6 +163,23 @@ binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder __INTRODUCED_IN(29); /** + * Writes a file descriptor to the next location in a non-null parcel. This does not take ownership + * of fd. + * + * This corresponds to the SDK's android.os.ParcelFileDescriptor. + */ +binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd); + +/** + * Reads an int from the next location in a non-null parcel. + * + * The returned fd must be closed. + * + * This corresponds to the SDK's android.os.ParcelFileDescriptor. + */ +binder_status_t AParcel_readParcelFileDescriptor(const AParcel* parcel, int* fd); + +/** * Writes an AStatus object to the next location in a non-null parcel. * * If the status is considered to be a low-level status and has no additional information other diff --git a/libs/binder/ndk/libbinder_ndk.map.txt b/libs/binder/ndk/libbinder_ndk.map.txt index f84814fa3c..ec6587a7e4 100644 --- a/libs/binder/ndk/libbinder_ndk.map.txt +++ b/libs/binder/ndk/libbinder_ndk.map.txt @@ -38,6 +38,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_readInt64; AParcel_readInt64Array; AParcel_readNullableStrongBinder; + AParcel_readParcelFileDescriptor; AParcel_readStatusHeader; AParcel_readString; AParcel_readStrongBinder; @@ -59,6 +60,7 @@ LIBBINDER_NDK { # introduced=29 AParcel_writeInt32Array; AParcel_writeInt64; AParcel_writeInt64Array; + AParcel_writeParcelFileDescriptor; AParcel_writeStatusHeader; AParcel_writeString; AParcel_writeStrongBinder; diff --git a/libs/binder/ndk/parcel.cpp b/libs/binder/ndk/parcel.cpp index 29094dba7b..ffa5caedba 100644 --- a/libs/binder/ndk/parcel.cpp +++ b/libs/binder/ndk/parcel.cpp @@ -23,13 +23,17 @@ #include <limits> #include <android-base/logging.h> +#include <android-base/unique_fd.h> #include <binder/Parcel.h> +#include <binder/ParcelFileDescriptor.h> #include <utils/Unicode.h> using ::android::IBinder; using ::android::Parcel; using ::android::sp; using ::android::status_t; +using ::android::base::unique_fd; +using ::android::os::ParcelFileDescriptor; template <typename T> using ContiguousArrayGetter = T* (*)(void* arrayData); @@ -218,6 +222,28 @@ binder_status_t AParcel_readNullableStrongBinder(const AParcel* parcel, AIBinder *binder = ret.get(); return PruneStatusT(status); } + +binder_status_t AParcel_writeParcelFileDescriptor(AParcel* parcel, int fd) { + ParcelFileDescriptor parcelFd((unique_fd(fd))); + + status_t status = parcel->get()->writeParcelable(parcelFd); + + // ownership is retained by caller + (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()); + status_t status = parcel->get()->readParcelable(&parcelFd); + if (status != STATUS_OK) return PruneStatusT(status); + + *fd = parcelFd.release().release(); + return STATUS_OK; +} + binder_status_t AParcel_writeStatusHeader(AParcel* parcel, const AStatus* status) { return PruneStatusT(status->get()->writeToParcel(parcel->get())); } |