diff options
| -rw-r--r-- | include/binder/Parcel.h | 18 | ||||
| -rw-r--r-- | libs/binder/Parcel.cpp | 16 |
2 files changed, 32 insertions, 2 deletions
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index 44fd59e1d2..9c3877ec4a 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -252,6 +252,7 @@ public: const char16_t* readString16Inplace(size_t* outLen) const; sp<IBinder> readStrongBinder() const; status_t readStrongBinder(sp<IBinder>* val) const; + status_t readNullableStrongBinder(sp<IBinder>* val) const; wp<IBinder> readWeakBinder() const; template<typename T> @@ -268,6 +269,9 @@ public: template<typename T> status_t readStrongBinder(sp<T>* val) const; + template<typename T> + status_t readNullableStrongBinder(sp<T>* val) const; + status_t readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const; status_t readStrongBinderVector(std::vector<sp<IBinder>>* val) const; @@ -574,6 +578,20 @@ status_t Parcel::readStrongBinder(sp<T>* val) const { return ret; } +template<typename T> +status_t Parcel::readNullableStrongBinder(sp<T>* val) const { + sp<IBinder> tmp; + status_t ret = readNullableStrongBinder(&tmp); + + if (ret == OK) { + *val = interface_cast<T>(tmp); + + if (val->get() == nullptr) { + return UNKNOWN_ERROR; + } + } +} + template<typename T, typename U> status_t Parcel::unsafeReadTypedVector( std::vector<T>* val, diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 678d98bc8a..1ecc5cef35 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1109,7 +1109,7 @@ status_t Parcel::writeStrongBinderVector(const std::unique_ptr<std::vector<sp<IB } status_t Parcel::readStrongBinderVector(std::unique_ptr<std::vector<sp<IBinder>>>* val) const { - return readNullableTypedVector(val, &Parcel::readStrongBinder); + return readNullableTypedVector(val, &Parcel::readNullableStrongBinder); } status_t Parcel::readStrongBinderVector(std::vector<sp<IBinder>>* val) const { @@ -1905,13 +1905,25 @@ const char16_t* Parcel::readString16Inplace(size_t* outLen) const status_t Parcel::readStrongBinder(sp<IBinder>* val) const { + status_t status = readNullableStrongBinder(val); + if (status == OK && !val->get()) { + status = UNEXPECTED_NULL; + } + return status; +} + +status_t Parcel::readNullableStrongBinder(sp<IBinder>* val) const +{ return unflatten_binder(ProcessState::self(), *this, val); } sp<IBinder> Parcel::readStrongBinder() const { sp<IBinder> val; - readStrongBinder(&val); + // Note that a lot of code in Android reads binders by hand with this + // method, and that code has historically been ok with getting nullptr + // back (while ignoring error codes). + readNullableStrongBinder(&val); return val; } |