上篇文章写道Binder调用到了驱动层,这篇写服务端怎么执行后续流程
一、涉及源码
\frameworks\base\core\java\android\content\ContextWrapper.java
\frameworks\base\core\java\android\app\ContextImpl.java
\frameworks\base\core\java\android\app\ActivityManager.java
\frameworks\base\core\java\android\os\ServiceManagerNative.java
\frameworks\base\core\java\android\app\IActivityManager.aidl
\frameworks\base\core\java\android\os\Binder.java
\frameworks\base\core\jni\android_util_Binder.cpp
\frameworks\native\libs\binder\BpBinder.cpp
\frameworks\base\core\jni\AndroidRuntime.cpp
\frameworks\base\cmds\app_process\app_main.cpp
\frameworks\native\libs\binder\Binder.cpp
\frameworks\native\libs\binder\IPCThreadState.cpp
\frameworks\native\libs\binder\ProcessState.cpp
\drivers\staging\android\binder.c
二、回到用户空间
用户进程在fork之后,会调用ZygoteInit.zygoteInit方法做一些初始化操作,SystemServer进程启动之后也是这样调用
2.1、app_main的onZygoteInit方法
//ZygoteInit
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
...
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit(); //1
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}
private static final native void nativeZygoteInit();
//AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
//app_main.cpp
virtual void onZygoteInit()
{
sp<ProcessState> proc = ProcessState::self(); //1 获取ProcessState对象
proc->startThreadPool(); //2 启动新binder线程
}
可以看到启动进程时候,会调到app_main的onZygoteInit方法,ProcessState也是一个单例,一个进程对应一个实例。
2.2、ProcessState
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
if (gProcess != NULL) {
return gProcess;
}
gProcess = new ProcessState("/dev/binder");
return gProcess;
}
ProcessState::ProcessState(const char *driver)
: mDriverName(String8(driver))
, mDriverFD(open_driver(driver))
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
, mExecutingThreadsCount(0)
, mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
, mStarvationStartTimeMs(0)
, mManagesContexts(false)
, mBinderContextCheckFunc(NULL)
, mBinderContextUserData(NULL)
, mThreadPoolStarted(false)
, mThreadPoolSeq(1)
{
if (mDriverFD >= 0) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
//...
}
//...
}
这里可以看到调用open_driver()打开/dev/binder,再通过mmap映射一块物理空间到内核空间和进程空间,将Binder驱动的fd赋值ProcessState的mDriverFD,用于交互操作
2.3、proc->startThreadPool()
void ProcessState::startThreadPool()
{
AutoMutex _l(mLock);
if (!mThreadPoolStarted) {
mThreadPoolStarted = true;
spawnPooledThread(true);
}
}
void ProcessState::spawnPooledThread(bool isMain)
{
if (mThreadPoolStarted) {
String8 name = makeBinderThreadName();
//创建了一个PoolThread
sp<Thread> t = new PoolThread(isMain);
t->run(name.string());
}
}
class PoolThread : public Thread
{
public:
explicit PoolThread(bool isMain)
: mIsMain(isMain)
{
}
protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}
const bool mIsMain;
};
可以看到startThreadPool(),里面创建了一个PoolThread线程池,然后创建了一个IPCThreadState,调用它的joinThreadPool方法
2.4、IPCThreadState::self()->joinThreadPool
void IPCThreadState::joinThreadPool(bool isMain)
{
mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
status_t result;
do {
processPendingDerefs();
// now get the next command to be processed, waiting if necessary
result = getAndExecuteCommand();
.....
} while (result != -ECONNREFUSED && result != -EBADF);
//...
talkWithDriver(false);
}
status_t IPCThreadState::getAndExecuteCommand()
{
status_t result;
int32_t cmd;
result = talkWithDriver(); //与binder驱动进程交互
if (result >= NO_ERROR) {
result = executeCommand(cmd);
}
return result;
}
status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
//...
case BR_TRANSACTION:
{
binder_transaction_data tr;
result = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
const pid_t origPid = mCallingPid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
Parcel reply;
status_t error;
if (tr.target.ptr) {
// We only have a weak reference on the target object, so we must first try to
// safely acquire a strong reference before doing anything else with it.
if (reinterpret_cast<RefBase::weakref_type*>(
tr.target.ptr)->attemptIncStrong(this)) {
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
&reply, tr.flags); //1
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
} else {
error = UNKNOWN_TRANSACTION;
}
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
if ((tr.flags & TF_ONE_WAY) == 0) {
if (error < NO_ERROR) reply.setError(error);
sendReply(reply, 0);
} else {
}
}
break;
//...
}
if (result != NO_ERROR) {
mLastError = result;
}
return result;
}
在joinThreadPool方法中调用getAndExecuteCommand方法,在这个方法里面调用talkWithDriver与驱动交互,在binder_thread_read方法中,todo队列没有数据,等待被唤醒,由于binder_transaction方法里面调用wake_up_interruptible唤醒目标进程,binder_thread_read会走后面代码,走到getAndExecuteCommand方法。
关键代码在注释1处,会调用BBinder.transact方法
//\frameworks\native\libs\binder\Binder.cpp
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags); //1
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
//\frameworks\base\core\jni\android_util_Binder.cpp
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
//调用Binder.execTransact
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
...
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
在注释1处调用到onTransact()方法,里面会调用到java层的Binder.execTransact,这些对象的注册在AndroidRuntime::startReg过程,其中有一个过程便是register_android_os_Binder(),该过程会把gBinderOffsets.mExecTransact便是Binder.java中的execTransact()方法
//\frameworks\base\core\java\android\os\Binder.java
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
//...
try {
//...
//AMS.onTransact
res = onTransact(code, data, reply, flags);
} catch (RemoteException|RuntimeException e) {
//...
} catch (OutOfMemoryError e) {
//...
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
//...
return res;
}
这里调用到了java层的execTransact,里面会调用onTransact,服务端重写了这个方法,回调到IActivityManager.Stub里面,最后会调用到AMS。到这里就完成了客户端写到服务端的过程。
三、Reply流程
前面IPC.waitForResponse()过程,对于非oneway的方式,还仍在一直等待system_server这边的响应呢,只有收到服务端的REPLY命令之后才会结束流程。
前面executeCommand执行完transact方法,会调用sendReply方法向客户端返回reply
status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
{
status_t err;
status_t statusBuffer;
err = writeTransactionData(BC_REPLY, flags, -1, 0, reply, &statusBuffer);
if (err < NO_ERROR) return err;
return waitForResponse(NULL, NULL);
}
上面写入了BC_REPLY命令,看客户端收到这个命令如何进行后续操作
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
uint32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = (uint32_t)mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}
switch (cmd) {
//...
case BR_REPLY:
{
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
if (err != NO_ERROR) goto finish;
if (reply) {
if ((tr.flags & TF_STATUS_CODE) == 0) {
reply->ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t),
freeBuffer, this); //1
} else {
err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
freeBuffer(NULL,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), this);
}
} else {
//释放buffer
freeBuffer(NULL,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), this);
continue;
}
}
goto finish;
default:
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
...
return err;
}
客户端收到信息,就释放buffer,然后就结束了流程。
还是借助gityuan大佬的图来结束文章。