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

下面将通过一个系列来对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,让客户端来获取。

欢迎关注微信公众号:DroidMind
精品内容独家发布平台


呈现与博客不一样的技术干货

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值