01. Android Binder图解 小米系统专家 解析Service 的addService注册过程 (安卓12)

很多BAT也不一定能懂的binder机制!
我同事从小米跳槽过来,干安卓framework层10年,是小米的专家级别
然后他把binder驱动层全部和我讲解了一遍,然后我这边做个笔记分享给大家。
因为搞懂binder需要会c,linux内核知识。看java根本就看不懂!

分4篇文字讲解:

01. Android Binder图解 小米系统专家 解析Service 的addService注册过程 (安卓12)

02. Android Binder图解 小米系统专家 解析 ServiceManager和binder通信 (安卓12)

03. Android Binder图解 小米系统专家 解析binder驱动层解析binder通信过程 (安卓12)

04. Android Binder图解 小米系统专家 从binder java层解析binder整个流程(安卓12)

binder包含4部分:我将Binder机制分为了Java Binder、Native Binder、Kernel Binder,

20200824193035435.png

一句话总结:把service服务通过binder驱动添加到serverManager的过程

系统源码位置:

/frameworks/av/media/mediaserver/main_mediaserver.cpp
/frameworks/native/libs/binder/ProcessState.cpp
/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
/frameworks/native/libs/binder/IServiceManager.cpp
/frameworks/native/include/binder/IInterface.h
/frameworks/native/libs/binder/IServiceManager.cpp
/frameworks/native/libs/binder/Binder.cpp
/frameworks/native/libs/binder/IPCThreadState.cpp

一. MediaPlayerService是怎么创建的

media进程是init进程解析init.rc开启的

Media 进程是由

init 进程通过解析 init.rc 文件而创建的。

service media /system/bin/mediaserver

class main

user media

group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm     

ioprio rt 4

二:我们先来看MediaServer的入口函数,代码如下所示。
/frameworks/av/media/mediaserver/main_mediaserver.cpp

**

int main(int argc __unused, char argv __unused)
{
signal(SIGPIPE, SIG_IGN);
//获取ProcessState实例
sp proc(ProcessState::self());
sp sm(defaultServiceManager());
ALOGI("ServiceManager: %p", sm.get());
InitializeIcuOrDie();
//注册MediaPlayerService
MediaPlayerService::instantiate();//1
ResourceManagerService::instantiate();
registerExtensions();
//启动Binder线程池
ProcessState::self()->startThreadPool();
//当前线程加入到线程池
IPCThreadState::self()->joinThreadPool(); }

ProcesState源码的关键:

打开binder驱动

static int open_driver()
{
   int fd = open("/dev/binder", O_RDWR);
   if (fd >= 0) {              
       //设置驱动层的最大线程数;调用的时binder_ioctl()方法;
       size_t maxThreads = 15;
       result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
   } else {
       ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
   }
   return fd;
}

三. 添加defaultServiceManager()

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

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

四:传递数据

frameworks/native/libs/binder/IServiceManager.cpp

 virtual status_t addService(const String16& name, const sp& service,
                                bool allowIsolated, int dumpsysPriority) {
        Parcel data, reply;//数据包
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name); //name值为"media.player"
        data.writeStrongBinder(service); //service值为MediaPlayerService
        data.writeInt32(allowIsolated ? 1 : 0);
        data.writeInt32(dumpsysPriority);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);//1
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

然后传给BpBinder的transact函数,代码如下所示。
frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::transact(
   uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
   if (mAlive) {
       status_t status = IPCThreadState::self()->transact(
           mHandle, code, data, reply, flags);
       if (status == DEAD_OBJECT) mAlive = 0;
       return status;
   }

   return DEAD_OBJECT;
}

BpBinder类通过IPCThreadState类来与Binder驱动交互

BpBinder将逻辑处理交给IPCThreadState

