【Android进阶】Android Binder之ServiceManager注册服务解析1

来源:互联网 发布:spark要用java吗? 编辑:程序博客网 时间:2024/05/21 05:17

下面将通过一个系列来对binder进行解析,虽然之前很多人都已经写过相关的博客,不过还是决定自己来写写,把整个思路理一理,增加自己对binder的认识,也同时希望对大家有所帮助。

首先我们来看的就是ServiceManager注册服务的过程,通过MediaPlayerService的注册过程来讲解整个注册的流程,主要为了看看binder跨进程通信的具体过程。

下面直接上源码。

/frameworks/av/media/mediaserver/main_mediaserver.cpp

int main(int argc, char** argv){    // 1、得到一个ProcessState实例    sp<ProcessState> proc(ProcessState::self());    // 2、获取BpServiceManager对象    sp<IServiceManager> sm = defaultServiceManager();    // 3、注册多媒体服务    MediaPlayerService::instantiate();    // 4、启动Binder线程池    ProcessState::self()->startThreadPool();    // 5、当前线程加入到线程池    IPCThreadState::self()->joinThreadPool();}

一、得到一个ProcessState实例

framework/native/libs/binder/ProcessState.cpp

sp<ProcessState> ProcessState::self(){    Mutex::Autolock _l(gProcessMutex);    if (gProcess != NULL) {        return gProcess;    }    //实例化ProcessState    gProcess = new ProcessState;    return gProcess;}

使用单例模式,保证每一个进程只有一个ProcessState对象

下面看看ProcessState的创建

ProcessState::ProcessState()    : mDriverFD(open_driver()) // 打开Binder驱动    , mVMStart(MAP_FAILED)    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)    , mExecutingThreadsCount(0)    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)    , mManagesContexts(false)    , mBinderContextCheckFunc(NULL)    , mBinderContextUserData(NULL)    , mThreadPoolStarted(false)    , mThreadPoolSeq(1){    if (mDriverFD >= 0) {        //采用内存映射函数mmap,给binder分配一块虚拟地址空间        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);        if (mVMStart == MAP_FAILED) {            close(mDriverFD);            mDriverFD = -1;        }    }}

下面看看驱动的打开过程

static int open_driver(){    // 打开/dev/binder设备,建立与内核的Binder驱动的交互通道    int fd = open("/dev/binder", O_RDWR);    if (fd >= 0) {        fcntl(fd, F_SETFD, FD_CLOEXEC);        int vers = 0;        status_t result = ioctl(fd, BINDER_VERSION, &vers);        if (result == -1) {            close(fd);            fd = -1;        }        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {            close(fd);            fd = -1;        }        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;        // 通过ioctl设置binder驱动        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);        if (result == -1) {            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));        }    } else {        ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));    }    return fd;}

二、获取BpServiceManager对象

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

sp<IServiceManager> defaultServiceManager(){       // 同样使用的是单例模式    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;    {        AutoMutex _l(gDefaultServiceManagerLock);        while (gDefaultServiceManager == NULL) {            // 进入BpServiceManager的创建            // 分为两步:            // 1、BpBInder binder = ProcessState::self()->getContextObject(NULL)            // 2、interface_cast<IServiceManager>(binder)            gDefaultServiceManager = interface_cast<IServiceManager>(                ProcessState::self()->getContextObject(NULL));            if (gDefaultServiceManager == NULL)                sleep(1);        }    }    return gDefaultServiceManager;}

1、ProcessState::self()->getContextObject(NULL)

/frameworks/native/libs/binder/ProcessState.cpp

sp<ProcessState> ProcessState::self(){    // 同样使用的是单例模式    Mutex::Autolock _l(gProcessMutex);    if (gProcess != NULL) {        return gProcess;    }    gProcess = new ProcessState;    return gProcess;}sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller){    return getStrongProxyForHandle(0);}sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle){    sp<IBinder> result;    AutoMutex _l(mLock);    handle_entry* e = lookupHandleLocked(handle);    if (e != NULL) {        IBinder* b = e->binder;        if (b == NULL || !e->refs->attemptIncWeak(this)) {            if (handle == 0) {                Parcel data;                status_t status = IPCThreadState::self()->transact(                        0, IBinder::PING_TRANSACTION, data, NULL, 0);                if (status == DEAD_OBJECT)                   return NULL;            }        // 如果 e->binder为null,就需要创建一个新的BpBinder            b = new BpBinder(handle);             e->binder = b;            if (b) e->refs = b->getWeakRefs();            result = b;        } else {            result.force_set(b);            e->refs->decWeak(this);        }    }    return result;}

可以看到最终返回的其实就是new BpBinder(0);

2、interface_cast<IServiceManager>(new BpBinder(0))

interface_cast方法是一个模板方法,定义在IInterface.h文件中

/frameworks/native/include/binder/IInterface.h

template<typename INTERFACE>inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj){    return INTERFACE::asInterface(obj);}

所以,interface_cast<IServiceManager>(new BpBinder(0))等价于:

inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj){    return IServiceManager::asInterface(obj);}

可以看到实质就是调用了IServiceManager的asInterface方法,即:

IServiceManager::asInterface(new BpBinder(0));

下面在IServiceManager.h看看这个方法的定义

/frameworks/native/libs/binder/IServiceManager.h

class IServiceManager : public IInterface{public:    // 这个模板方法实质就是IServiceManager::asInterface(obj)    DECLARE_META_INTERFACE(ServiceManager);    // ......}

下面我们来看看这个模板方法的定义

/frameworks/native/include/binder/IInterface.h#define DECLARE_META_INTERFACE(INTERFACE)                               \    static const android::String16 descriptor;                          \    static android::sp<I##INTERFACE> asInterface(                       \            const android::sp<android::IBinder>& obj);                  \    virtual const android::String16& getInterfaceDescriptor() const;    \    I##INTERFACE();                                                     \    virtual ~I##INTERFACE();                                            \-------------------------------------------------------------------------下面是该方法的实现模板#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \    const android::String16 I##INTERFACE::descriptor(NAME);             \    const android::String16&                                            \            I##INTERFACE::getInterfaceDescriptor() const {              \        return I##INTERFACE::descriptor;                                \    }                                                                   \    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \            const android::sp<android::IBinder>& obj)                   \    {                                                                   \        android::sp<I##INTERFACE> intr;                                 \        if (obj != NULL) {                                              \            intr = static_cast<I##INTERFACE*>(                          \                obj->queryLocalInterface(                               \                        I##INTERFACE::descriptor).get());               \            if (intr == NULL) {                                         \                intr = new Bp##INTERFACE(obj);                          \            }                                                           \        }                                                               \        return intr;                                                    \    }                                                                   \    I##INTERFACE::I##INTERFACE() { }                                    \    I##INTERFACE::~I##INTERFACE() { }  

下面进行替换可以得到定义为:

static const android::String16 descriptor;                              \static android::sp<IServiceManager> asInterface(                        \        const android::sp<android::IBinder>& obj);              \virtual const android::String16& getInterfaceDescriptor() const;        \IServiceManager();                                                      \virtual ~IServiceManager();                                             \-------------------------------------------------------------------------IServiceManager::asInterface(obj)的实现为:const android::String16 IServiceManager::descriptor(NAME);                   \const android::String16&                                                     \        IServiceManager::getInterfaceDescriptor() const {            \    return IServiceManager::descriptor;                                  \}                                                                            \android::sp<IServiceManager> IServiceManager::asInterface(                   \        const android::sp<android::IBinder>& obj)                    \{                                                                            \    android::sp<IServiceManager> intr;                                   \    if (obj != NULL) {                                                   \        intr = static_cast<IServiceManager*>(                        \            obj->queryLocalInterface(                            \                    IServiceManager::descriptor).get()); \        if (intr == NULL) {                                          \            intr = new BpServiceManager(obj);                    \        }                                                            \    }                                                                    \    return intr;                                                         \}                                                                            \I##INTERFACE::I##INTERFACE() { }                                             \I##INTERFACE::~I##INTERFACE() { }  

从上面可以看到实质是new BpServiceManager(obj)创建了一个BpServiceManager对象。

从上面分析可以知道:

interface_cast<IServiceManager>(binder)实质等价为:
new BpServiceManager(new BpBinder(0))

也就是说 defaultServiceManager()方法最终返回的对象为BpServiceManager对象。

下面看看IServiceManager.cpp中BpServiceManager类的构造方法

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

class BpServiceManager : public BpInterface<IServiceManager>{public:    BpServiceManager(const sp<IBinder>& impl)        : BpInterface<IServiceManager>(impl)    {    }    //......}

可以看到BpServiceManager继承了BpInterface方法,并且同时在构造函数中也调用了BpInterface的构造方法。

BpServiceManager(new BpBinder(0))->BpInterface<IServiceManager>(new BpBinder(0))

下面看看BpInterface的构造函数

/frameworks/native/include/binder/IInterface.h

template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase{public:                                BpInterface(const sp<IBinder>& remote);protected:    virtual IBinder*            onAsBinder();};-------------------------------------------------------------------------template<typename INTERFACE>inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)    : BpRefBase(remote){}

它是一个模板方法,替换之后为:

class BpInterface : public IServiceManager, public BpRefBase{public:                                BpInterface(const sp<IBinder>& remote);protected:    virtual IBinder*            onAsBinder();};----------------------------------------------------------------------------inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote)    : BpRefBase(remote){}

可以看到BpInterface继承了IServiceManager和BpRefBase,并且调用了BpRefBase的构造方法

BpServiceManager(new BpBinder(0))->BpInterface<IServiceManager>(new BpBinder(0))–>BpRefBase(new BpBinder(0))

下面看看BpRefBase的构造方法

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

BpRefBase::BpRefBase(const sp<IBinder>& o)    // 这里实质就是将new BpBinder(0)这个对象复制给mRemote    // 即mRemote持有对BpBinder对象的引用    : mRemote(o.get()), mRefs(NULL), mState(0){    extendObjectLifetime(OBJECT_LIFETIME_WEAK);    if (mRemote) {        mRemote->incStrong(this);           // Removed on first IncStrong().        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.    }}

上面类直接的关系图如下所示:

这里写图片描述

三、注册多媒体服务

当我们拿到这个BpServiceManager对象之后,相当于我们就拿到了ServiceManager的远程代理对象,使用BpServiceManager这个代理对象我们就可以实现对ServiceManager的远程调用,下面我们通过注册多媒体服务来看看它的调用流程。

/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

void MediaPlayerService::instantiate() {    defaultServiceManager()->addService(String16("media.player"), new MediaPlayerService());}

上面已经说过defaultServiceManager()是一个单例方法,返回的是BpServiceManager对象,下面看看该对象的addService方法,它实现的是对远程ServiceManager对象的addService方法的调用。

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

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

remote()方法返回的就是前面设传递进去的BpBinder对象,也就是说最终会将调用的数据进行打包到Parcel对象中,然后调用BpBinder对象的transact方法。

/frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::transact(    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){    // Once a binder has died, it will never come back to life.    if (mAlive) {        status_t status = IPCThreadState::self()->transact(            mHandle, code, data, reply, flags);        if (status == DEAD_OBJECT) mAlive = 0;        return status;    }    return DEAD_OBJECT;}

可以看到最终调用的是IPCThreadState对象的transact方法。

上面的调用关系图如下:

这里写图片描述

下面我们来看看具体的调用过程。

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

IPCThreadState* IPCThreadState::self(){    if (gHaveTLS) {restart:        const pthread_key_t k = gTLS;        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);        if (st) return st;        return new IPCThreadState;    }    if (gShutdown) return NULL;    pthread_mutex_lock(&gTLSMutex);    if (!gHaveTLS) {        if (pthread_key_create(&gTLS, threadDestructor) != 0) {            pthread_mutex_unlock(&gTLSMutex);            return NULL;        }        gHaveTLS = true;    }    pthread_mutex_unlock(&gTLSMutex);    goto restart;}

实质就是获取一个IPCThreadState对象,这是一个线程相关的对象,每个线程只有一个IPCThreadState对象,下面看看IPCThreadState的构造方法

IPCThreadState::IPCThreadState()    : mProcess(ProcessState::self()),      mMyThreadId(androidGetTid()),      mStrictModePolicy(0),      mLastTransactionBinderFlags(0){    pthread_setspecific(gTLS, this);    clearCaller();    mIn.setDataCapacity(256);    mOut.setDataCapacity(256);}

每个IPCThreadState对象都有一个mIn和一个mOut,其中mIn接收来自Binder设备的数据,mOut存放发往Binder设备的数据。

另外,我们可以看到在IPCThreadState中有一个mProcess变量它对应的就是ProcessState的引用,我们知道,在ProcessState中我们在前面打开过binder驱动。

这里写图片描述

下面我们来具体看看IPCThreadState对象的transact方法。

status_t IPCThreadState::transact(int32_t handle,                                  uint32_t code, const Parcel& data,                                  Parcel* reply, uint32_t flags){    status_t err = data.errorCheck();    flags |= TF_ACCEPT_FDS;    IF_LOG_TRANSACTIONS() {        TextOutput::Bundle _b(alog);        alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "            << handle << " / code " << TypeCode(code) << ": "            << indent << data << dedent << endl;    }    if (err == NO_ERROR) {        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);    }    if (err != NO_ERROR) {        if (reply) reply->setError(err);        return (mLastError = err);    }    if ((flags & TF_ONE_WAY) == 0) {        #if 0        if (code == 4) { // relayout            ALOGI(">>>>>> CALLING transaction 4");        } else {            ALOGI(">>>>>> CALLING transaction %d", code);        }        #endif        if (reply) {            err = waitForResponse(reply);        } else {            Parcel fakeReply;            err = waitForResponse(&fakeReply);        }        #if 0        if (code == 4) { // relayout            ALOGI("<<<<<< RETURNING transaction 4");        } else {            ALOGI("<<<<<< RETURNING transaction %d", code);        }        #endif        IF_LOG_TRANSACTIONS() {            TextOutput::Bundle _b(alog);            alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "                << handle << ": ";            if (reply) alog << indent << *reply << dedent << endl;            else alog << "(none requested)" << endl;        }    } else {        err = waitForResponse(NULL, NULL);    }    return err;}

上面过程主要有两步:

1、writeTransactionData方法进行数据写入

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer){    binder_transaction_data tr;    tr.target.handle = handle;    tr.code = code;    tr.flags = binderFlags;    tr.cookie = 0;    tr.sender_pid = 0;    tr.sender_euid = 0;    const status_t err = data.errorCheck();    if (err == NO_ERROR) {        tr.data_size = data.ipcDataSize();        tr.data.ptr.buffer = data.ipcData();        tr.offsets_size = data.ipcObjectsCount()*sizeof(size_t);        tr.data.ptr.offsets = data.ipcObjects();    } else if (statusBuffer) {        tr.flags |= TF_STATUS_CODE;        *statusBuffer = err;        tr.data_size = sizeof(status_t);        tr.data.ptr.buffer = statusBuffer;        tr.offsets_size = 0;        tr.data.ptr.offsets = NULL;    } else {        return (mLastError = err);    }    mOut.writeInt32(cmd);  //cmd = BC_TRANSACTION    mOut.write(&tr, sizeof(tr));    return NO_ERROR;}

上面的过程就是将addService的请求信息写入到mOut中。

2、waitForResponse方法进行请求发送并等待回复

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){    int32_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 = mIn.readInt32();        IF_LOG_COMMANDS() {            alog << "Processing waitForResponse Command: "                << getReturnString(cmd) << endl;        }        switch (cmd) {        case BR_TRANSACTION_COMPLETE:            if (!reply && !acquireResult) goto finish;            break;        case BR_DEAD_REPLY:            err = DEAD_OBJECT;            goto finish;        case BR_FAILED_REPLY:            err = FAILED_TRANSACTION;            goto finish;        case BR_ACQUIRE_RESULT:            {                ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");                const int32_t result = mIn.readInt32();                if (!acquireResult) continue;                *acquireResult = result ? NO_ERROR : INVALID_OPERATION;            }            goto finish;        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 size_t*>(tr.data.ptr.offsets),                            tr.offsets_size/sizeof(size_t),                            freeBuffer, this);                    } else {                        err = *static_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 size_t*>(tr.data.ptr.offsets),                            tr.offsets_size/sizeof(size_t), this);                    }                } else {                    freeBuffer(NULL,                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),                        tr.data_size,                        reinterpret_cast<const size_t*>(tr.data.ptr.offsets),                        tr.offsets_size/sizeof(size_t), this);                    continue;                }            }            goto finish;        default:            err = executeCommand(cmd);            if (err != NO_ERROR) goto finish;            break;        }    }finish:    if (err != NO_ERROR) {        if (acquireResult) *acquireResult = err;        if (reply) reply->setError(err);        mLastError = err;    }    return err;}

上面就是在talkWithDriver中,把mOut发出去,然后从driver中读到回复数据放到mIn中了。这样就完成了一次跨进程的操作。

这里写图片描述

前面我们说到,我们把mOut发出去,那边另一端肯定会取出这个数据,然后根据这个数据的需要完成知道的操作,完成之后把需要返回的数据再写入到driver中,这样我们这端就可以从driver中读到回复数据放到mIn中,完成一次跨进程的操作,我们前面所分析的整个过程是客户端发起的过程,那么另一端就是服务端,我们下面就要分析服务端是怎么从driver获取到mOut数据,执行相应的操作,然后把返回数据再写回到driver,让客户端来获取。

原创粉丝点击