Loading libs/binder/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,10 @@ cc_library { "ParcelFileDescriptor.cpp", "PersistableBundle.cpp", "ProcessState.cpp", "RpcAddress.cpp", "RpcConnection.cpp", "RpcServer.cpp", "RpcState.cpp", "Static.cpp", "Stability.cpp", "Status.cpp", Loading libs/binder/BpBinder.cpp +91 −36 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> #include <binder/RpcConnection.h> #include <binder/Stability.h> #include <cutils/compiler.h> #include <utils/Log.h> Loading Loading @@ -133,25 +134,56 @@ BpBinder* BpBinder::create(int32_t handle) { } sTrackingMap[trackedUid]++; } return new BpBinder(handle, trackedUid); return new BpBinder(BinderHandle{handle}, trackedUid); } BpBinder::BpBinder(int32_t handle, int32_t trackedUid) : mStability(0) , mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(nullptr) , mTrackedUid(trackedUid) { ALOGV("Creating BpBinder %p handle %d\n", this, mHandle); BpBinder* BpBinder::create(const sp<RpcConnection>& connection, const RpcAddress& address) { LOG_ALWAYS_FATAL_IF(connection == nullptr, "BpBinder::create null connection"); // These are not currently tracked, since there is no UID or other // identifier to track them with. However, if similar functionality is // needed, connection objects keep track of all BpBinder objects on a // per-connection basis. return new BpBinder(SocketHandle{connection, address}); } BpBinder::BpBinder(Handle&& handle) : mStability(0), mHandle(handle), mAlive(true), mObitsSent(false), mObituaries(nullptr), mTrackedUid(-1) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle, this); } int32_t BpBinder::handle() const { return mHandle; BpBinder::BpBinder(BinderHandle&& handle, int32_t trackedUid) : BpBinder(Handle(handle)) { mTrackedUid = trackedUid; ALOGV("Creating BpBinder %p handle %d\n", this, this->binderHandle()); IPCThreadState::self()->incWeakHandle(this->binderHandle(), this); } BpBinder::BpBinder(SocketHandle&& handle) : BpBinder(Handle(handle)) { LOG_ALWAYS_FATAL_IF(rpcConnection() == nullptr, "BpBinder created w/o connection object"); } bool BpBinder::isRpcBinder() const { return std::holds_alternative<SocketHandle>(mHandle); } const RpcAddress& BpBinder::rpcAddress() const { return std::get<SocketHandle>(mHandle).address; } const sp<RpcConnection>& BpBinder::rpcConnection() const { return std::get<SocketHandle>(mHandle).connection; } int32_t BpBinder::binderHandle() const { return std::get<BinderHandle>(mHandle).handle; } bool BpBinder::isDescriptorCached() const { Loading Loading @@ -190,9 +222,10 @@ bool BpBinder::isBinderAlive() const status_t BpBinder::pingBinder() { Parcel send; Parcel data; data.markForBinder(this); Parcel reply; return transact(PING_TRANSACTION, send, &reply); return transact(PING_TRANSACTION, data, &reply); } status_t BpBinder::dump(int fd, const Vector<String16>& args) Loading Loading @@ -236,8 +269,13 @@ status_t BpBinder::transact( } } status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); status_t status; if (CC_UNLIKELY(isRpcBinder())) { status = rpcConnection()->transact(rpcAddress(), code, data, reply, flags); } else { status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags); } if (status == DEAD_OBJECT) mAlive = 0; return status; Loading @@ -250,6 +288,8 @@ status_t BpBinder::transact( status_t BpBinder::linkToDeath( const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) { if (isRpcBinder()) return UNKNOWN_TRANSACTION; Obituary ob; ob.recipient = recipient; ob.cookie = cookie; Loading @@ -267,10 +307,10 @@ status_t BpBinder::linkToDeath( if (!mObituaries) { return NO_MEMORY; } ALOGV("Requesting death notification: %p handle %d\n", this, mHandle); ALOGV("Requesting death notification: %p handle %d\n", this, binderHandle()); getWeakRefs()->incWeak(this); IPCThreadState* self = IPCThreadState::self(); self->requestDeathNotification(mHandle, this); self->requestDeathNotification(binderHandle(), this); self->flushCommands(); } ssize_t res = mObituaries->add(ob); Loading @@ -286,6 +326,8 @@ status_t BpBinder::unlinkToDeath( const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, wp<DeathRecipient>* outRecipient) { if (isRpcBinder()) return UNKNOWN_TRANSACTION; AutoMutex _l(mLock); if (mObitsSent) { Loading @@ -303,9 +345,9 @@ status_t BpBinder::unlinkToDeath( } mObituaries->removeAt(i); if (mObituaries->size() == 0) { ALOGV("Clearing death notification: %p handle %d\n", this, mHandle); ALOGV("Clearing death notification: %p handle %d\n", this, binderHandle()); IPCThreadState* self = IPCThreadState::self(); self->clearDeathNotification(mHandle, this); self->clearDeathNotification(binderHandle(), this); self->flushCommands(); delete mObituaries; mObituaries = nullptr; Loading @@ -319,8 +361,10 @@ status_t BpBinder::unlinkToDeath( void BpBinder::sendObituary() { ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", this, mHandle, mObitsSent ? "true" : "false"); LOG_ALWAYS_FATAL_IF(isRpcBinder(), "Cannot send obituary for remote binder."); ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", this, binderHandle(), mObitsSent ? "true" : "false"); mAlive = 0; if (mObitsSent) return; Loading @@ -328,9 +372,9 @@ void BpBinder::sendObituary() mLock.lock(); Vector<Obituary>* obits = mObituaries; if(obits != nullptr) { ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle); ALOGV("Clearing sent death notification: %p handle %d\n", this, binderHandle()); IPCThreadState* self = IPCThreadState::self(); self->clearDeathNotification(mHandle, this); self->clearDeathNotification(binderHandle(), this); self->flushCommands(); mObituaries = nullptr; } Loading Loading @@ -388,7 +432,9 @@ BpBinder* BpBinder::remoteBinder() BpBinder::~BpBinder() { ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle); ALOGV("Destroying BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) return; IPCThreadState* ipc = IPCThreadState::self(); Loading @@ -396,7 +442,8 @@ BpBinder::~BpBinder() AutoMutex _l(sTrackingLock); uint32_t trackedValue = sTrackingMap[mTrackedUid]; if (CC_UNLIKELY((trackedValue & COUNTING_VALUE_MASK) == 0)) { ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this, mHandle); ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this, binderHandle()); } else { if (CC_UNLIKELY( (trackedValue & LIMIT_REACHED_MASK) && Loading @@ -413,26 +460,31 @@ BpBinder::~BpBinder() } if (ipc) { ipc->expungeHandle(mHandle, this); ipc->decWeakHandle(mHandle); ipc->expungeHandle(binderHandle(), this); ipc->decWeakHandle(binderHandle()); } } void BpBinder::onFirstRef() { ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle); ALOGV("onFirstRef BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) return; IPCThreadState* ipc = IPCThreadState::self(); if (ipc) ipc->incStrongHandle(mHandle, this); if (ipc) ipc->incStrongHandle(binderHandle(), this); } void BpBinder::onLastStrongRef(const void* /*id*/) { ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle); ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) { (void)rpcConnection()->sendDecStrong(rpcAddress()); return; } IF_ALOGV() { printRefs(); } IPCThreadState* ipc = IPCThreadState::self(); if (ipc) ipc->decStrongHandle(mHandle); if (ipc) ipc->decStrongHandle(binderHandle()); mLock.lock(); Vector<Obituary>* obits = mObituaries; Loading @@ -442,7 +494,7 @@ void BpBinder::onLastStrongRef(const void* /*id*/) mDescriptorCache.size() ? String8(mDescriptorCache).c_str() : "<uncached descriptor>"); } if (ipc) ipc->clearDeathNotification(mHandle, this); if (ipc) ipc->clearDeathNotification(binderHandle(), this); mObituaries = nullptr; } mLock.unlock(); Loading @@ -457,9 +509,12 @@ void BpBinder::onLastStrongRef(const void* /*id*/) bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/) { ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle); // RPC binder doesn't currently support inc from weak binders if (CC_UNLIKELY(isRpcBinder())) return false; ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, binderHandle()); IPCThreadState* ipc = IPCThreadState::self(); return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false; return ipc ? ipc->attemptIncStrongHandle(binderHandle()) == NO_ERROR : false; } uint32_t BpBinder::getBinderProxyCount(uint32_t uid) Loading libs/binder/Debug.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,22 @@ namespace android { std::string hexString(const void* bytes, size_t len) { if (bytes == nullptr) return "<null>"; const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes); const char chars[] = "0123456789abcdef"; std::string result; result.resize(len * 2); for (size_t i = 0; i < len; i++) { result[2 * i] = chars[bytes8[i] >> 4]; result[2 * i + 1] = chars[bytes8[i] & 0xf]; } return result; } // --------------------------------------------------------------------- static const char indentStr[] = Loading libs/binder/Debug.h +2 −4 Original line number Diff line number Diff line Loading @@ -17,13 +17,13 @@ #pragma once #include <stdint.h> #include <sys/cdefs.h> #include <sys/types.h> #include <string> namespace android { // --------------------------------------------------------------------------- __BEGIN_DECLS std::string hexString(const void* data, size_t size); const char* stringForIndent(int32_t indentLevel); Loading @@ -40,7 +40,5 @@ void printHexData(int32_t indent, const void *buf, size_t length, ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf); __END_DECLS // --------------------------------------------------------------------------- } // namespace android libs/binder/IPCThreadState.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -689,6 +689,8 @@ status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { LOG_ALWAYS_FATAL_IF(data.isForRpc(), "Parcel constructed for RPC, but being used with binder."); status_t err; flags |= TF_ACCEPT_FDS; Loading Loading
libs/binder/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -124,6 +124,10 @@ cc_library { "ParcelFileDescriptor.cpp", "PersistableBundle.cpp", "ProcessState.cpp", "RpcAddress.cpp", "RpcConnection.cpp", "RpcServer.cpp", "RpcState.cpp", "Static.cpp", "Stability.cpp", "Status.cpp", Loading
libs/binder/BpBinder.cpp +91 −36 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <binder/IPCThreadState.h> #include <binder/IResultReceiver.h> #include <binder/RpcConnection.h> #include <binder/Stability.h> #include <cutils/compiler.h> #include <utils/Log.h> Loading Loading @@ -133,25 +134,56 @@ BpBinder* BpBinder::create(int32_t handle) { } sTrackingMap[trackedUid]++; } return new BpBinder(handle, trackedUid); return new BpBinder(BinderHandle{handle}, trackedUid); } BpBinder::BpBinder(int32_t handle, int32_t trackedUid) : mStability(0) , mHandle(handle) , mAlive(1) , mObitsSent(0) , mObituaries(nullptr) , mTrackedUid(trackedUid) { ALOGV("Creating BpBinder %p handle %d\n", this, mHandle); BpBinder* BpBinder::create(const sp<RpcConnection>& connection, const RpcAddress& address) { LOG_ALWAYS_FATAL_IF(connection == nullptr, "BpBinder::create null connection"); // These are not currently tracked, since there is no UID or other // identifier to track them with. However, if similar functionality is // needed, connection objects keep track of all BpBinder objects on a // per-connection basis. return new BpBinder(SocketHandle{connection, address}); } BpBinder::BpBinder(Handle&& handle) : mStability(0), mHandle(handle), mAlive(true), mObitsSent(false), mObituaries(nullptr), mTrackedUid(-1) { extendObjectLifetime(OBJECT_LIFETIME_WEAK); IPCThreadState::self()->incWeakHandle(handle, this); } int32_t BpBinder::handle() const { return mHandle; BpBinder::BpBinder(BinderHandle&& handle, int32_t trackedUid) : BpBinder(Handle(handle)) { mTrackedUid = trackedUid; ALOGV("Creating BpBinder %p handle %d\n", this, this->binderHandle()); IPCThreadState::self()->incWeakHandle(this->binderHandle(), this); } BpBinder::BpBinder(SocketHandle&& handle) : BpBinder(Handle(handle)) { LOG_ALWAYS_FATAL_IF(rpcConnection() == nullptr, "BpBinder created w/o connection object"); } bool BpBinder::isRpcBinder() const { return std::holds_alternative<SocketHandle>(mHandle); } const RpcAddress& BpBinder::rpcAddress() const { return std::get<SocketHandle>(mHandle).address; } const sp<RpcConnection>& BpBinder::rpcConnection() const { return std::get<SocketHandle>(mHandle).connection; } int32_t BpBinder::binderHandle() const { return std::get<BinderHandle>(mHandle).handle; } bool BpBinder::isDescriptorCached() const { Loading Loading @@ -190,9 +222,10 @@ bool BpBinder::isBinderAlive() const status_t BpBinder::pingBinder() { Parcel send; Parcel data; data.markForBinder(this); Parcel reply; return transact(PING_TRANSACTION, send, &reply); return transact(PING_TRANSACTION, data, &reply); } status_t BpBinder::dump(int fd, const Vector<String16>& args) Loading Loading @@ -236,8 +269,13 @@ status_t BpBinder::transact( } } status_t status = IPCThreadState::self()->transact( mHandle, code, data, reply, flags); status_t status; if (CC_UNLIKELY(isRpcBinder())) { status = rpcConnection()->transact(rpcAddress(), code, data, reply, flags); } else { status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags); } if (status == DEAD_OBJECT) mAlive = 0; return status; Loading @@ -250,6 +288,8 @@ status_t BpBinder::transact( status_t BpBinder::linkToDeath( const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags) { if (isRpcBinder()) return UNKNOWN_TRANSACTION; Obituary ob; ob.recipient = recipient; ob.cookie = cookie; Loading @@ -267,10 +307,10 @@ status_t BpBinder::linkToDeath( if (!mObituaries) { return NO_MEMORY; } ALOGV("Requesting death notification: %p handle %d\n", this, mHandle); ALOGV("Requesting death notification: %p handle %d\n", this, binderHandle()); getWeakRefs()->incWeak(this); IPCThreadState* self = IPCThreadState::self(); self->requestDeathNotification(mHandle, this); self->requestDeathNotification(binderHandle(), this); self->flushCommands(); } ssize_t res = mObituaries->add(ob); Loading @@ -286,6 +326,8 @@ status_t BpBinder::unlinkToDeath( const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags, wp<DeathRecipient>* outRecipient) { if (isRpcBinder()) return UNKNOWN_TRANSACTION; AutoMutex _l(mLock); if (mObitsSent) { Loading @@ -303,9 +345,9 @@ status_t BpBinder::unlinkToDeath( } mObituaries->removeAt(i); if (mObituaries->size() == 0) { ALOGV("Clearing death notification: %p handle %d\n", this, mHandle); ALOGV("Clearing death notification: %p handle %d\n", this, binderHandle()); IPCThreadState* self = IPCThreadState::self(); self->clearDeathNotification(mHandle, this); self->clearDeathNotification(binderHandle(), this); self->flushCommands(); delete mObituaries; mObituaries = nullptr; Loading @@ -319,8 +361,10 @@ status_t BpBinder::unlinkToDeath( void BpBinder::sendObituary() { ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", this, mHandle, mObitsSent ? "true" : "false"); LOG_ALWAYS_FATAL_IF(isRpcBinder(), "Cannot send obituary for remote binder."); ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n", this, binderHandle(), mObitsSent ? "true" : "false"); mAlive = 0; if (mObitsSent) return; Loading @@ -328,9 +372,9 @@ void BpBinder::sendObituary() mLock.lock(); Vector<Obituary>* obits = mObituaries; if(obits != nullptr) { ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle); ALOGV("Clearing sent death notification: %p handle %d\n", this, binderHandle()); IPCThreadState* self = IPCThreadState::self(); self->clearDeathNotification(mHandle, this); self->clearDeathNotification(binderHandle(), this); self->flushCommands(); mObituaries = nullptr; } Loading Loading @@ -388,7 +432,9 @@ BpBinder* BpBinder::remoteBinder() BpBinder::~BpBinder() { ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle); ALOGV("Destroying BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) return; IPCThreadState* ipc = IPCThreadState::self(); Loading @@ -396,7 +442,8 @@ BpBinder::~BpBinder() AutoMutex _l(sTrackingLock); uint32_t trackedValue = sTrackingMap[mTrackedUid]; if (CC_UNLIKELY((trackedValue & COUNTING_VALUE_MASK) == 0)) { ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this, mHandle); ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this, binderHandle()); } else { if (CC_UNLIKELY( (trackedValue & LIMIT_REACHED_MASK) && Loading @@ -413,26 +460,31 @@ BpBinder::~BpBinder() } if (ipc) { ipc->expungeHandle(mHandle, this); ipc->decWeakHandle(mHandle); ipc->expungeHandle(binderHandle(), this); ipc->decWeakHandle(binderHandle()); } } void BpBinder::onFirstRef() { ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle); ALOGV("onFirstRef BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) return; IPCThreadState* ipc = IPCThreadState::self(); if (ipc) ipc->incStrongHandle(mHandle, this); if (ipc) ipc->incStrongHandle(binderHandle(), this); } void BpBinder::onLastStrongRef(const void* /*id*/) { ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle); ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, binderHandle()); if (CC_UNLIKELY(isRpcBinder())) { (void)rpcConnection()->sendDecStrong(rpcAddress()); return; } IF_ALOGV() { printRefs(); } IPCThreadState* ipc = IPCThreadState::self(); if (ipc) ipc->decStrongHandle(mHandle); if (ipc) ipc->decStrongHandle(binderHandle()); mLock.lock(); Vector<Obituary>* obits = mObituaries; Loading @@ -442,7 +494,7 @@ void BpBinder::onLastStrongRef(const void* /*id*/) mDescriptorCache.size() ? String8(mDescriptorCache).c_str() : "<uncached descriptor>"); } if (ipc) ipc->clearDeathNotification(mHandle, this); if (ipc) ipc->clearDeathNotification(binderHandle(), this); mObituaries = nullptr; } mLock.unlock(); Loading @@ -457,9 +509,12 @@ void BpBinder::onLastStrongRef(const void* /*id*/) bool BpBinder::onIncStrongAttempted(uint32_t /*flags*/, const void* /*id*/) { ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle); // RPC binder doesn't currently support inc from weak binders if (CC_UNLIKELY(isRpcBinder())) return false; ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, binderHandle()); IPCThreadState* ipc = IPCThreadState::self(); return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false; return ipc ? ipc->attemptIncStrongHandle(binderHandle()) == NO_ERROR : false; } uint32_t BpBinder::getBinderProxyCount(uint32_t uid) Loading
libs/binder/Debug.cpp +16 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,22 @@ namespace android { std::string hexString(const void* bytes, size_t len) { if (bytes == nullptr) return "<null>"; const uint8_t* bytes8 = static_cast<const uint8_t*>(bytes); const char chars[] = "0123456789abcdef"; std::string result; result.resize(len * 2); for (size_t i = 0; i < len; i++) { result[2 * i] = chars[bytes8[i] >> 4]; result[2 * i + 1] = chars[bytes8[i] & 0xf]; } return result; } // --------------------------------------------------------------------- static const char indentStr[] = Loading
libs/binder/Debug.h +2 −4 Original line number Diff line number Diff line Loading @@ -17,13 +17,13 @@ #pragma once #include <stdint.h> #include <sys/cdefs.h> #include <sys/types.h> #include <string> namespace android { // --------------------------------------------------------------------------- __BEGIN_DECLS std::string hexString(const void* data, size_t size); const char* stringForIndent(int32_t indentLevel); Loading @@ -40,7 +40,5 @@ void printHexData(int32_t indent, const void *buf, size_t length, ssize_t getBinderKernelReferences(size_t count, uintptr_t* buf); __END_DECLS // --------------------------------------------------------------------------- } // namespace android
libs/binder/IPCThreadState.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -689,6 +689,8 @@ status_t IPCThreadState::transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { LOG_ALWAYS_FATAL_IF(data.isForRpc(), "Parcel constructed for RPC, but being used with binder."); status_t err; flags |= TF_ACCEPT_FDS; Loading