binder机制原理分析(二):普通Service注册到ServiceManager

binder机制原理分析一共分5个部分,其实省了一点,但是分析到后面都差不多了,以后再补充吧。

1、ServiceManager 进程启动

2、普通Service注册到ServiceManager

3、从ServiceManager中获取服务

4、java层service的注册过程

5、Java层service的获取过程

一般service注册到ServiceManager都经过五个步骤:

  1. sp proc = (ProcessState::self());获取ProcessState实例;
  2. sp sm = defaultServiceManager();获取IServiceManager实例;
  3. XXXService::Instantiate();调试用addService方法,将XXX服务注册到sm中去;
  4. ProcessState::self()—>startThreadPool();开启binder线程池;
  5. IPCThreadState::self()—>joinThreadPool();添加到binder线程池;
    获取ProcessState实例

涉及到的关键类:

IServiceManager:重写了addServie、gerService、checkService、serviceList四个方法
ProcessState:1、构造中open_driver();mmap();2、getContextObj方法获取ServiceManager类;3、startThreadPool开启线程池new poolThread
IPCThreadState:1、transact方法输入入口;2、writeTransactionDate()方法数据,将数据封装成binder_transact_date并写入到mOut中;3、执行waitForResponse方法等待响应结果。4、joinThreadPool加入到线程池中并开启do while与binder交互;5、执行talkWithDriver方法,将数据封装成binder_write_read通过ioctl的BINDER_WRITE_READ指令发送给binder驱动;6、通过executeCommand方法执行binder响应指令BP_XXX。7、IPCThreadState中还包含mIn、一个mOut,其中mIn用来接收来自Binder驱动的数据,mOut用来存储发往Binder驱动的数据,它们默认大小都为256字节

步骤一、ProcessState::self()

获取processState单例

是个单例通过autoLock自锁,返回一个new ProcessState实例对象;ProcessState中定义了binder默认内存大小是1M-8K;默认binder的最大线程数是15。
注意: 这里的binder默认的内存大小和binder的默认最大线程数大小

#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
#define DEFAULT_MAX_BINDER_THREADS 15
sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState;
    return gProcess;
}

进行processState构造

1、调用open_driver()方法,其实就是调用open()方法获取proc结构体,同时获取binder版本号并设置最大线程数;2、通过mmap()申请虚拟内存空间并进行双映射。

ProcessState::ProcessState()
1open_driver()中调用open()方法获取proc结构体,同时获取binder版本号和binder最大线程数
    mDriverFD(open_driver())
.................{
    if (mDriverFD >= 0) {
.................
2、通过mmap机制申请虚拟空间内存并进行双映射
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
    }
}

步骤二、获取SM对象defaultServiceManager()

  1. 通过defaultServiceManager()方法——>调用ProcessState中的getContextObject()方法——>调用getStrongProxyForHandler(0)——>最终获得BpBinder实例。
  2. 通过interface_cast(new BpBinder(0))模板宏定义替换INTERFACE标签,实现asInterface方法后得到BpServiceManager(new BpBinder(0))。这里的BpServiceManager属于IServiceManager,BpServiceManager继承了BpRefBase,BpRefBase中的成员mRemote指针指向BpBinde(0)。
  3. IServiceManager实现了IInterface的addService、getService、checkService和serviceList四个方法。所以BpServiceManager也实现了。

先获取BpBinder(0)

sp<IServiceManager> defaultServiceManager(){
        if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
        {
            AutoMutex _l(gDefaultServiceManagerLock);
            // 循环获取servicemanager,采用循环应该是考虑到servicemanager进程可能加载慢的问题
            while (gDefaultServiceManager == NULL) {
                gDefaultServiceManager = interface_cast<IServiceManager>(
                    ProcessState::self()->getContextObject(NULL));
                if (gDefaultServiceManager == NULL)
                    sleep(1);
            }
        }
        return gDefaultServiceManager;
    }
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/){
返回handle = 0即servicemanager代理的强引用
    return getStrongProxyForHandle(0);
}
获取handle对应的BpBinder对象。
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) {
                // 查询servicemanager是否可用
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            // 创建handle对应的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;
}

到这里defaultServiceManager先得到的就是interface_cast(new BpBinder(0)),然后继续下一步。

替换模板interface_cast得到BpServiceManager

inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
通过宏定义将所有的INTERFACE标签替换成ServiceManager,最终返回new BpServiceManager(obj)对象
#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;  
    }

再将BpBinder(0)赋给BpRefBase的成员remote对象,通过remote()获取mRemote,就是BpBinder(0)
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase{
public:
       BpInterface(const sp<IBinder>& remote);
protected:
    virtual IBinder* onAsBinder();
};

最终:sp defaultServiceManager()最终得到的是new BpServiceManager(new BpBinder(0))
这里BpServiceManager属于IServiceManager,BpBinder属于IBinder。

步骤三、通过Instantiate()注册服务

  1. Instantiate()这个方法实际上调用的就是defaultServiceManager().addService方法。
    class XXXService :public BinderService可以看到XXXService继承BinderService
  2. Instantiate()这个方法在BinderService中实现,可以看到又是个模板类,主要为了将SERVICE标签替换成XXXService去获取serviceName调用publish()方法,因此就是调用BpServiceManager类中的addService方法;
static void instantiate() { publish(); }
static status_t publish(bool allowIsolated = false) {
    sp<IServiceManager> sm(defaultServiceManager());
    return sm->addService(
            String16(SERVICE::getServiceName()),
            new SERVICE(), allowIsolated);
}
virtual status_t addService(const String16& name, const sp<IBinder>& service,
        bool allowIsolated){
写入通过Parcel对象的data数据包
    Parcel data, reply;
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    data.writeStrongBinder(service);
    data.writeInt32(allowIsolated ? 1 : 0);
remote()就是BpBinder(0)的引用。这里就是调用的BpBinder的transact方法。
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    return err == NO_ERROR ? reply.readExceptionCode() : err;
}
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) {
BpBinder又调用了IPCThreadState的transact方法发送数据包
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }
    return DEAD_OBJECT;
}

线程类IPCThreadState跟每一个binder线程一一对应,每一个binder线程都对应一个IPCThreadState实例(利用TLS:ThreadLocationStorage线程本地存贮实现),IPCThreadState负责最终与binder驱动交互。

核心共两部分:
1、通过writeTransactionData构造结构体;
2、通过talkwithbinder与binder驱动进行交互
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) {
1、如果数据没有错,调用writeTransactionData方法:构建binder_transaction_data结构体,封装数据,然后写如mOut中去。
        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);
    }
2、通过waitForResponse等待binder响应;这里TF_ONE_WAY:0是同步,否正是异步。在waitForResponse方法中通过talkWithdDriver方法不断的跟binder进行io交互,将mOut数据写入binder中,然后将binder中数据读取保存到mIn中。
    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;
}
writeTransactionData目的是为了封装binder_transaction_data结构体,然后写入到mOut中去
status_t IPCThreadState::writeTransactionData(
    int32_t cmd,            //此时cmd为BC_TRANSACTION,
    uint32_t binderFlags,   //binderFlags为0|TF_ACCEPT_FDS
    int32_t handle,         //handle为0
    uint32_t code,          //code,注册服务用ADD_SERVICE_TRANSACTION
    const Parcel& data,     //data包含了要传递给Binder驱动程序的进程间通信数据Parcel包
    status_t* statusBuffer ,//statusBuffer为NULL
    ){
    binder_transaction_data tr;
    tr.target.handle = handle;//0
    tr.code = code;//ADD_SERVICE_TRANSACTION
    tr.flags = binderFlags;//0|TF_ACCEPT_FDS
    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) {
        ........
    } else {
        ........
    }
    mOut.writeInt32(cmd);//BC_TRANSACTION
    mOut.write(&tr, sizeof(tr));
    return NO_ERROR;
}

