App 进程初始化binder、获取ServiceManager服务

数据结构

ProcessState:用户空间下表示进程状态,单个进程只有一个ProcessState对象。负责打开Binder驱动和建立线程池

IPCThreadState:用户空间下线程通过IPCthreadState跟binder驱动进行命令交互

App进程启动

Init进程启动了zygote进程、system_server进程、ServiceManager进程、lwkd服务等

zygote并没有利用binder通信,而是利用socket接收信息,在执行ZygoteInit.main()后便进入runSelectLoop()循环体内,当有客户端连接时便会执行ZygoteConnection.runOnce()方法,再经过层层调用后fork出新的应用进程;

java层Process.start()来启动一个进程,在ZygoteConnection.runOnce()中:

// ZygoteConnection.runOnce
boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
    pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                parsedArgs.appDataDir);
    ...
        if (pid == 0) { // fork完成之后,子进程的pid会等于0,会进入
            zygoteServer.closeServerSocket(); // 子进程结束掉zygote的socket监听
            IoUtils.closeQuietly(serverPipeFd);
            serverPipeFd = null;
            handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr);
            return true;
        }
}

private void handleChildProc(Arguments parsedArgs,
        FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr)
        throws Zygote.MethodAndArgsCaller {
    ...
    ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
    parsedArgs.remainingArgs, null /* classLoader */);
}

// ZygoteInit.java
public static final void zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit();
    RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

ZygonteInit

//frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

// frameworks/base/cmds/app_process/App_main.cpp 
virtual void onZygoteInit()
{
    sp<ProcessState> proc = ProcessState::self();
    proc->startThreadPool();
}

进程只有一个ProcessState实例,且只有在ProcessState对象建立时才打开Binder设备以及做内存映射

// frameworks/native/libs/binder/ProcessState.cpp
// 单例模式
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);
        if (mVMStart == MAP_FAILED) {
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }
}

open_driver、mmap() 已经分析过了,可以参考 https://blog.csdn.net/qq_15893929/article/details/103965875

startThreadPool创建一个PoolThread表示当前线程并注册为binder线程

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

// 创建一个新的子线程
void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

PoolThread表示binder线程

class PoolThread : public Thread
{
public:
    explicit PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }
    
protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
    
    const bool mIsMain;
};

IPCThreadState跟binder驱动交互

void IPCThreadState::joinThreadPool(bool isMain)
{
    // 如果是主线程,则命令是BC_ENTER_LOOPER,如果是子线程则是BC_REGISTER_LOOPER
    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(); // 阻塞获取下个命令并执行

        if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
            ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                  mProcess->mDriverFD, result);
            abort();
        }

        // Let this thread exit the thread pool if it is no longer
        // needed and it is not the main process thread.
        if(result == TIMED_OUT && !isMain) {
            break;
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

    mOut.writeInt32(BC_EXIT_LOOPER);
    talkWithDriver(false);
}

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;
    result = talkWithDriver();
    if (result >= NO_ERROR) {
        ...
        pthread_mutex_unlock(&mProcess->mThreadCountLock);
        result = executeCommand(cmd);
        pthread_mutex_lock(&mProcess->mThreadCountLock);
        ...
    }
    return result;
}

// 跟binder驱动ioctl,修改bwr,修改 mOut、mIn
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    binder_write_read bwr;
    …

    bwr.write_consumed = 0;
    bwr.read_consumed = 0;
    status_t err;
    do {
       if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
    } while (err == -EINTR);

    if (err >= NO_ERROR) {
        if (bwr.write_consumed > 0) {
            if (bwr.write_consumed < mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
        }
        if (bwr.read_consumed > 0) {
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        return NO_ERROR;
    }

    return err;
}

status_t IPCThreadState::executeCommand(int32_t cmd)
{
    BBinder* obj;
    RefBase::weakref_type* refs;
    status_t result = NO_ERROR;
    switch ((uint32_t)cmd) {
    case BR_ACQUIRE:
        ...
        break;
    case BR_TRANSACTION:
        ...
        break;
    }
    return result;
}

如何添加新的binder线程,因为会有同时多个任务需要执行

IPCThreadState线程中,进行ioctl(BINDER_WRITE_READ), 在binder内核中会进入binder_ioctl_write_read,如果bwr有读缓存的数据,

两个进程之间相互传递的数据格式是binder_transaction_data

进程跟驱动进程相互传递的数据格式是binder_write_read

那可能需要更多的binder线程来处理binder_transaction_data数据

static int binder_thread_read(struct binder_proc *proc, struct binder_thread *thread, binder_uintptr_t binder_buffer, size_t size,binder_size_t *consumed, int non_block)
{ 
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
void __user *ptr = buffer + *consumed;
void __user *end = buffer + size; 
int ret = 0; 
int wait_for_proc_work;

retry:
    binder_inner_proc_lock(proc);
    // 获取当前线程是否空闲等待,即线程事务栈和todo队列都为空
    wait_for_proc_work = binder_available_for_proc_work_ilocked(thread);
    binder_inner_proc_unlock(proc);
   // 线程即将进入睡眠等待,设置线程状态改为BINDER_LOOPER_STATE_WAITING*/
    thread->looper |= BINDER_LOOPER_STATE_WAITING;
    if (non_block) {
        if (!binder_has_work(thread, wait_for_proc_work))
            ret = -EAGAIN;
    } else {
        // wait_for_proc_work  线程没有事务项,需要进入阻塞等待
        ret = binder_wait_for_work(thread, wait_for_proc_work);
    }
    thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
    if (ret)
       return ret;

     while (1) {
            uint32_t cmd;
            struct binder_transaction_data_secctx tr;     
            struct binder_transaction_data *trd = &tr.transaction_data; 
            struct binder_work *w = NULL; 
            switch (w->type) {
                case BINDER_WORK_TRANSACTION: {
                   ...
                } break; 
                case BINDER_WORK_RETURN_ERROR: {
                  ...
                } break;}
done:
*consumed = ptr - buffer; 
binder_inner_proc_lock(proc);

// 当满足条件时候,会创建一个binder_thread,同时告诉给用户进程空间BR_SPAWN_LOOPER去创建多一个线程
if (proc->requested_threads == 0 && list_empty(&thread->proc->waiting_threads) && proc->requested_threads_started < proc->max_threads &&
(thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) /* the user-space code fails to */
/*spawn a new thread if we leave this out */) { 
    proc->requested_threads++;
    binder_inner_proc_unlock(proc);
// 返回给用户空间BR_SPAWN_LOOPER
if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer)) 
    return -EFAULT;
    binder_stat_br(proc, thread, BR_SPAWN_LOOPER);
} else
    binder_inner_proc_unlock(proc);
return 0;
}

