Reland "IPCThreadState: Add a public method to probe if a binder call is being served.""
This reverts commit d2e4de2a0c99031fd7227f162517de313fd29262.
Reason for revert: Dependencies which broke tests due to exclusion from
LOCAL_JNI_SHARED_LIBS have been added.
Change-Id: If400a48214274d121e79135ac5d573fcb1a4a4c2
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 61b8818..da10687 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -119,6 +119,7 @@
"liblog",
"libcutils",
"libutils",
+ "libbinderthreadstate",
],
header_libs: [
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index b2217b5..f052bcb 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "IPCThreadState"
#include <binder/IPCThreadState.h>
+#include <binderthreadstate/IPCThreadStateBase.h>
#include <binder/Binder.h>
#include <binder/BpBinder.h>
@@ -742,6 +743,7 @@
clearCaller();
mIn.setDataCapacity(256);
mOut.setDataCapacity(256);
+ mIPCThreadStateBase = IPCThreadStateBase::self();
}
IPCThreadState::~IPCThreadState()
@@ -1082,6 +1084,9 @@
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
+ //Record the fact that we're in a binder call.
+ mIPCThreadStateBase->pushCurrentState(
+ IPCThreadStateBase::CallState::BINDER);
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
@@ -1129,6 +1134,7 @@
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
+ mIPCThreadStateBase->popCurrentState();
//ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
// mCallingPid, origPid, origUid);
@@ -1192,6 +1198,10 @@
return result;
}
+bool IPCThreadState::isServingCall() const {
+ return mIPCThreadStateBase->getCurrentBinderCallState() == IPCThreadStateBase::CallState::BINDER;
+}
+
void IPCThreadState::threadDestructor(void *st)
{
IPCThreadState* const self = static_cast<IPCThreadState*>(st);
diff --git a/libs/binder/include/binder/IPCThreadState.h b/libs/binder/include/binder/IPCThreadState.h
index dce3f38..40b51ad 100644
--- a/libs/binder/include/binder/IPCThreadState.h
+++ b/libs/binder/include/binder/IPCThreadState.h
@@ -29,6 +29,8 @@
// ---------------------------------------------------------------------------
namespace android {
+class IPCThreadStateBase;
+
class IPCThreadState
{
public:
@@ -89,6 +91,33 @@
// the maximum number of binder threads threads allowed for this process.
void blockUntilThreadAvailable();
+
+ // Is this thread currently serving a binder call. This method
+ // returns true if while traversing backwards from the function call
+ // stack for this thread, we encounter a function serving a binder
+ // call before encountering a hwbinder call / hitting the end of the
+ // call stack.
+ // Eg: If thread T1 went through the following call pattern
+ // 1) T1 receives and executes hwbinder call H1.
+ // 2) While handling H1, T1 makes binder call B1.
+ // 3) The handler of B1, calls into T1 with a callback B2.
+ // If isServingCall() is called during H1 before 3), this method
+ // will return false, else true.
+ //
+ // ----
+ // | B2 | ---> While callback B2 is being handled, during 3).
+ // ----
+ // | H1 | ---> While H1 is being handled.
+ // ----
+ // Fig: Thread Call stack while handling B2
+ //
+ // This is since after 3), while traversing the thread call stack,
+ // we hit a binder call before a hwbinder call / end of stack. This
+ // method may be typically used to determine whether to use
+ // hardware::IPCThreadState methods or IPCThreadState methods to
+ // infer information about thread state.
+ bool isServingCall() const;
+
private:
IPCThreadState();
~IPCThreadState();
@@ -128,6 +157,7 @@
uid_t mCallingUid;
int32_t mStrictModePolicy;
int32_t mLastTransactionBinderFlags;
+ IPCThreadStateBase *mIPCThreadStateBase;
};
}; // namespace android