IPCThreadState* IPCThreadState::self()
{   
   //首次进来gHaveTLS的值为false
   if (gHaveTLS) {
restart:
       const pthread_key_t k = gTLS;//1
       IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);//2
       if (st) return st;
       return new IPCThreadState;//3
   }
   ...
   pthread_mutex_unlock(&gTLSMutex);
   goto restart;
}

IPCThreadState的transact函数。

在内存中创建一个Binder节点,将自己置为0号节点,这里的handle 值为 0 代表是 ServiceManager 进程

  • Binder驱动在内核空间中为传输的Binder实体对象创建对应的Binder节点

frameworks/native/libs/binder/IPCThreadState.cpp

*```
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel
reply, uint32_t flags)
{
status_t err;

flags |= TF_ACCEPT_FDS;
...
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);//1

if (err != NO_ERROR) {
    if (reply) reply->setError(err);
    return (mLastError = err);
}

if ((flags & TF_ONE_WAY) == 0) {
   ...
    if (reply) {
        err = waitForResponse(reply);//2
    } else {
        Parcel fakeReply;
        err = waitForResponse(&fakeReply);
    }
   ...
} else {
   //不需要等待reply的分支
    err = waitForResponse(NULL, NULL);
}

return err;

}

**总结:

1.addService函数将数据打包发送给BpBinder来进行处理。

2.BpBinder新建一个IPCThreadState对象,并将通信的任务交给IPCThreadState。

3.IPCThreadState的writeTransactionData函数用于将命令协议和数据写入到mOut中。

4.IPCThreadState的waitForResponse函数主要做了两件事,一件事是通过ioctl函数操作mOut和mIn来与Binder驱动进行数据交互,另一件事是处理各种命令协议。**

**open 是打开驱动、mmap 是映射驱动、ioctl 是操作驱动、close 是关闭驱动,

分别对应驱动层的 binder_open、binder_mmap、binder_ioctl 和 binder_colse 方法

最终通过ioctl函数和Binder驱动进行通信,最后是交给了binder 驱动的 ioctl 方法,这一部分涉及到Kernel Binder的内容**

面试常问的问题:

问题:请问****MediaPlayerService****所在的进程,如何和binder驱动通信的?(重点)

MediaPlayerService是如何注册的。通过了解MediaPlayerService是如何注册的,可以得知系统服务的注册过程

我的理解:

1).打开binder驱动

2). 把对应的参数,封装成bpbinder序列化的对象,交给binder驱动

打开/dev/binder设备,这样的话就相当于和内核binder机制有了交互的通道

l 映射fd到内存,设备的fd传进去后,估计这块内存是和binder设备共享的

binder_ioctl()

问题:MediaPlayerService和servermanager是不同进程,如何通信的?

通过binder驱动。内核,内存映射关系。

————————————————

问题:bpbinder有什么作用?

Bn 是Binder Native的含义,是和Bp相对的,Bp的p是proxy代理的意思,那么另一端一定有一个和代理打交道的东西,这个就是Bn。

讲到这里会有点乱喔。先分析下,到目前为止都构造出来了什么。

l BpServiceManager

l BnMediaPlayerService

数据流向:

具体的数据有 interfaceToken(远程服务的名称)、handle(远程服务的句柄)、cookie(本地服务的地址),

有两个结构体 flat_binder_object 和 binder_write_read。

问题:Media 服务是如何添加到servermanager中的?

1).Media 进程是由 init 进程通过解析 init.rc 文件而创建的。

2). 最后是交给了binder 驱动的 ioctl 方法

问题:binder进程是在哪里启动的?

我们知道Zygote进程会调用AndroidRuntime::startReg函数注册一系列的JNI函数,而这其中就包括我们的Android Framework层的Binder框架层相关的JNI,此时就标志着Framework层BInder框架的启动,而不是到了system_server进程才开始启动的

!
1641780705473-ti3.png
binder.png

你可能感兴趣的:(01. Android Binder图解 小米系统专家 解析Service 的addService注册过程 (安卓12))