继续看用户进程IPCThreadState如何处理BR_SPAWN_LOOPER

status_t IPCThreadState::executeCommand(int32_t cmd)
{
    switch ((uint32_t)cmd) {
        mProcess->spawnPooledThread(false);
        break;
    }
    return result;
}

获取ServiceManager服务

在此之前,先介绍几个数据结构

IBinder

class IBinder : public virtual RefBase
{
public:
    virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);
    // 查询服务返回一个IInterface
    virtual status_t pingBinder() = 0;
    virtual status_t transact(uint32_t code,  const Parcel& data, Parcel* reply, uint32_t flags = 0) = 0;
   // 发送IPC请求
    virtual status_t  linkToDeath(const sp<DeathRecipient>& recipient, void* cookie = NULL, 
    uint32_t flags = 0) = 0;
    // 死亡通知回调
    virtual BBinder* localBinder();
    // 同一个进程下,返回一个BBinder,表示 binder实体
    virtual BpBinder* remoteBinder();
    // 不同进程下,返回一个BpBinder,表示binder引用代理
}

BBinder

在用户进程空间下,表示binder实体

class BBinder : public IBinder 
{
protected:
    virtual status_t  onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
    // 接收IPC请求
private:
    std::atomic<Extras*> mExtras; 
    void* mReserved0;
}

BPBinder

在用户进程空间下,表示binder代理

// 在用户进程下,保存着binder_ref handle句柄
class BpBinder : public IBinder
{
public:
    inline  int32_t  handle() const { return mHandle; }
    virtual status_t    transact(   uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
    // 发送IPC请求
        KeyedVector<const void*, entry_t> mObjects;
    };
private:
    const   int32_t             mHandle;
    mutable Mutex               mLock;
    volatile int32_t    mAlive;
    volatile int32_t    mObitsSent;
    Vector<Obituary>*   mObituaries;
    ObjectManager       mObjects;
    Parcel*             mConstantData;
    mutable String16            mDescriptorCache;
};

所有的进程获取ServiceManger都是通过IServiceMnager.cpp的静态方法获取

App进程获取ServiceManager,就是获取ServiceManager的代理,在binder驱动角度看,就是App对应的binder_proc获取对应的binder_ref,在App用户进程上看,App获取对应ServiceManager的BpBinder。

// framework/native/libs/binder/IServiceMnager.cpp
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    return gDefaultServiceManager;
}

从 ProcessState::self()->getContextObject(NULL) 获取ServiceManager,若为空,则说明ServiceManager进程还没起来,进入sleep,再次循环获取,直至非空。

ProcessState 是进程单例,表示当前进程状态

// frameworks/native/libs/binder/ProcessState.cppkkj
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    // 获取句柄为0,即ServiceManager的BpBinder
    return getStrongProxyForHandle(0);
}

struct handle_entry {
      IBinder* binder; // 指向BBinder或者BpBinder
      RefBase::weakref_type* refs;
};

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;
    AutoMutex _l(mLock);
    // 查找对应的BBinder或者BpBinder,在这里是取BpBinder
    handle_entry* e = lookupHandleLocked(handle);
    if (e != NULL) {
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) { // handle为0,即ServiceManager
                Parcel data;
                // 底层是binder_ioctl,查看对应的handle对应的binder是否已死
                status_t status = IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return 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;
}

更多参考:http://gityuan.com/2016/10/29/binder-thread-pool/

利用 ProcessState::self()->getContextObject(NULL)) App进程获取到了ServiceManager的BpBinder,其中BpBinder的handle是0

gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL)); 转型为IServiceManager,接着App进程需要向ServiceManager查询所需要的服务,其实也是binder的跨进程通信。

你可能感兴趣的:(android)