Loading libs/binder/ndk/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ cc_library { "ibinder.cpp", "parcel.cpp", "process.cpp", "status.cpp", "service_manager.cpp", ], Loading libs/binder/ndk/ibinder.cpp +38 −33 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android/binder_status.h> #include "parcel_internal.h" #include "status_internal.h" #include <android-base/logging.h> Loading @@ -27,6 +28,7 @@ using DeathRecipient = ::android::IBinder::DeathRecipient; using ::android::IBinder; using ::android::Parcel; using ::android::sp; using ::android::status_t; using ::android::String16; using ::android::wp; Loading Loading @@ -116,17 +118,18 @@ const String16& ABBinder::getInterfaceDescriptor() const { return getClass()->getInterfaceDescriptor(); } binder_status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply, status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply, binder_flags_t flags) { if (isUserCommand(code)) { if (!data.checkInterface(this)) { return EX_ILLEGAL_STATE; return STATUS_PERMISSION_DENIED; } const AParcel in = AParcel::readOnly(this, &data); AParcel out = AParcel(this, reply, false /*owns*/); return getClass()->onTransact(this, code, &in, &out); binder_status_t status = getClass()->onTransact(this, code, &in, &out); return PruneStatusT(status); } else { return BBinder::onTransact(code, data, reply, flags); } Loading Loading @@ -253,13 +256,13 @@ binder_status_t AIBinder_DeathRecipient::linkToDeath(AIBinder* binder, void* coo sp<TransferDeathRecipient> recipient = new TransferDeathRecipient(binder->getBinder(), cookie, mOnDied); binder_status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/); if (status != EX_NONE) { return status; status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/); if (status != STATUS_OK) { return PruneStatusT(status); } mDeathRecipients.push_back(recipient); return EX_NONE; return STATUS_OK; } binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* cookie) { Loading @@ -270,22 +273,19 @@ binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* c for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) { sp<TransferDeathRecipient> recipient = *it; if (recipient->getCookie() == cookie && recipient->getWho() == binder->getBinder()) { if (recipient->getCookie() == cookie && recipient->getWho() == binder->getBinder()) { mDeathRecipients.erase(it.base() - 1); binder_status_t status = binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/); if (status != EX_NONE) { status_t status = binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/); if (status != ::android::OK) { LOG(ERROR) << __func__ << ": removed reference to death recipient but unlink failed."; } return status; return PruneStatusT(status); } } return -ENOENT; return STATUS_NAME_NOT_FOUND; } // start of C-API methods Loading Loading @@ -323,19 +323,20 @@ bool AIBinder_isAlive(const AIBinder* binder) { binder_status_t AIBinder_ping(AIBinder* binder) { if (binder == nullptr) { return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } return binder->getBinder()->pingBinder(); return PruneStatusT(binder->getBinder()->pingBinder()); } binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) { if (binder == nullptr || recipient == nullptr) { LOG(ERROR) << __func__ << ": Must provide binder and recipient."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } // returns binder_status_t return recipient->linkToDeath(binder, cookie); } Loading @@ -343,9 +344,10 @@ binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient void* cookie) { if (binder == nullptr || recipient == nullptr) { LOG(ERROR) << __func__ << ": Must provide binder and recipient."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } // returns binder_status_t return recipient->unlinkToDeath(binder, cookie); } Loading Loading @@ -406,14 +408,14 @@ void* AIBinder_getUserData(AIBinder* binder) { binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { if (binder == nullptr || in == nullptr) { LOG(ERROR) << __func__ << ": requires non-null parameters."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } const AIBinder_Class* clazz = binder->getClass(); if (clazz == nullptr) { LOG(ERROR) << __func__ << ": Class must be defined for a remote binder transaction. See " "AIBinder_associateClass."; return EX_ILLEGAL_STATE; return STATUS_INVALID_OPERATION; } if (!binder->isRemote()) { Loading @@ -424,20 +426,22 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { } *in = new AParcel(binder); binder_status_t status = (**in)->writeInterfaceToken(clazz->getInterfaceDescriptor()); if (status != EX_NONE) { status_t status = (**in)->writeInterfaceToken(clazz->getInterfaceDescriptor()); binder_status_t ret = PruneStatusT(status); if (ret != STATUS_OK) { delete *in; *in = nullptr; } return status; return ret; } binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in, AParcel** out, binder_flags_t flags) { if (in == nullptr) { LOG(ERROR) << __func__ << ": requires non-null in parameter"; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>; Loading @@ -447,36 +451,37 @@ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, APa if (!isUserCommand(code)) { LOG(ERROR) << __func__ << ": Only user-defined transactions can be made from the NDK."; return EX_UNSUPPORTED_OPERATION; return STATUS_UNKNOWN_TRANSACTION; } if ((flags & ~FLAG_ONEWAY) != 0) { LOG(ERROR) << __func__ << ": Unrecognized flags sent: " << flags; return EX_ILLEGAL_ARGUMENT; return STATUS_BAD_VALUE; } if (binder == nullptr || *in == nullptr || out == nullptr) { LOG(ERROR) << __func__ << ": requires non-null parameters."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } if ((*in)->getBinder() != binder) { LOG(ERROR) << __func__ << ": parcel is associated with binder object " << binder << " but called with " << (*in)->getBinder(); return EX_ILLEGAL_STATE; return STATUS_BAD_VALUE; } *out = new AParcel(binder); binder_status_t parcelStatus = status_t status = binder->getBinder()->transact(code, *(*in)->operator->(), (*out)->operator->(), flags); binder_status_t ret = PruneStatusT(status); if (parcelStatus != EX_NONE) { if (ret != STATUS_OK) { delete *out; *out = nullptr; } return parcelStatus; return ret; } AIBinder_DeathRecipient* AIBinder_DeathRecipient_new( Loading libs/binder/ndk/ibinder_internal.h +2 −2 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ struct ABBinder : public AIBinder, public ::android::BBinder { ABBinder* asABBinder() override { return this; } const ::android::String16& getInterfaceDescriptor() const override; binder_status_t onTransact(uint32_t code, const ::android::Parcel& data, ::android::status_t onTransact(uint32_t code, const ::android::Parcel& data, ::android::Parcel* reply, binder_flags_t flags) override; private: Loading libs/binder/ndk/include_ndk/android/binder_ibinder.h +2 −2 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ typedef struct AIBinder_Class AIBinder_Class; * * If the process containing an AIBinder dies, it is possible to be holding a strong reference to * an object which does not exist. In this case, transactions to this binder will return * EX_DEAD_OBJECT. See also AIBinder_linkToDeath, AIBinder_unlinkToDeath, and AIBinder_isAlive. * STATUS_DEAD_OBJECT. See also AIBinder_linkToDeath, AIBinder_unlinkToDeath, and AIBinder_isAlive. * * Once an AIBinder is created, anywhere it is passed (remotely or locally), there is a 1-1 * correspondence between the address of an AIBinder and the object it represents. This means that Loading Loading @@ -211,7 +211,7 @@ binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* /** * Stops registration for the associated binder dying. Does not delete the recipient. This function * may return a binder transaction failure and in case the death recipient cannot be found, it * returns -ENOENT. * returns STATUS_NAME_NOT_FOUND. */ binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie); Loading libs/binder/ndk/include_ndk/android/binder_status.h +37 −10 Original line number Diff line number Diff line Loading @@ -25,12 +25,42 @@ #pragma once #include <errno.h> #include <stdint.h> #include <sys/cdefs.h> __BEGIN_DECLS // Keep the exception codes in sync with android/os/Parcel.java. enum { STATUS_OK = 0, STATUS_UNKNOWN_ERROR = (-2147483647 - 1), // INT32_MIN value STATUS_NO_MEMORY = -ENOMEM, STATUS_INVALID_OPERATION = -ENOSYS, STATUS_BAD_VALUE = -EINVAL, STATUS_BAD_TYPE = (STATUS_UNKNOWN_ERROR + 1), STATUS_NAME_NOT_FOUND = -ENOENT, STATUS_PERMISSION_DENIED = -EPERM, STATUS_NO_INIT = -ENODEV, STATUS_ALREADY_EXISTS = -EEXIST, STATUS_DEAD_OBJECT = -EPIPE, STATUS_FAILED_TRANSACTION = (STATUS_UNKNOWN_ERROR + 2), STATUS_BAD_INDEX = -EOVERFLOW, STATUS_NOT_ENOUGH_DATA = -ENODATA, STATUS_WOULD_BLOCK = -EWOULDBLOCK, STATUS_TIMED_OUT = -ETIMEDOUT, STATUS_UNKNOWN_TRANSACTION = -EBADMSG, STATUS_FDS_NOT_ALLOWED = (STATUS_UNKNOWN_ERROR + 7), STATUS_UNEXPECTED_NULL = (STATUS_UNKNOWN_ERROR + 8), }; /** * One of the STATUS_* values. * * All unrecognized values are coerced into STATUS_UNKNOWN_ERROR. */ typedef int32_t binder_status_t; enum { EX_NONE = 0, EX_SECURITY = -1, Loading @@ -43,12 +73,6 @@ enum { EX_SERVICE_SPECIFIC = -8, EX_PARCELABLE = -9, /** * This is special and Java specific; see Parcel.java. * This should be considered a success, and the next readInt32 bytes can be ignored. */ EX_HAS_REPLY_HEADER = -128, /** * This is special, and indicates to native binder proxies that the * transaction has failed at a low level. Loading @@ -57,10 +81,13 @@ enum { }; /** * One of the above values or -errno. * By convention, positive values are considered to mean service-specific exceptions. * One of the EXCEPTION_* types. * * All unrecognized values are coerced into EXCEPTION_TRANSACTION_FAILED. * * These exceptions values are used by the SDK for parcelables. Also see Parcel.java. */ typedef int32_t binder_status_t; typedef int32_t binder_exception_t; __END_DECLS Loading Loading
libs/binder/ndk/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ cc_library { "ibinder.cpp", "parcel.cpp", "process.cpp", "status.cpp", "service_manager.cpp", ], Loading
libs/binder/ndk/ibinder.cpp +38 −33 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <android/binder_status.h> #include "parcel_internal.h" #include "status_internal.h" #include <android-base/logging.h> Loading @@ -27,6 +28,7 @@ using DeathRecipient = ::android::IBinder::DeathRecipient; using ::android::IBinder; using ::android::Parcel; using ::android::sp; using ::android::status_t; using ::android::String16; using ::android::wp; Loading Loading @@ -116,17 +118,18 @@ const String16& ABBinder::getInterfaceDescriptor() const { return getClass()->getInterfaceDescriptor(); } binder_status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply, status_t ABBinder::onTransact(transaction_code_t code, const Parcel& data, Parcel* reply, binder_flags_t flags) { if (isUserCommand(code)) { if (!data.checkInterface(this)) { return EX_ILLEGAL_STATE; return STATUS_PERMISSION_DENIED; } const AParcel in = AParcel::readOnly(this, &data); AParcel out = AParcel(this, reply, false /*owns*/); return getClass()->onTransact(this, code, &in, &out); binder_status_t status = getClass()->onTransact(this, code, &in, &out); return PruneStatusT(status); } else { return BBinder::onTransact(code, data, reply, flags); } Loading Loading @@ -253,13 +256,13 @@ binder_status_t AIBinder_DeathRecipient::linkToDeath(AIBinder* binder, void* coo sp<TransferDeathRecipient> recipient = new TransferDeathRecipient(binder->getBinder(), cookie, mOnDied); binder_status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/); if (status != EX_NONE) { return status; status_t status = binder->getBinder()->linkToDeath(recipient, cookie, 0 /*flags*/); if (status != STATUS_OK) { return PruneStatusT(status); } mDeathRecipients.push_back(recipient); return EX_NONE; return STATUS_OK; } binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* cookie) { Loading @@ -270,22 +273,19 @@ binder_status_t AIBinder_DeathRecipient::unlinkToDeath(AIBinder* binder, void* c for (auto it = mDeathRecipients.rbegin(); it != mDeathRecipients.rend(); ++it) { sp<TransferDeathRecipient> recipient = *it; if (recipient->getCookie() == cookie && recipient->getWho() == binder->getBinder()) { if (recipient->getCookie() == cookie && recipient->getWho() == binder->getBinder()) { mDeathRecipients.erase(it.base() - 1); binder_status_t status = binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/); if (status != EX_NONE) { status_t status = binder->getBinder()->unlinkToDeath(recipient, cookie, 0 /*flags*/); if (status != ::android::OK) { LOG(ERROR) << __func__ << ": removed reference to death recipient but unlink failed."; } return status; return PruneStatusT(status); } } return -ENOENT; return STATUS_NAME_NOT_FOUND; } // start of C-API methods Loading Loading @@ -323,19 +323,20 @@ bool AIBinder_isAlive(const AIBinder* binder) { binder_status_t AIBinder_ping(AIBinder* binder) { if (binder == nullptr) { return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } return binder->getBinder()->pingBinder(); return PruneStatusT(binder->getBinder()->pingBinder()); } binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie) { if (binder == nullptr || recipient == nullptr) { LOG(ERROR) << __func__ << ": Must provide binder and recipient."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } // returns binder_status_t return recipient->linkToDeath(binder, cookie); } Loading @@ -343,9 +344,10 @@ binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient void* cookie) { if (binder == nullptr || recipient == nullptr) { LOG(ERROR) << __func__ << ": Must provide binder and recipient."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } // returns binder_status_t return recipient->unlinkToDeath(binder, cookie); } Loading Loading @@ -406,14 +408,14 @@ void* AIBinder_getUserData(AIBinder* binder) { binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { if (binder == nullptr || in == nullptr) { LOG(ERROR) << __func__ << ": requires non-null parameters."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } const AIBinder_Class* clazz = binder->getClass(); if (clazz == nullptr) { LOG(ERROR) << __func__ << ": Class must be defined for a remote binder transaction. See " "AIBinder_associateClass."; return EX_ILLEGAL_STATE; return STATUS_INVALID_OPERATION; } if (!binder->isRemote()) { Loading @@ -424,20 +426,22 @@ binder_status_t AIBinder_prepareTransaction(AIBinder* binder, AParcel** in) { } *in = new AParcel(binder); binder_status_t status = (**in)->writeInterfaceToken(clazz->getInterfaceDescriptor()); if (status != EX_NONE) { status_t status = (**in)->writeInterfaceToken(clazz->getInterfaceDescriptor()); binder_status_t ret = PruneStatusT(status); if (ret != STATUS_OK) { delete *in; *in = nullptr; } return status; return ret; } binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, AParcel** in, AParcel** out, binder_flags_t flags) { if (in == nullptr) { LOG(ERROR) << __func__ << ": requires non-null in parameter"; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } using AutoParcelDestroyer = std::unique_ptr<AParcel*, void (*)(AParcel**)>; Loading @@ -447,36 +451,37 @@ binder_status_t AIBinder_transact(AIBinder* binder, transaction_code_t code, APa if (!isUserCommand(code)) { LOG(ERROR) << __func__ << ": Only user-defined transactions can be made from the NDK."; return EX_UNSUPPORTED_OPERATION; return STATUS_UNKNOWN_TRANSACTION; } if ((flags & ~FLAG_ONEWAY) != 0) { LOG(ERROR) << __func__ << ": Unrecognized flags sent: " << flags; return EX_ILLEGAL_ARGUMENT; return STATUS_BAD_VALUE; } if (binder == nullptr || *in == nullptr || out == nullptr) { LOG(ERROR) << __func__ << ": requires non-null parameters."; return EX_NULL_POINTER; return STATUS_UNEXPECTED_NULL; } if ((*in)->getBinder() != binder) { LOG(ERROR) << __func__ << ": parcel is associated with binder object " << binder << " but called with " << (*in)->getBinder(); return EX_ILLEGAL_STATE; return STATUS_BAD_VALUE; } *out = new AParcel(binder); binder_status_t parcelStatus = status_t status = binder->getBinder()->transact(code, *(*in)->operator->(), (*out)->operator->(), flags); binder_status_t ret = PruneStatusT(status); if (parcelStatus != EX_NONE) { if (ret != STATUS_OK) { delete *out; *out = nullptr; } return parcelStatus; return ret; } AIBinder_DeathRecipient* AIBinder_DeathRecipient_new( Loading
libs/binder/ndk/ibinder_internal.h +2 −2 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ struct ABBinder : public AIBinder, public ::android::BBinder { ABBinder* asABBinder() override { return this; } const ::android::String16& getInterfaceDescriptor() const override; binder_status_t onTransact(uint32_t code, const ::android::Parcel& data, ::android::status_t onTransact(uint32_t code, const ::android::Parcel& data, ::android::Parcel* reply, binder_flags_t flags) override; private: Loading
libs/binder/ndk/include_ndk/android/binder_ibinder.h +2 −2 Original line number Diff line number Diff line Loading @@ -97,7 +97,7 @@ typedef struct AIBinder_Class AIBinder_Class; * * If the process containing an AIBinder dies, it is possible to be holding a strong reference to * an object which does not exist. In this case, transactions to this binder will return * EX_DEAD_OBJECT. See also AIBinder_linkToDeath, AIBinder_unlinkToDeath, and AIBinder_isAlive. * STATUS_DEAD_OBJECT. See also AIBinder_linkToDeath, AIBinder_unlinkToDeath, and AIBinder_isAlive. * * Once an AIBinder is created, anywhere it is passed (remotely or locally), there is a 1-1 * correspondence between the address of an AIBinder and the object it represents. This means that Loading Loading @@ -211,7 +211,7 @@ binder_status_t AIBinder_linkToDeath(AIBinder* binder, AIBinder_DeathRecipient* /** * Stops registration for the associated binder dying. Does not delete the recipient. This function * may return a binder transaction failure and in case the death recipient cannot be found, it * returns -ENOENT. * returns STATUS_NAME_NOT_FOUND. */ binder_status_t AIBinder_unlinkToDeath(AIBinder* binder, AIBinder_DeathRecipient* recipient, void* cookie); Loading
libs/binder/ndk/include_ndk/android/binder_status.h +37 −10 Original line number Diff line number Diff line Loading @@ -25,12 +25,42 @@ #pragma once #include <errno.h> #include <stdint.h> #include <sys/cdefs.h> __BEGIN_DECLS // Keep the exception codes in sync with android/os/Parcel.java. enum { STATUS_OK = 0, STATUS_UNKNOWN_ERROR = (-2147483647 - 1), // INT32_MIN value STATUS_NO_MEMORY = -ENOMEM, STATUS_INVALID_OPERATION = -ENOSYS, STATUS_BAD_VALUE = -EINVAL, STATUS_BAD_TYPE = (STATUS_UNKNOWN_ERROR + 1), STATUS_NAME_NOT_FOUND = -ENOENT, STATUS_PERMISSION_DENIED = -EPERM, STATUS_NO_INIT = -ENODEV, STATUS_ALREADY_EXISTS = -EEXIST, STATUS_DEAD_OBJECT = -EPIPE, STATUS_FAILED_TRANSACTION = (STATUS_UNKNOWN_ERROR + 2), STATUS_BAD_INDEX = -EOVERFLOW, STATUS_NOT_ENOUGH_DATA = -ENODATA, STATUS_WOULD_BLOCK = -EWOULDBLOCK, STATUS_TIMED_OUT = -ETIMEDOUT, STATUS_UNKNOWN_TRANSACTION = -EBADMSG, STATUS_FDS_NOT_ALLOWED = (STATUS_UNKNOWN_ERROR + 7), STATUS_UNEXPECTED_NULL = (STATUS_UNKNOWN_ERROR + 8), }; /** * One of the STATUS_* values. * * All unrecognized values are coerced into STATUS_UNKNOWN_ERROR. */ typedef int32_t binder_status_t; enum { EX_NONE = 0, EX_SECURITY = -1, Loading @@ -43,12 +73,6 @@ enum { EX_SERVICE_SPECIFIC = -8, EX_PARCELABLE = -9, /** * This is special and Java specific; see Parcel.java. * This should be considered a success, and the next readInt32 bytes can be ignored. */ EX_HAS_REPLY_HEADER = -128, /** * This is special, and indicates to native binder proxies that the * transaction has failed at a low level. Loading @@ -57,10 +81,13 @@ enum { }; /** * One of the above values or -errno. * By convention, positive values are considered to mean service-specific exceptions. * One of the EXCEPTION_* types. * * All unrecognized values are coerced into EXCEPTION_TRANSACTION_FAILED. * * These exceptions values are used by the SDK for parcelables. Also see Parcel.java. */ typedef int32_t binder_status_t; typedef int32_t binder_exception_t; __END_DECLS Loading