Android Binder 服务端分析

Posted we1less

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder 服务端分析相关的知识,希望对你有一定的参考价值。

本篇文章以这篇为锚点Android Binder 应用程序Binder 启动源码分析_we1less的博客-CSDN博客

startThreadPool开始进行分析


joinThreadPool

        路径  frameworks/native/libs/binder/IPCThreadState.cpp

        循环执行getAndExecuteCommand

void                joinThreadPool(bool isMain = true);

void IPCThreadState::joinThreadPool(bool isMain)
{
    ...
    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);
}

getAndExecuteCommand

        路径  frameworks/native/libs/binder/IPCThreadState.cpp

        这个函数的意思就是 循环执行从binder驱动获取接收到的命令再调用executeCommand执行

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;

    result = talkWithDriver();
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();
        ...
        result = executeCommand(cmd);
       ...
    }
    return result;
}

executeCommand

        路径  frameworks/native/libs/binder/IPCThreadState.cpp

        将tr.cookie强转为BBinder再调用BBindertransact方法

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));
            ...
            if (tr.target.ptr) {
                if (reinterpret_cast<RefBase::weakref_type*>(
                    error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
                            &reply, tr.flags);
                } else {
                    error = UNKNOWN_TRANSACTION;
                }
            ...
        }
        break;

    ...
    return result;
}

transact

        路径  frameworks/native/libs/binder/Binder.cpp           

        直接调用onTransact方法  在这里可以直接看做调用到了service重写的onTransact方法

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);
            break;
    }

    if (reply != NULL) {
        reply->setDataPosition(0);
    }

    return err;
}

tr.cookie是什么

这里面的tr.cookie猜想肯定是Service继承BBinder对象的类。
那么首先得回到最开始ServiceManager的addService:

addService

        路径  frameworks/native/libs/binder/IServiceManager.cpp        

        主要是调用了ParcelwriteStrongBinder

virtual status_t addService(const String16& name, const sp<IBinder>& service,
            bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

writeStrongBinder

        路径  frameworks/native/libs/binder/Parcel.cpp 

status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}

flatten_binder 

         路径  frameworks/native/libs/binder/Parcel.cpp 

        这里面就存在了obj.cookie

        可见tr.cookie就是当前service的弱引用指针

        IBinder *local = binder->localBinder(); 

status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;
    ...
    if (binder != NULL) {
        IBinder *local = binder->localBinder();
        if (!local) {
            ...
        } else {
            obj.type = BINDER_TYPE_BINDER;
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);
        }
    }...

    return finish_flatten_binder(binder, obj, out);
}

binder->localBinder();  

        路径  frameworks/native/libs/binder/Binder.cpp

BBinder* BBinder::localBinder()
{
    return this;
}

以上是关于Android Binder 服务端分析的主要内容,如果未能解决你的问题,请参考以下文章

BInder

BInder

Android Binder解析

结合Binder机制看ActivityManager

结合Binder机制看ActivityManager

Android中Parcel的分析以及使用