waitForResponse中while循环开启talkWithBinder不断的跟binder驱动进行交互,最终得到响应的reply

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult){
        uint32_t cmd;
        int32_t err;
        while (1) {
            // 将写缓冲区mOut中的数据写入驱动
            if ((err=talkWithDriver()) < NO_ERROR) break;
            err = mIn.errorCheck();
            if (err < NO_ERROR) break;
            if (mIn.dataAvail() == 0) continue;
            cmd = (uint32_t)mIn.readInt32();
            switch (cmd) {
            case BR_TRANSACTION_COMPLETE:
                if (!reply && !acquireResult) goto finish;
                break;
            ....
            // 服务端响应请求
            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;
                    ....
                }
                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通过封装binder_write_read结构体,并调用ioctl命令将数据发送给binder,读也ioctl,写也ioctl;如果mOut不为空,写入数据,如果mIn不为空,读取数据。

status_t IPCThreadState::talkWithDriver(bool doReceive){
        if (mProcess->mDriverFD <= 0) {
            return -EBADF;
        }
封装binder的读写数据结构体变量binder_write_read;
        binder_write_read bwr;
        // 读缓冲区是否为空
        const bool needRead = mIn.dataPosition() >= mIn.dataSize();
        // 当前是否可写入数据到binder驱动
        const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
        bwr.write_size = outAvail;
        bwr.write_buffer = (uintptr_t)mOut.data();
        // 可读数据
        if (doReceive && needRead) {
            bwr.read_size = mIn.dataCapacity();
            // 将bwr的读缓冲指向mIn的数据区
            bwr.read_buffer = (uintptr_t)mIn.data();
        } else {
            bwr.read_size = 0;
            bwr.read_buffer = 0;
        }
        // Return immediately if there is nothing to do.
        if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;
        bwr.write_consumed = 0; //已写数据
        bwr.read_consumed = 0; // 已读数据
        status_t err;
        do {
    #if defined(__ANDROID__)
            //与驱动交互,将mOut的数据写入到驱动,读取的数据保存到mIn
            if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
                err = NO_ERROR;
            else
                err = -errno;
    #else
            err = INVALID_OPERATION;
    #endif

        } while (err == -EINTR);
        if (err >= NO_ERROR) {
            // 将已写入驱动的数据从mOut中移除
            if (bwr.write_consumed > 0) {
                if (bwr.write_consumed < mOut.dataSize())
                    mOut.remove(0, bwr.write_consumed);
                else
                    mOut.setDataSize(0);
            }
            // 将读取到的数据信息保存到mIn
            if (bwr.read_consumed > 0) {
                mIn.setDataSize(bwr.read_consumed);
                mIn.setDataPosition(0);
            }
            return NO_ERROR;
        }
        return err;
    }

开启binder线程池:startThreadPool()

调用startThreadPool(),最终new PoolThread方法创建并开启线程池

void ProcessState::startThreadPool(){
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

添加到binder线程池:joinThreadPool()

通过IPCThreadState中的joinThreadPool()方法执行线程looper。

void IPCThreadState::joinThreadPool(bool isMain){
        LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
 1、设置线程状态
        mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
        // 设置当前线程的调度策略
        set_sched_policy(mMyThreadId, SP_FOREGROUND);
        status_t result;
        do {
            processPendingDerefs();
2、不断执行从binder驱动获取到的命令
            result = getAndExecuteCommand();
            ....
            // 非主线程超时,直接退出
            if(result == TIMED_OUT && !isMain) {
                break;
            }
        } while (result != -ECONNREFUSED && result != -EBADF);
        // 退出线程池
        mOut.writeInt32(BC_EXIT_LOOPER);
        //停止与binder的通信
        talkWithDriver(false);
}
status_t IPCThreadState::getAndExecuteCommand(){
    status_t result;
    int32_t cmd;
    // 与binder进行数据通信
    result = talkWithDriver();
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();
        // 进程中正在执行任务的线程数加一
        pthread_mutex_lock(&mProcess->mThreadCountLock);
        mProcess->mExecutingThreadsCount++;
        if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
                mProcess->mStarvationStartTimeMs == 0) {
            mProcess->mStarvationStartTimeMs = uptimeMillis();
        }
        pthread_mutex_unlock(&mProcess->mThreadCountLock);
        result = executeCommand(cmd);
        ....
        // 保持线程处于Forground状态
        set_sched_policy(mMyThreadId, SP_FOREGROUND);
    }
    return result;
}

总结:

主要分为5步骤:

  1. 通过ProcessState::self()获取processState实例:实例构造的时候通过open_driver()方法打开驱动设备文件,获取binder版本号,设置binder最大线程,通过mmap机制申请内存并实现双映射;

  2. 通过defaltServiceManager()获取servicemager实例:方法中调用了interface_cast (ProcessState::self()—>getContextObj())方法获取serviceManager实例。

  3. 通过instantiate将服务add到serviceManager中去:

  4. 通过startThreadPool开启线程池:

  5. 通过joinThreadPool添加到线程池:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值