Loading libs/binder/IPCThreadState.cpp +29 −6 Original line number Diff line number Diff line Loading @@ -486,6 +486,19 @@ void IPCThreadState::flushCommands() } } bool IPCThreadState::flushIfNeeded() { if (mIsLooper || mServingStackPointer != nullptr) { return false; } // In case this thread is not a looper and is not currently serving a binder transaction, // there's no guarantee that this thread will call back into the kernel driver any time // soon. Therefore, flush pending commands such as BC_FREE_BUFFER, to prevent them from getting // stuck in this thread's out buffer. flushCommands(); return true; } void IPCThreadState::blockUntilThreadAvailable() { pthread_mutex_lock(&mProcess->mThreadCountLock); Loading Loading @@ -604,6 +617,7 @@ void IPCThreadState::joinThreadPool(bool isMain) mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); mIsLooper = true; status_t result; do { processPendingDerefs(); Loading @@ -626,6 +640,7 @@ void IPCThreadState::joinThreadPool(bool isMain) (void*)pthread_self(), getpid(), result); mOut.writeInt32(BC_EXIT_LOOPER); mIsLooper = false; talkWithDriver(false); } Loading Loading @@ -739,16 +754,19 @@ void IPCThreadState::incStrongHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle); mOut.writeInt32(BC_ACQUIRE); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->incStrong(mProcess.get()); mPostWriteStrongDerefs.push(proxy); } } void IPCThreadState::decStrongHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle); mOut.writeInt32(BC_RELEASE); mOut.writeInt32(handle); flushIfNeeded(); } void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) Loading @@ -756,16 +774,19 @@ void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle); mOut.writeInt32(BC_INCREFS); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->getWeakRefs()->incWeak(mProcess.get()); mPostWriteWeakDerefs.push(proxy->getWeakRefs()); } } void IPCThreadState::decWeakHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle); mOut.writeInt32(BC_DECREFS); mOut.writeInt32(handle); flushIfNeeded(); } status_t IPCThreadState::attemptIncStrongHandle(int32_t handle) Loading Loading @@ -821,6 +842,7 @@ IPCThreadState::IPCThreadState() mServingStackPointer(nullptr), mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mIsLooper(false), mStrictModePolicy(0), mLastTransactionBinderFlags(0), mCallRestriction(mProcess->mCallRestriction) Loading Loading @@ -1401,6 +1423,7 @@ void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, IPCThreadState* state = self(); state->mOut.writeInt32(BC_FREE_BUFFER); state->mOut.writePointer((uintptr_t)data); state->flushIfNeeded(); } } // namespace android libs/binder/LazyServiceRegistrar.cpp +23 −18 Original line number Diff line number Diff line Loading @@ -38,8 +38,7 @@ public: bool allowIsolated, int dumpFlags); void forcePersist(bool persist); void setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback); void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback); bool tryUnregister(); Loading Loading @@ -82,13 +81,16 @@ private: // count of services with clients size_t mNumConnectedServices; // previous value passed to the active services callback std::optional<bool> mPreviousHasClients; // map of registered names and services std::map<std::string, Service> mRegisteredServices; bool mForcePersist; // Callback used to report the number of services with clients std::function<bool(int)> mActiveServicesCountCallback; // Callback used to report if there are services with clients std::function<bool(bool)> mActiveServicesCallback; }; class ClientCounterCallback { Loading @@ -103,8 +105,7 @@ public: */ void forcePersist(bool persist); void setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback); void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback); bool tryUnregister(); Loading Loading @@ -158,7 +159,7 @@ std::map<std::string, ClientCounterCallbackImpl::Service>::iterator ClientCounte void ClientCounterCallbackImpl::forcePersist(bool persist) { mForcePersist = persist; if (!mForcePersist && mNumConnectedServices == 0) { if (!mForcePersist) { // Attempt a shutdown in case the number of clients hit 0 while the flag was on maybeTryShutdown(); } Loading Loading @@ -204,8 +205,12 @@ void ClientCounterCallbackImpl::maybeTryShutdown() { } bool handledInCallback = false; if (mActiveServicesCountCallback != nullptr) { handledInCallback = mActiveServicesCountCallback(mNumConnectedServices); if (mActiveServicesCallback != nullptr) { bool hasClients = mNumConnectedServices != 0; if (hasClients != mPreviousHasClients) { handledInCallback = mActiveServicesCallback(hasClients); mPreviousHasClients = hasClients; } } // If there is no callback defined or the callback did not handle this Loading Loading @@ -256,9 +261,9 @@ Status ClientCounterCallbackImpl::onClients(const sp<IBinder>& service, bool cli reRegister(); } void ClientCounterCallbackImpl::setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback) { mActiveServicesCountCallback = activeServicesCountCallback; void ClientCounterCallbackImpl::setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback) { mActiveServicesCallback = activeServicesCallback; } ClientCounterCallback::ClientCounterCallback() { Loading @@ -274,9 +279,9 @@ void ClientCounterCallback::forcePersist(bool persist) { mImpl->forcePersist(persist); } void ClientCounterCallback::setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback) { mImpl->setActiveServicesCountCallback(activeServicesCountCallback); void ClientCounterCallback::setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback) { mImpl->setActiveServicesCallback(activeServicesCallback); } bool ClientCounterCallback::tryUnregister() { Loading Loading @@ -310,9 +315,9 @@ void LazyServiceRegistrar::forcePersist(bool persist) { mClientCC->forcePersist(persist); } void LazyServiceRegistrar::setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback) { mClientCC->setActiveServicesCountCallback(activeServicesCountCallback); void LazyServiceRegistrar::setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback) { mClientCC->setActiveServicesCallback(activeServicesCallback); } bool LazyServiceRegistrar::tryUnregister() { Loading libs/binder/include/binder/IPCThreadState.h +2 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ public: status_t setupPolling(int* fd); status_t handlePolledCommands(); void flushCommands(); bool flushIfNeeded(); void joinThreadPool(bool isMain = true); Loading Loading @@ -204,6 +205,7 @@ private: int32_t mWorkSource; // Whether the work source should be propagated. bool mPropagateWorkSource; bool mIsLooper; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; CallRestriction mCallRestriction; Loading libs/binder/include/binder/LazyServiceRegistrar.h +5 −6 Original line number Diff line number Diff line Loading @@ -56,10 +56,10 @@ class LazyServiceRegistrar { void forcePersist(bool persist); /** * Set a callback that is executed when the total number of services with * clients changes. * The callback takes an argument, which is the number of registered * lazy services for this process which have clients. * Set a callback that is invoked when the active service count (i.e. services with clients) * registered with this process drops to zero (or becomes nonzero). * The callback takes a boolean argument, which is 'true' if there is * at least one service with clients. * * Callback return value: * - false: Default behavior for lazy services (shut down the process if there Loading @@ -73,8 +73,7 @@ class LazyServiceRegistrar { * * This method should be called before 'registerService' to avoid races. */ void setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback); void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback); /** * Try to unregister all services previously registered with 'registerService'. Loading libs/binder/ndk/include_cpp/android/binder_auto_utils.h +12 −1 Original line number Diff line number Diff line Loading @@ -265,7 +265,18 @@ class ScopedAStatus : public impl::ScopedAResource<AStatus*, AStatus_delete, nul AStatus_deleteDescription(cStr); return ret; } return "(not available)"; binder_exception_t exception = getExceptionCode(); std::string desc = std::to_string(exception); if (exception == EX_SERVICE_SPECIFIC) { desc += " (" + std::to_string(getServiceSpecificError()) + ")"; } else if (exception == EX_TRANSACTION_FAILED) { desc += " (" + std::to_string(getStatus()) + ")"; } if (const char* msg = getMessage(); msg != nullptr) { desc += ": "; desc += msg; } return desc; } /** Loading Loading
libs/binder/IPCThreadState.cpp +29 −6 Original line number Diff line number Diff line Loading @@ -486,6 +486,19 @@ void IPCThreadState::flushCommands() } } bool IPCThreadState::flushIfNeeded() { if (mIsLooper || mServingStackPointer != nullptr) { return false; } // In case this thread is not a looper and is not currently serving a binder transaction, // there's no guarantee that this thread will call back into the kernel driver any time // soon. Therefore, flush pending commands such as BC_FREE_BUFFER, to prevent them from getting // stuck in this thread's out buffer. flushCommands(); return true; } void IPCThreadState::blockUntilThreadAvailable() { pthread_mutex_lock(&mProcess->mThreadCountLock); Loading Loading @@ -604,6 +617,7 @@ void IPCThreadState::joinThreadPool(bool isMain) mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); mIsLooper = true; status_t result; do { processPendingDerefs(); Loading @@ -626,6 +640,7 @@ void IPCThreadState::joinThreadPool(bool isMain) (void*)pthread_self(), getpid(), result); mOut.writeInt32(BC_EXIT_LOOPER); mIsLooper = false; talkWithDriver(false); } Loading Loading @@ -739,16 +754,19 @@ void IPCThreadState::incStrongHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incStrongHandle(%d)\n", handle); mOut.writeInt32(BC_ACQUIRE); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->incStrong(mProcess.get()); mPostWriteStrongDerefs.push(proxy); } } void IPCThreadState::decStrongHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decStrongHandle(%d)\n", handle); mOut.writeInt32(BC_RELEASE); mOut.writeInt32(handle); flushIfNeeded(); } void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) Loading @@ -756,16 +774,19 @@ void IPCThreadState::incWeakHandle(int32_t handle, BpBinder *proxy) LOG_REMOTEREFS("IPCThreadState::incWeakHandle(%d)\n", handle); mOut.writeInt32(BC_INCREFS); mOut.writeInt32(handle); if (!flushIfNeeded()) { // Create a temp reference until the driver has handled this command. proxy->getWeakRefs()->incWeak(mProcess.get()); mPostWriteWeakDerefs.push(proxy->getWeakRefs()); } } void IPCThreadState::decWeakHandle(int32_t handle) { LOG_REMOTEREFS("IPCThreadState::decWeakHandle(%d)\n", handle); mOut.writeInt32(BC_DECREFS); mOut.writeInt32(handle); flushIfNeeded(); } status_t IPCThreadState::attemptIncStrongHandle(int32_t handle) Loading Loading @@ -821,6 +842,7 @@ IPCThreadState::IPCThreadState() mServingStackPointer(nullptr), mWorkSource(kUnsetWorkSource), mPropagateWorkSource(false), mIsLooper(false), mStrictModePolicy(0), mLastTransactionBinderFlags(0), mCallRestriction(mProcess->mCallRestriction) Loading Loading @@ -1401,6 +1423,7 @@ void IPCThreadState::freeBuffer(Parcel* parcel, const uint8_t* data, IPCThreadState* state = self(); state->mOut.writeInt32(BC_FREE_BUFFER); state->mOut.writePointer((uintptr_t)data); state->flushIfNeeded(); } } // namespace android
libs/binder/LazyServiceRegistrar.cpp +23 −18 Original line number Diff line number Diff line Loading @@ -38,8 +38,7 @@ public: bool allowIsolated, int dumpFlags); void forcePersist(bool persist); void setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback); void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback); bool tryUnregister(); Loading Loading @@ -82,13 +81,16 @@ private: // count of services with clients size_t mNumConnectedServices; // previous value passed to the active services callback std::optional<bool> mPreviousHasClients; // map of registered names and services std::map<std::string, Service> mRegisteredServices; bool mForcePersist; // Callback used to report the number of services with clients std::function<bool(int)> mActiveServicesCountCallback; // Callback used to report if there are services with clients std::function<bool(bool)> mActiveServicesCallback; }; class ClientCounterCallback { Loading @@ -103,8 +105,7 @@ public: */ void forcePersist(bool persist); void setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback); void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback); bool tryUnregister(); Loading Loading @@ -158,7 +159,7 @@ std::map<std::string, ClientCounterCallbackImpl::Service>::iterator ClientCounte void ClientCounterCallbackImpl::forcePersist(bool persist) { mForcePersist = persist; if (!mForcePersist && mNumConnectedServices == 0) { if (!mForcePersist) { // Attempt a shutdown in case the number of clients hit 0 while the flag was on maybeTryShutdown(); } Loading Loading @@ -204,8 +205,12 @@ void ClientCounterCallbackImpl::maybeTryShutdown() { } bool handledInCallback = false; if (mActiveServicesCountCallback != nullptr) { handledInCallback = mActiveServicesCountCallback(mNumConnectedServices); if (mActiveServicesCallback != nullptr) { bool hasClients = mNumConnectedServices != 0; if (hasClients != mPreviousHasClients) { handledInCallback = mActiveServicesCallback(hasClients); mPreviousHasClients = hasClients; } } // If there is no callback defined or the callback did not handle this Loading Loading @@ -256,9 +261,9 @@ Status ClientCounterCallbackImpl::onClients(const sp<IBinder>& service, bool cli reRegister(); } void ClientCounterCallbackImpl::setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback) { mActiveServicesCountCallback = activeServicesCountCallback; void ClientCounterCallbackImpl::setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback) { mActiveServicesCallback = activeServicesCallback; } ClientCounterCallback::ClientCounterCallback() { Loading @@ -274,9 +279,9 @@ void ClientCounterCallback::forcePersist(bool persist) { mImpl->forcePersist(persist); } void ClientCounterCallback::setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback) { mImpl->setActiveServicesCountCallback(activeServicesCountCallback); void ClientCounterCallback::setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback) { mImpl->setActiveServicesCallback(activeServicesCallback); } bool ClientCounterCallback::tryUnregister() { Loading Loading @@ -310,9 +315,9 @@ void LazyServiceRegistrar::forcePersist(bool persist) { mClientCC->forcePersist(persist); } void LazyServiceRegistrar::setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback) { mClientCC->setActiveServicesCountCallback(activeServicesCountCallback); void LazyServiceRegistrar::setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback) { mClientCC->setActiveServicesCallback(activeServicesCallback); } bool LazyServiceRegistrar::tryUnregister() { Loading
libs/binder/include/binder/IPCThreadState.h +2 −0 Original line number Diff line number Diff line Loading @@ -110,6 +110,7 @@ public: status_t setupPolling(int* fd); status_t handlePolledCommands(); void flushCommands(); bool flushIfNeeded(); void joinThreadPool(bool isMain = true); Loading Loading @@ -204,6 +205,7 @@ private: int32_t mWorkSource; // Whether the work source should be propagated. bool mPropagateWorkSource; bool mIsLooper; int32_t mStrictModePolicy; int32_t mLastTransactionBinderFlags; CallRestriction mCallRestriction; Loading
libs/binder/include/binder/LazyServiceRegistrar.h +5 −6 Original line number Diff line number Diff line Loading @@ -56,10 +56,10 @@ class LazyServiceRegistrar { void forcePersist(bool persist); /** * Set a callback that is executed when the total number of services with * clients changes. * The callback takes an argument, which is the number of registered * lazy services for this process which have clients. * Set a callback that is invoked when the active service count (i.e. services with clients) * registered with this process drops to zero (or becomes nonzero). * The callback takes a boolean argument, which is 'true' if there is * at least one service with clients. * * Callback return value: * - false: Default behavior for lazy services (shut down the process if there Loading @@ -73,8 +73,7 @@ class LazyServiceRegistrar { * * This method should be called before 'registerService' to avoid races. */ void setActiveServicesCountCallback(const std::function<bool(int)>& activeServicesCountCallback); void setActiveServicesCallback(const std::function<bool(bool)>& activeServicesCallback); /** * Try to unregister all services previously registered with 'registerService'. Loading
libs/binder/ndk/include_cpp/android/binder_auto_utils.h +12 −1 Original line number Diff line number Diff line Loading @@ -265,7 +265,18 @@ class ScopedAStatus : public impl::ScopedAResource<AStatus*, AStatus_delete, nul AStatus_deleteDescription(cStr); return ret; } return "(not available)"; binder_exception_t exception = getExceptionCode(); std::string desc = std::to_string(exception); if (exception == EX_SERVICE_SPECIFIC) { desc += " (" + std::to_string(getServiceSpecificError()) + ")"; } else if (exception == EX_TRANSACTION_FAILED) { desc += " (" + std::to_string(getStatus()) + ")"; } if (const char* msg = getMessage(); msg != nullptr) { desc += ": "; desc += msg; } return desc; } /** Loading