Binder机制原理解析

news2024/12/22 23:09:56

前言

我们都知道Android应用程序由Activity、Service、Broadcast Receiver、Content Provider四大组件构成的,他们可能运行在不同进程中,还有Android系统中还有各种服务,例如Actiivty管理服务ActivityManagerService、电源管理服务PowerManagerService、显示管理服务DisplayManagerService、包管理服务PackageManagerService等服务,这些服务在都在系统进程System中,应用程序通过上下文Context的getSystemService()方法轻松获取那些服务的功能,这是怎么做到的呢?这其中就是通过Binder跨进程通讯机制来实现的。

一.Binder机制是什么,在Android中扮演什么角色

Binder机制是Android系统跨进制通讯的一种机制,与传统的跨进程通讯如Socket、Share Memory、Signal相比,它在进程间传输数据中,只需执行一次复制操作,提高了效率节省了内存,并且Binder采用了CS架构,通讯更加稳定,提供服务的进程叫做Server进程,而访问服务的叫做Client进程,Server进程和Client进程的通讯需要依靠Binder驱动程序中的一个/dev/binder设备文件。在Server组件服务启动的时候,会将自己注册到Service Manager中,以便Client组件进程可以通过Service Manager找到Service组件服务。Service Manager是Binder进程间通讯的管理者,它是一种特殊的Service服务组件。
binder框架

如上图所示,我们可以看出Client、Service、Service Manager都运行在用户进程,而Binder驱动程序运行在 内核空间,其中,Service Manager和Binder驱动程序由系统负责提供,而Client和Service组件由应用程序来实现。Client、Service和Service Manager均是通过系统调用叩open()、mmap()、ioctl()方法来访问设备文件/dev/ binder,从而实现与Binder驱动程序的交互,而交互的目的就是为了能够间接地执行进程间通信。
这里先简单介绍下Binder机制的整体流程,先有个概念先,后面再逐步的讲解
Binder机制有三个层次,Java Binder、Native Binder、kernel Binder。Java Binder依赖于Native Binder, Native Binder依赖于Kernel Binder。先介绍下Service Manager这个进程,这个Service Manager和Java层的ServiceManager不同,Java层的是一个管理类可以添加注册查询服务,通过Serive Manager Binder大管家的代理对象去添加注册查询服务的。代理对象相当于Client端。而实际的Service Manager就是Serivce端,它的代码路径为.\frameworks\native\cmds\servicemanager\service_manager.c 。它是个单独的程序开机的时候由init进程启动的。管理着所有的Service组件,如前面的ActivityManagerService等各种服务,并想Client提供获取Service组件代理对象的服务,。了解了这个背景知识我们接下来我们分析下整体流程:

1.首先需要去注册服务,如ActivityManagerService服务,注册服务的时候会先获取Service Manager的代理对象IServiceManager,把AMS服务的名称、Binder对象等封装成Parcel对象,通过ioctl通讯会把数据传给Binder驱动程序。
2.Binder驱动层会根据代理对象的句柄值(Service Manager代理对象的句柄值默认为0)去寻找驱动层的Service Manager的实体对象,因为Service Manager 在Android系统启动的时候已经向Binder驱动程序注册为Binder上下文管理者,所以肯定能找到;从前面流程我们知道会传AMS Binder对象到驱动层,驱动层会去寻找有没有AMS对对应的实体对象,如果没有,就会去创建一个AMS的实体对象,并保存在一个红黑树中,并且会创建AMS的引用对象。
3.Binder驱动程序根据Service Manager实体对象去找对应的服务端程序,即之前提的service_manager.c所运行的程序,这个程序在启动的时候就有个循环一直等待Binder驱动程序的消息。service_manager.c程序收到注册
4.Service_manager.c收到注册AMS服务的消息后,会把驱动程序传给它AMS的句柄值封装成一个binder_object对象,并把对象加入到链表中。然后返回到Binder驱动程序。
5.Binder程序收到注册成功的消息后会发消息给调用端程序,调用端程序收到消息,注册流程就结束了。
获取对应的服务流程和注册服务流程相似,这里先不介绍了。接下来具体分析怎么注册服务。

二、Binder机制的具体流程分析

2.1.Service Manager服务的启动流程
在前面提到Service Manager服务进程作为Binder机制的大管家扮演者很重要的角色,所以我们先分析下这个程序,ServiceManager是init进程负责启动的,具体是在解析init.rc配置文件时启动的,init进程是在系统启动时启动的,因此ServiceManager亦是如此。
ServiceManager的启动脚本在servicemanager.rc中, frameworks/native/cmds/servicemanager/

service servicemanager /system/bin/servicemanager
    class core animation
    user system  //1
    group system readproc
    critical //2
    onrestart restart healthd  
    onrestart restart zygote
    onrestart restart audioserver
    onrestart restart media
    onrestart restart surfaceflinger
    onrestart restart inputflinger
    onrestart restart drm
    onrestart restart cameraserver
    onrestart restart keystore
    onrestart restart gatekeeperd
    writepid /dev/cpuset/system-background/tasks
    shutdown critical

service用于通知init进程创建名为servicemanager的进程,这个servicemanager进程执行程序的路径为/system/bin/servicemanager。注释1的关键字user说明servicemanager是以用户system的身份运行的,注释2处的critical说明servicemanager是系统中的关键服务,关键服务是不会退出的,如果退出了,系统就会重启,当系统重启时就会启动用onrestart关键字修饰的进程,比如zygote、media、surfaceflinger等等。servicemanager的入口函数service_manager.c
//service_manager.c程序

int main(int argc, char** argv)
{
    struct binder_state *bs;//1
    union selinux_callback cb;
    char *driver;

    if (argc > 1) {
        driver = argv[1];
    } else {
        driver = "/dev/binder";
    }

    bs = binder_open(driver, 128*1024);//2
    ...
    if (binder_become_context_manager(bs)) {//3
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    ...
    if (getcon(&service_manager_context) != 0) {
        ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
        abort();
    }
    binder_loop(bs, svcmgr_handler);//4

    return 0;
}

注释1处的binder_state结构体用来存储binder的三个信息:

struct binder_state
{
    int fd; //binder设备的文件描述符
    void *mapped; //binder设备文件映射到进程的地址空间
    size_t mapsize; //内存映射后,系统分配的地址空间的大小,默认为128KB
};

main函数主要做了三件事:
1.注释2处调用binder_open函数用于打开binder设备文件,并申请128k字节大小的内存空间。
2.注释3处调用binder_become_context_manager函数,将servicemanager注册成为Binder机制的上下文管理者。
3.注释4处调用binder_loop函数,循环等待和处理client端发来的请求。
现在详细介绍下这三部分的知识
2.1.1 打开和映射Binder设备文件
Binder_open函数用来打开设备文件/dev/binder,并且将他映射到进程的地址空间,它的实现如下:

struct binder_state *binder_open(const char* driver, size_t mapsize)
{
    struct binder_state *bs;
    struct binder_version vers;
   //分配 binder_state空间
    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return NULL;
    }
//打开设备文件
    bs->fd = open(driver, O_RDWR | O_CLOEXEC);//1
    if (bs->fd < 0) {
        fprintf(stderr,"binder: cannot open %s (%s)\n",
                driver, strerror(errno));
        goto fail_open;
    }
    //获取Binder的version
    if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
        (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {//2
        fprintf(stderr,
                "binder: kernel driver version (%d) differs from user space version (%d)\n",
                vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
        goto fail_open;
    }
   //mapszie 为128K
    bs->mapsize = mapsize;
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);//3
    if (bs->mapped == MAP_FAILED) {
        fprintf(stderr,"binder: cannot map device (%s)\n",
                strerror(errno));
        goto fail_map;
    }
    return bs;

fail_map:
    close(bs->fd);
fail_open:
    free(bs);
    return NULL;
}

注释1处用于打开binder设备文件,Binder驱动程序中的binder_open就会调用,它会为当前进程创建一个binder_proc结构体,用来描述当前进程的Binder进程间的通讯。
注释2处的ioctl函数用于获取Binder的版本,如果获取不到或者内核空间和用户空间的binder不是同一个版本就会直接goto到fail_open标签,释放binder的内存空间。
注释3处调用mmap函数进行内存映射,通俗来讲就是将binder设备文件映射到进程的地址空间,地址空间的大小为mapsize,也就是128K。映射完毕后会将地址空间的起始地址和大小保存在binder_state结构体中的mapped和mapsize变量中.
kernel/goldfish/drivers/staging/android/binder.c
//binder 驱动程序中代码

static int binder_open(struct inode *nodp, struct file *filp)
{   //代表Binder进程
	struct binder_proc *proc;//1
	binder_debug(BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n",
		     current->group_leader->pid, current->pid);
     //分配binder_proc内存空间
	proc = kzalloc(sizeof(*proc), GFP_KERNEL);//2
	if (proc == NULL)
	return -ENOMEM;
        //接下来对binder_proc结构体进行初始化操作
	get_task_struct(current);
	//任务控制块
	proc->tsk = current;
	INIT_LIST_HEAD(&proc->todo);
	init_waitqueue_head(&proc->wait);
	//默认优先级
	proc->default_priority = task_nice(current);
    //binder同步锁
	binder_lock(__func__);
	//将当前的binder_proc加入到binder驱动程序全局的hash队列binder_proces中
 	 binder_stats_created(BINDER_STAT_PROC);
	hlist_add_head(&proc->proc_node, &binder_procs);
	//进程pid
	proc->pid = current->group_leader->pid;
	INIT_LIST_HEAD(&proc->delivered_death);
	//将proc结构体保存在参数filp成员变量private_data中,参数filep指向一个打开、//文件结构体,当进程调用函数open打开设备文件/dev/binder之后,内核会返回一个文件句
//柄,这个文件句柄就是和参数filep关联在一起的,因此后面进程使用mmap或者ioctl和
//驱动程序交互时,就可以用成员变量private_data找到binder_proc结构体
	filp->private_data = proc;//3
    //binder同步锁释放
	binder_unlock(__func__);
	...
	return 0;
}

上面代码已经注释很清楚了,调用open,Binder驱动程序主要创建binder_proc结构体,并加入到全局hash队列中,无论是在Service组件或者是在Client程序中调用open打开设备文件/dev/binder都会为其创建一个binder_proc结构体代表目标进程。
2.1.2注册成为Binder上下文管理者
Service Manager要成为Binder进程间通信机制的上下文管理者,就必须通过IO控制命令BINDER_SET_CONTEXT_MGR将自己注册到Binder驱动程序中,通过函数binder_become_context_manager来实现,代码如下:

int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

BINDER_SET_CONTEXT_MGR是一个整型参数,用来描述一个和Service Manager对应Binder本地对象的地址值,由于Service Manger对应的Binder本地对象是一个虚拟对象,其地址值为0,所以后面一个参数传0就可以了。
最终会调用Binder驱动程序的binder_ioctl函数
kernel/goldfish/drivers/staging/android/binder.c

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int ret;
	//获取binder_proc结构体
	struct binder_proc *proc = filp->private_data; //1
	struct binder_thread *thread;
	unsigned int size = _IOC_SIZE(cmd);
	void __user *ubuf = (void __user *)arg;
	trace_binder_ioctl(cmd, arg);

	ret = wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
	if (ret)
		goto err_unlocked;

	binder_lock(__func__);
	//调用函数binder_get_thread为当前线程创建一个binder_thread结构体,当前线程即Service Manager进程的主线程,同时它也是Binder线程
	thread = binder_get_thread(proc);//2
	if (thread == NULL) {
		ret = -ENOMEM;
		goto err;
	}

	switch (cmd) {
    ...
	case BINDER_SET_CONTEXT_MGR:
//binder_context_mgr_node不等于NULL说明已经注册过了
		if (binder_context_mgr_node != NULL) {//3
			printk(KERN_ERR "binder: BINDER_SET_CONTEXT_MGR already set\n");
			ret = -EBUSY;
			goto err;
		}
		ret = security_binder_set_context_mgr(proc->tsk);
		if (ret < 0)
			goto err;
		//全局变量binder_context_mgr_uid用来描述注册了binder上下文管理者的进程的有效用户ID,不等于-1,说明已经有一个进程注册过了上下文管理者
		if (binder_context_mgr_uid != -1) {//4
//判断当前进程的有效用户ID是否等于binder_context_mgr_uid
			if (binder_context_mgr_uid != current->cred->euid) {//5
				printk(KERN_ERR "binder: BINDER_SET_"
				       "CONTEXT_MGR bad uid %d != %d\n",
				       current->cred->euid,
				       binder_context_mgr_uid);
				ret = -EPERM;
				goto err;
			}
		} else
	             binder_context_mgr_uid = current->cred->euid;//6赋值uid
// 创建Service Manager实体对象binder_node结构体,保存在全局变量binder_context_mgr_node中
		  binder_context_mgr_node = binder_new_node(proc, NULL, NULL);//7
		if (binder_context_mgr_node == NULL) {
			ret = -ENOMEM;
			goto err;
		}
//增加引用计数,引用计数用来管理binder实体对象的生命周期的,使用弱引用和强引用技术管理
		binder_context_mgr_node->local_weak_refs++;
		binder_context_mgr_node->local_strong_refs++;
		binder_context_mgr_node->has_strong_ref = 1;
		binder_context_mgr_node->has_weak_ref = 1;
		break;
 ...
err_unlocked:
	trace_binder_ioctl_done(ret);
	return ret;
}

让Service Manager成为上下文管理者在驱动层主要是为其创建一个全局的Service Manager实体对象并保存在binder_context_mgr_node中,注意在调用过程中会通过binder_get_thread方法创建一个binder_thread结构体,用来描述Binder线程池中的一个线程,它的定义如下:

 struct binder_thread (
	//所属的宿主进程
	struct binder_proc *proc;
	//一个节点,宿主进程proc使用红黑树来保存其binder线程池中所有的线程,rb_node表示其一个节点
struct rb_node rb_node;
	//宿主进程pid
	int pid;
//线程状态
	int looper;	
//binder事务
	struct binder_transaction	*transaction_stack;
	struct list_head todo;
	uint32_t return_error; /*	Write	failed,	return error code in read buf */
	uint32_t return_error2; /* Write failed, return error code in read */
	/* buffer. Used when sending a reply to a dead process that */
	/* we are also waiting on */
	wait_queue_head_t wait;
		struct binder_stats stats;
};
Looper的取值有如下几种:
enum {	
BINDER_LOOPER_STATE_REGISTERED  = 0x01,	
BINDER_LOOPER_STATE_ENTERED     = 0x02,	
BINDER_LOOPER_STATE_EXITED      = 0x04,	
BINDER_LOOPER_STATE_INVALID     = 0x08,	
BINDER_LOOPER_STATE_WAITING     = 0x10,	
BINDER_LOOPER_STATE_NEED_RETURN = 0x20
};

一个刚创建的binder_thread结构体其状态初始化为BINDER_LOOOPER_STATE_ NEED_RETURN,表示该线程需要马上返回到用户空间。当它可以处理进程间通信请求的时候,Binder驱动程序会将他状态设置为BINDER_LOOPER_STATE_ REGISTERED或者BINDER_LOOOPER_STATE_ENTERED,当线程空闲的时候会将其状态设置为BINDER_LOOPER_STATE_WAITING,当Binder线程退出的时候会将其状态设置为BINDER_LOOPER_STATE_EXITED。
当一个来自Client进程的请求指定要由某一个Binder线程来处理时,这个请求就会加入到相应的binder, thmad结构体的成员变量tedo所表示的狀列中,并且会唤醒这个线程来处理,因为这时候这个线程可能 处于睡眠状态。
当Binder驱动程序决金将二个事务交给一个Binder线程处理时,它就会将该事务封装成一个hinder, transaction结构体,并且将它添加到由线程结构体binder_ thread的成员变量transaction_stack所描述的一 个事务堆栈中。
回到之前Service Manager注册成为上下文管理者,之后将会循环等待Client进程请求了。
2.1.3 循环等待Client进程请求

void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    uint32_t readbuf[32];

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;

    readbuf[0] = BC_ENTER_LOOPER;
    binder_write(bs, readbuf, sizeof(uint32_t));//1

    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;

        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//2

        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }

        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);//3
        if (res == 0) {
            ALOGE("binder_loop: unexpected reply?!\n");
            break;
        }
        if (res < 0) {
            ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
            break;
        }
    }
}

注释1处将BC_ENTER_LOOPER指令通过binder_write函数写入到Binder驱动中,这样当前线程(ServiceManager的主线程)就成为了一个Binder线程,这样就可以处理进程间的请求了。在无限循环中不断的调用注释2处的ioctl函数,它不断的使用BINDER_WRITE_READ指令查询Binder驱动中是否有新的请求,如果有就交给注释3处的binder_parse函数处理。如果没有,当前线程就会在Binder驱动中睡眠,等待新的进程间请求。
frameworks/native/cmds/servicemanager/binder.c

int binder_write(struct binder_state *bs, void *data, size_t len)
{
    struct binder_write_read bwr;//1
    int res;

    bwr.write_size = len;
    bwr.write_consumed = 0;
    bwr.write_buffer = (uintptr_t) data;//2
    bwr.read_size = 0;
    bwr.read_consumed = 0;
    bwr.read_buffer = 0;
    res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);//3
    if (res < 0) {
        fprintf(stderr,"binder_write: ioctl failed (%s)\n",
                strerror(errno));
    }
    return res;
}

注释1处定义binder_write_read结构体,接下来的代码对bwr进行赋值,其中需要注意的是,注释2处的data的值为BC_ENTER_LOOPER。注释3处的ioctl函数将会bwr中的数据发送给binder驱动,我们已经知道了ioctl函数在Kernel Binder中对应的函数为binder_ioctl,此前分析过这个函数,这里截取BINDER_WRITE_READ命令处理部分

static long binder_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{   
    ...
    void __user *ubuf = (void __user *)arg;
    ...
	switch (cmd) {
	case BINDER_WRITE_READ: {
		struct binder_write_read bwr;
		if (size != sizeof(struct binder_write_read)) {
			ret = -EINVAL;
			goto err;
		}
		if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {//1
			ret = -EFAULT;
			goto err;
		}
		binder_debug(BINDER_DEBUG_READ_WRITE,
			     "binder: %d:%d write %ld at %08lx, read %ld at %08lx\n",
			     proc->pid, thread->pid, bwr.write_size, bwr.write_buffer,
			     bwr.read_size, bwr.read_buffer);

		if (bwr.write_size > 0) {//2
			ret = binder_thread_write(proc, thread, (void __user *)bwr.write_buffer, bwr.write_size, &bwr.write_consumed);//3
			trace_binder_write_done(ret);
			if (ret < 0) {
				bwr.read_consumed = 0;
				if (copy_to_user(ubuf, &bwr, sizeof(bwr)))
					ret = -EFAULT;
				goto err;
			}
		}
	    ...
		binder_debug(BINDER_DEBUG_READ_WRITE,
			     "binder: %d:%d wrote %ld of %ld, read return %ld of %ld\n",
			     proc->pid, thread->pid, bwr.write_consumed, bwr.write_size,
			     bwr.read_consumed, bwr.read_size);
		if (copy_to_user(ubuf, &bwr, sizeof(bwr))) {//4
			ret = -EFAULT;
			goto err;
		}
		break;
	}
   ...
	return ret;
}

注释1处的copy_from_user函数,它用于将把用户空间数据ubuf拷贝出来保存到内核数据bwr(binder_write_read结构体)中。注释2处,bwr的输入缓存区有数据时,会调用注释3处的binder_thread_write函数来处理BC_ENTER_LOOPER协议,其内部会将目标线程的状态设置为BINDER_LOOPER_STATE_ENTERED,这样目标线程就是一个Binder线程。
注释4处通过copy_to_user函数将内核空间数据bwr拷贝到用户空间。
在前面提到的无限循环中,不断的使用BINDER_WRITE_READ指令查询Binder驱动中是否有新的请求,所传递的binder_write_read结构体输入缓冲区大小为0,因此驱动程序只会调用binder_thread_read检查Service Manager进程是否有新的进程间通信请求需要处理,

接下来分析下binder驱动的binder_thread_read方法
kernel/goldfish/drivers/staging/android/binder.c

 static int binder_thread_read(struct binder_proc *proc, struct binder_thread *thread,
	void  	_user *buffer, int size, signed long *consumedz int non_block)
 {
void _user *ptr = buffer + *consumed;
 void _user *end = buffer + size;
int ret = 0;
int wait_for_proc_work;
........
wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);//注释1
........
thread->looper |= BINDER_LOOPER_STATE_WAITING; 
if (wait_for_proc_work)
	proc->ready_threads++;
mutex_unlock(&binder_lock);
if (wait_for_proc_work) {
......
	binder_set_nice(proc->default_priority);
	if (non_block) {
	 	if(!binder_has_proc_work(proc, thread))
			ret = -EAGAIN;
		} else
		ret = wait_event_interruptible_exclusive(proc->wait, binder_has_proc_ thread));
	} else {
		if (non_block) {
			if (!binder_has_thread_work(thread))
			ret = -EAGAIN;
		} else
	        ret = wait_event_interruptible(thread->wait, binder_has_thread_work(thread));
	 }
mutex_lock(&binder_lock);
if (wait_for_proc_work)
proc->ready_tbreads——;
thread->looper &= -BINDER_LOOPER_STATE_WAITING;
........
while (1) {//注释2
........
}
done:
*consumed = ptr - buffer;
if (proc->requested_threads + proc->ready_threads == 0 && 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++;
.......
if (put_user(BR_SPAWN_LOOPER, (uint32_t  	user *)buffer))
return -EFAULT;
}
return 0;
}

在前面介绍结构体binder_thread时提到,如果一个线程的事务堆 栈transaction_stack不等于NULL,就表示它正在等待其他线程完成另外一个事务。另外,如果一个线程的todo队列不为空,就说明该线程有未处理的工作项。一个线程只有在其事务堆栈transaction_stack为NULL,并且其todo队列为空时,才可以去处理其所属进程的todo队列中的待处理工作项;否则它就要处理其事务堆栈transaction_stack中的事务或者todo队列中的待处理工作项。
在注释1中检查当前线程的事务堆栈是否为NULL.以及todo队列是否为空.如果两个条件都成立,那么就会将变量wait_for_proc_work的值设置为1 ,表示它接下来要检查它所属进程binder_proc的todo队列中是否有未处理的工作项;否则,它接下来就要优先处理自己的事务或者工作项了。接下来将当前线程的状态设置为BINDER_LOOPER_STATE_W AITING,表示该线程正 处于空闲状态,接着第19行判断变量wail_for_proe_work的值是否等于1。如果是,那么就说明当前线程所属的进程多了一个空闲Binder线程,接下来如果当前线程没有事要处理,判断是否是非阻塞的方式打开的设备文件/dev/binder,如果是当前进程有工作项或者当前线程需要立刻返回到用户空间就立刻返回到用户空间,否则睡眠等待在所属进程的等待队列wait中。如果当前线程有工作项事务处理,也判断是否是非阻塞,如果非阻塞,当前线程有作项否则需要立刻返回用户空间就返回到用户空间,否则睡眠在当前线程的等待队列中。

当当前线程被唤醒之后,会在while(1)循环中处理工作项,处理完之后还会检查是否需要请求当前线程所属进程proc增加一个新的binder线程来处理进程间通信请求。最后返回到用户层中。

Service Manager的启动流程到这里就介绍完了,接下来我们介绍怎么获取Service Manager服务的代理对象。
2.2.Service Manager代理对象的获取
service组件在启动时,需要将自己注册到Service Manager中;而Client组件在使用Service组件提供 的服务之前,也需要通过Service Manager来获得Serivce组件的代理对象。由于Service Manager本身也是 一个Service组件,因此,其他的Service组件和Client组件在使用它提供的服务之前,也需要先获得它 的代理对象。作为一个特殊的Service组件,Service Manager代理对象的获取过程与其他的Service代理 对象的获取过程有所不同,在本节中,我们将详细分析这个过程
Binder库提供了一个defaultServiceManager函数来获取一个Service Manager代理对象,我们从这个函数入口来进行介绍
路径 framework/base/libs/binder/IServiceManager.cpp

sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;

    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));//1
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }

    return gDefaultServiceManager;
}

从IServiceManager所在的文件路径就可以知道,ServiceManager中不仅仅使用了Binder通信,它自身也是属于Binder体系的。defaultServiceManager中同样使用了单例保证了进程中只存在一个Service Manager代理对象,注释1处的interface_cast函数生成了gDefaultServiceManager,其内部调用了ProcessState的getContextObject函数.gDefaultServiceManager是一个类型为IServiceManager的指针,它指向了进程内的一个BpServiceManager对象。
frameworks/native/libs/binder/ProcessState.cpp

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");//1
    return gProcess;
}

这里采用了单例模式,确保每个进程只有一个ProcessState实例。注释1处用于创建一个ProcessState实例,参数为/dev/binder。接着来查看ProcessState的构造函数,代码如下所示

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))//1
    , 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) {
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);//2
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }
    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

ProcessState的构造函数中调用了很多函数,需要注意的是注释1处,它用来打开/dev/binder设备。
注释2处的mmap函数,它会在内核虚拟地址空间中申请一块与用户虚拟内存相同大小的内存,然后再申请物理内存,将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间,实现了内核虚拟地址空间和用户虚拟内存空间的数据同步操作,也就是内存映射。
mmap函数用于对Binder设备进行内存映射,除了它还有open、ioctl函数,来看看它们做了什么。
注释1处的open_driver函数的代码如下所示。

static int open_driver(const char *driver)
{
    int fd = open(driver, O_RDWR | O_CLOEXEC);//1
    if (fd >= 0) {
        ...
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);//2
        if (result == -1) {
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
        }
    } else {
        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
    }
    return fd;
}

注释1处用于打开/dev/binder设备并返回文件操作符fd,这样就可以操作内核的Binder驱动了。注释2处的ioctl函数的作用就是和Binder设备进行参数的传递,这里的ioctl函数用于设定binder支持的最大线程数为15(maxThreads的值为15)。最终open_driver函数返回文件操作符fd。
ProcessState就分析倒这里,总的来说它做了以下几个重要的事:
1.打开/dev/binder设备并设定Binder最大的支持线程数。
2.通过mmap为binder分配一块虚拟地址空间,达到内存映射的目的
接下来回到IServiceManager.cpp代码中,通过ProcessState的调用了getContextObject函数获取一个Binder代理对象。代码如下:

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);//1
    if (e != NULL) {
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) { //2
            if (handle == 0) {
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            b = BpBinder::create(handle);//3
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

getContextObject函数中直接调用了getStrongProxyForHandle函数,注意它的参数的值为0,那么handle的值就为0,handle是一个资源标识。注释1处查询这个资源标识对应的资源(handle_entry)是否存在,如果不存在就会在注释3处新建BpBinder,并在注释3处赋值给 handle_entry的binder。最终返回的result的值为BpBinder

其实Binder库为每一个进程维护了一个Binder代理对象列表,使用一个向量列表Vector<handler_entry> mHandleToObject存储。相关的定义如下:

frameworks\native\include\binder\ProcessState.h
private:                                                                                        
   struct handle_entry {                                                                         
                IBinder* binder;                                                                
                RefBase::weakref_type* refs;                                                     
            };                                                                                  
          Vector<handle_entry>mHandleToObject;                                              

接下来看看注释1中lookupHandleLocked来检查mHandleToObject中有没有一个句柄值handle对应的handle_entry结构体:

ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)                    
{                                                                                               
    const size_t N=mHandleToObject.size();                                                     
    if (N <= (size_t)handle) {                                                                    
        handle_entry e;                                                                         
        e.binder = NULL;                                                                          
        e.refs = NULL;                                                                          
        status_t err = mHandleToObject.insertAt(e, N, handle+1-N);                                 
        if (err < NO_ERROR) return NULL;                                                       
    }                                                                                           
    return &mHandleToObject.editItemAt(handle);                                                
}

mHandlerToObejct是从小到大排列的,key为handle值,如果handle大于N就直接再最后插入,如果小于N就找到对应的位置插入即可。这时候插入的handle_entry还没被关联起来,里面的binder,refs变量还是NULL
接下来看注释2处如果获取的binder等于NULL,或者binder不等于但不能增加其弱引用计数说明binder已经被销毁了,这时候通过注释3创建一个BpBinder对象,赋值给binder变量,并给refs变量赋值,然后赋值给result返回。如果binder不等于NULL并且没有销毁掉,就从列表中得到的binder赋值给result返回,因为之前增加了弱引用计数,这时候需要减除。到这一步我们就获取到了ServiceManager的代理对象的BpBinder对象了。

接下来分析BpBinder如何转化成IServiceManager对象
interface_cast是IServiceManager父类IInterface中的一个内联函数,定义如下:

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

这里INTERFACE代表IServiceManager,IServiceManager的成员函数asInterface通过宏定义实现的,如下所示

class IServiceManager : public IInterface
{
public:
    DECLARE_META_INTERFACE(ServiceManager)//1
    ...
    //一些操作Service的函数
    virtual sp<IBinder>         getService( const String16& name) const = 0;
    virtual sp<IBinder>         checkService( const String16& name) const = 0;
    virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                bool allowIsolated = false,
                                int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
    virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;
    enum {
        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        CHECK_SERVICE_TRANSACTION,
        ADD_SERVICE_TRANSACTION,
        LIST_SERVICES_TRANSACTION,
    };
};

注释1处调用了DECLARE_META_INTERFACE宏,它的定义在父类IInterface.h中
frameworks/native/libs/binder/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();     

其中INTERFACE的值为ServiceManager,那么经过替换后的代码如下所示。

    static const ::android::String16 descriptor;       
    //定义asInterface函数
    static ::android::sp<IServiceManager> asInterface(                    
            const ::android::sp<::android::IBinder>& obj);            
    virtual const ::android::String16& getInterfaceDescriptor() const;  
    //定义IServiceManager构造函数
    IServiceManager();          
    //定义IServiceManager析构函数
    virtual ~IServiceManager();     

从DECLARE_META_INTERFACE宏的名称和上面的代码中,可以发现它主要声明了一些函数和一个变量。那么这些函数和变量的实现在哪呢?答案还是在IInterface.h中,叫做IMPLEMENT_META_INTERFACE宏,代码如下所示/
frameworks/native/libs/binder/include/binder/IInterface.h

#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() { }                                   \
IMPLEMENT_META_INTERFACE宏的INTERFACE值为ServiceManager,NAME值为”android.os.IServiceManager”,进行替换后的代码如下所示:
const ::android::String16 IServiceManager::descriptor("android.os.IServiceManager");          
const ::android::String16&                                          
        IServiceManager::getInterfaceDescriptor() const {              
    return IServiceManager::descriptor;                                
} 
 //实现了asInterface函数
::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);//1                        
        }                                                           
    }                                                               
    return intr;                                                    
}                                                                   
IServiceManager::IServiceManager() { }                                    
IServiceManager::~IServiceManager() { }       

参数obj是一个BpBinder对象,所以会调用queryLocalInterface函数,BpBinder该函数会返回NULL
所以会创建一个BpServiceManager对象。接下来我们看下BpServiceManager类,BpServiceManager定义在IServiceManager.cpp文件中
frameworks/native/libs/binder/IServiceManager.cpp

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

impl的值其实就是BpBinder,BpServiceManager的构造函数调用了基类BpInterface的构造函数

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

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
...
};
BpInterface继承了INTERFACE、BpRefBase,BpRefBase的实现如下所示
BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);//1

    if (mRemote) {
        mRemote->incStrong(this);           
        mRefs = mRemote->createWeak(this);  
    }
}

注释1中指定该对象生命周期收到弱引用计数和强引用计数影响,mRemote是一个IBinder* 指针,它最终的指向为BpBinder,也就是说BpServiceManager的mRemote指向了BpBinder。那么BpServiceManager的作用也就知道了,就是它实现了IServiceManager,并且通过BpBinder来实现通信。
现在梳理下 Service Manager代理对象各个类中的UML图
在这里插入图片描述

从图可以看出BpServiceManager继承了IServiceManager,IServiceManager继承BpInterfac,BpInterface继承了BpRefBase BpRefBase里包含了一个Bpbinder,Bpbinder和BBinder都继承于IBinder,Bpbinder代表代理对象,BBbinder代表服务端对象。
关于Service Manager代理对象的获取就介绍到这里,介绍了Serivce Manager服务端程序启动和其代理对象的获取,我们接下来分析下,从Java层面从上往下分析注册一个服务和获取一个服务是怎样的过程,注册和获取服务都是通过Service Manager代理对象来实现的。我们举个PowerManagerService的例子是怎么注册和获取的。
2.3.系统服务的注册过程
我们以PowerManagerService为例进行分析,PowerManagerService是在系统进程System中启动的,在System进程启动的时候会调用run方法,再其中启动系统的各种服务,具体代码如下:
framework/base/services/java/com/android/server/SystemServer.java

  private void run() { 
        ....... 
           try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();//1
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
.......

}

在注释1中会启动重要服务其中就有PMS服务,代码如下:

  private void startBootstrapServices() {                                                                                      
       ......                                                                                                                       
traceBeginAndSlog("StartPowerManager");
mPowerManagerService=mSystemServiceManager.startService(PowerManagerService.class);
traceEnd();
......
}

mSystemServiceManager时一个SystemServiceManager对象会去创建,回去创建一个PowerManagerService对象,并且调用其onStart方法。代码如下:
frameworks\base\services\core\java\com\android\server\SystemServiceManager.java

 @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            Slog.i(TAG, "Starting " + name);
            Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);

            // Create the service.
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                throw new RuntimeException("Failed to create " + name
                        + ": service must extend " + SystemService.class.getName());
            }
            final T service;
            try {
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service could not be instantiated", ex);
            } catch (IllegalAccessException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service must have a public constructor with a Context argument", ex);
            } catch (InvocationTargetException ex) {
                throw new RuntimeException("Failed to create service " + name
                        + ": service constructor threw an exception", ex);
            }

            startService(service);
            return service;
        } finally {
            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
        }
    }

    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        // Start it.
        long time = SystemClock.elapsedRealtime();
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            throw new RuntimeException("Failed to start service " + service.getClass().getName()
                    + ": onStart threw an exception", ex);
        }
        warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
    }

接下来看下PowerManagerService的onStart()方法,PowerManageService继承了SystemService:

 @Override
    public void onStart() {
        publishBinderService(Context.POWER_SERVICE, new BinderService());\\1
        publishLocalService(PowerManagerInternal.class, new LocalService());

        Watchdog.getInstance().addMonitor(this);
        Watchdog.getInstance().addThread(mHandler);
    }

注释1中就是当前的服务注册到binder机制中。BinderServic是服务端Binder对象,继承自IPowerManager.Stub,而IPowerManager.Stub继承自Binder对象并且实现了IPowerManager接口,因此创建的时候会调用Binder对象的构造方法:

public Binder() {
    mObject = getNativeBBinderHolder();//1
    NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);

    if (FIND_POTENTIAL_LEAKS) {
        final Class<? extends Binder> klass = getClass();
        if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                (klass.getModifiers() & Modifier.STATIC) == 0) {
            Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
                klass.getCanonicalName());
        }
    }
}

看注释1中通过本地方法创建了一个JavaBBinderHolder对象并用mObject保存了该对象的指针,以后通讯时需要使用。如下代码所示:

frameworks/base/core/jni/android_util_Binder.cpp
static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
{
    JavaBBinderHolder* jbh = new JavaBBinderHolder();
    return (jlong) jbh;
}
JavaBBinderHolder定义如下:
class JavaBBinderHolder
{
public:
    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    {
        AutoMutex _l(mLock);
        sp<JavaBBinder> b = mBinder.promote();
        if (b == NULL) {
            b = new JavaBBinder(env, obj);
            mBinder = b;
            ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
                 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
        }

        return b;
    }

    sp<JavaBBinder> getExisting()
    {
        AutoMutex _l(mLock);
        return mBinder.promote();
    }

private:
    Mutex           mLock;
    wp<JavaBBinder> mBinder;
};

里面有一个JavaBBinder对象,JavaBBinder继承了Binder库的BBinder,用来描述一个服务端本地对象的。
回到PMS的注册过程中来如下代码:

 protected final void publishBinderService(String name, IBinder service,
            boolean allowIsolated, int dumpPriority) {
        ServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }
我们发现最终通过ServiceManager.addService进行注册的
   public static void addService(String name, IBinder service, boolean allowIsolated,
            int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

主要分析getIServiceManager方法返回的是什么,代码如下所示
frameworks/base/core/java/android/os/ServiceManager.java

private static IServiceManager getIServiceManager() {
     if (sServiceManager != null) {
         return sServiceManager;
     }
     sServiceManager = ServiceManagerNative
             .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));//注释1
     return sServiceManager;
 }

我们看注释1中IServiceManager的获取过程
BinderInternal.getContextObject()获取一个java端的服务端代理对象BinderProxy,代码如下:
frameworks/base/core/jni/android_util_Binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//1
    return javaObjectForIBinder(env, b);
}

注释1之前已经讲解过了获取的是一个BpBinder对象,我们需要将通过javaObjectForIBinder函数转化成Java层的BinderProxy对象返回。

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    if (val == NULL) return NULL;

  
    if (val->checkSubclass(&gBinderOffsets)) { //1
        // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }

    // For the rest of the function we will hold this lock, to serialize
    // looking/creation/destruction of Java proxies for native Binder proxies.
    AutoMutex _l(gProxyLock);

    BinderProxyNativeData* nativeData = gNativeDataCache;
    if (nativeData == nullptr) {
        nativeData = new BinderProxyNativeData();
    }
    // gNativeDataCache is now logically empty.
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());//2
    if (env->ExceptionCheck()) {
        // In the exception case, getInstance still took ownership of nativeData.
        gNativeDataCache = nullptr;
        return NULL;
    }
    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
    if (actualNativeData == nativeData) {
        // New BinderProxy; we still have exclusive access.
        nativeData->mOrgue = new DeathRecipientList;//3
        nativeData->mObject = val;//4
        gNativeDataCache = nullptr;
        ++gNumProxies;
        if (gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) {
            ALOGW("Unexpectedly many live BinderProxies: %d\n", gNumProxies);
            gProxiesWarned = gNumProxies;
        }
    } else {
        // nativeData wasn't used. Reuse it the next time.
        gNativeDataCache = nativeData;
    }

    return object;
}

val要么是Binder代理对象要么是Binder服务端本地对象。这里是IServiceManager的代理对象。注释1检查是一个代理对象还是本地对象。Binder代理对象一直返回false。这句代码其中gBinderOffset是一个bindernative_offset_t结构体,有三个成员变量mClass对应Java层的Binder类,mExecTransact,mObject对应Binder对象的execTransact方法和mObject变量。这里返回false继续往下走,我们需要先了解下gBinderProxyOffsets结构体:

static struct binderproxy_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mGetInstance;
    jmethodID mSendDeathNotice;
    jmethodID mDumpProxyDebugInfo;

    // Object state.
    jfieldID mNativeData;  // Field holds native pointer to BinderProxyNativeData.
} gBinderProxyOffsets;

它有五个成员变量:mClass、mGetInstances mSendDeathNotice、mDumpProxyDebugInfo和mNaticeData,其中,mClass 指向Java层中的BinderProxy类,而mGetInstances、 mSendDeathNotice、mDumpProxyDebugInfo和mNativeData 分别指向这个 BinderProxy类的静态成员函数getInstance、静态成员函数sendDeathNctice,静态成员函数dumpProxyDebugInfo、成员变量mNativeData。
判断全局变量gNativeDataCache是否为空,为空就创建一个,这个指针会保存在Java层的BinderProxy的mNaticeData变量中。接下来通过注释2创建了一个BinderProxy对象.注释3和4对gNativeDataCache成员变量赋值。最后返回object对象。通过代码分析我们发现,BinderProxy会有个mNativeData变量指向native层的BinderProxyNativeData,而BinderProxyNativeData中mObject保存了BpBinder对象。
回到注册流程分析 ServiceManagerNative.asInterface方法。

static public IServiceManager asInterface(IBinder obj)
 {
     if (obj == null) {
         return null;
     }
     IServiceManager in =
         (IServiceManager)obj.queryLocalInterface(descriptor);
     if (in != null) {
         return in;
     }

     return new ServiceManagerProxy(obj);
 }

从前面的代码分析我们得知obj是一个BinderProxy对象,它的queryLocalInterface方法返回null.所以会创建一个ServiceManagerProxy对象。ServiceManagerProxy是ServiceManagerNative的内部类,它实现了IServiceManager接口。如下所示:

class ServiceManagerProxy implements IServiceManager {
   public ServiceManagerProxy(IBinder remote) {
       mRemote = remote;
   }

   public IBinder asBinder() {
       return mRemote;
}
.....
}

mRemote对象就是BinderProxy对象。获取到ServiceManager的代理对象ServieManagerProxy后,我们接下来分析addService方法

public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
        throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
    data.writeStrongBinder(service);//1
    data.writeInt(allowIsolated ? 1 : 0);
    data.writeInt(dumpPriority);
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//2
    reply.recycle();
    data.recycle();
}

我们发现会把数据封装成一个Parcel对象。把要添加服务的描述符和名字还有服务等写入到data中,reply是用来存储返回结果的。注释1中调用了writeStrongBinder(service);写入服务。具体代码如下:
frameworks\base\core\jni\android_os_Parcel.cpp

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}

调用ibinderForJaveObject方法获取一个IBinder对象写入到Parcel中去
frameworks\base\core\jni\android_util_Binder.cpp

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    if (obj == NULL) return NULL;

    // Instance of Binder?
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {//1
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh->get(env, obj);
    }

    // Instance of BinderProxy?
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return getBPNativeData(env, obj)->mObject;
    }

    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    return NULL;
}

这里的obj是IPowerManager.Stub对象。所以注释1会成立。将其mObject变量指针转换成JavaBBinderHolder,调用其get方法返回一个BBinder对象。这个前面已经分析过了。这个JavaBBinderHolder以后客户端代理请求数据的时候需要用到。
回到addService方法中,最终通过BinderProxy的transact方法进行跨进程通信。这里code命令为ADD_SERVICE_TRANSACTION这里最终会通过jni调用到native层。如下所示:
frameworks/base/core/jni/android_util_Binder.cpp

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
    if (dataObj == NULL) {
        jniThrowNullPointerException(env, NULL);
        return JNI_FALSE;
    }
    Parcel* data = parcelForJavaObject(env, dataObj);//1
    if (data == NULL) {
        return JNI_FALSE;
    }
    Parcel* reply = parcelForJavaObject(env, replyObj);//2
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }
    IBinder* target = getBPNativeData(env, obj)->mObject.get();//3
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }
   ...
    status_t err = target->transact(code, *data, reply, flags);//4
    return JNI_FALSE;
}

注释1和注释2处,将Java层的Parcel对象转化成为Native层的Parcel对象。在1.1小节中,我们得知BpBinder会保存到BinderProxyNativeData的成员变量mObject中,因此在注释3处,从BinderProxy获取到BinderProxyNativeData指针再从成员变量mObject中获取BpBinder。最终会在注释4处调用BpBinder的transact函数,向Binder驱动发送数据,可以看出Java Binder是需要Native Binder支持的,最终的目的就是向Binder驱动发送和接收数据。接下来分析BpBinder的transact方法怎么和驱动binder发送和接收数据的。
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方法进行通讯,我们看下其静态方法self()的实现

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

注释1处的TLS的全称为Thread local storage,指的是线程本地存储空间,在每个线程中都有TLS,并且线程间不共享。注释2处用于获取TLS中的内容并赋值给IPCThreadState*指针。注释3处会新建一个IPCThreadState,这里可以得知IPCThreadState::self()实际上是为了创建IPCThreadState,它的构造函数如下所示。

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

注释1处的pthread_setspecific函数用于设置TLS,将IPCThreadState::self()获得的TLS和自身传进去。IPCThreadState中还包含mIn、一个mOut,其中mIn用来接收来自Binder驱动的数据,mOut用来存储发往Binder驱动的数据,它们默认大小都为256字节。
知道了IPCThreadState的构造函数,再回来查看IPCThreadState的transact函数。
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;
}

调用BpBinder的transact函数实际上就是调用IPCThreadState的transact函数。注释1处的writeTransactionData函数用于传输数据,其中第一个参数BC_TRANSACTION代表向Binder驱动发送命令协议,向Binder设备发送的命令协议都以BC_开头,而Binder驱动返回的命令协议以BR_开头。
现在分别来分析注释1的writeTransactionData函数和注释2处的waitForResponse函数
frameworks/native/libs/binder/IPCThreadState.cpp

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;//1

    tr.target.ptr = 0; 
    tr.target.handle = handle;//2 
    tr.code = code;  //code=ADD_SERVICE_TRANSACTION
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;

    const status_t err = data.errorCheck();//3
    if (err == NO_ERROR) {
        tr.data_size = data.ipcDataSize();
        tr.data.ptr.buffer = data.ipcData();
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_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 = reinterpret_cast<uintptr_t>(statusBuffer);
        tr.offsets_size = 0;
        tr.data.ptr.offsets = 0;
    } else {
        return (mLastError = err);
    }

    mOut.writeInt32(cmd);  //cmd=BC_TRANSACTION
    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;
}

注释1处的binder_transaction_data结构体(tr结构体)是向Binder驱动通信的数据结构,注释2处将handle传递给target的handle,用于标识目标,这里的handle的值为0,代表了ServiceManager代理对象;注释3处对数据data进行错误检查,如果没有错误就将数据赋值给对应的tr结构体。最后会将BC_TRANSACTION和tr结构体写入到mOut中。接下来就继续调用成员函数waitForResponse向Binder驱动程 序发送这个BC_TRANSACTION命令协议。

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    uint32_t cmd;
    int32_t err;
    while (1) {
        if ((err=talkWithDriver()) < NO_ERROR) break;//1
        err = mIn.errorCheck();
        if (err < NO_ERROR) break;
        if (mIn.dataAvail() == 0) continue;
        cmd = (uint32_t)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_REPLY://2
            {
                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 binder_size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(binder_size_t),
                            freeBuffer, this);
                    } else {
                        err = *reinterpret_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 binder_size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(binder_size_t), this);
                    }
                } else {
                    freeBuffer(NULL,
                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                        tr.data_size,
                        reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                        tr.offsets_size/sizeof(binder_size_t), this);
                    continue;
                }
            }
            goto finish;
        default:
            //处理各种命令协议
            err = executeCommand(cmd);
            if (err != NO_ERROR) goto finish;
            break;
        }
}
finish:
    ...
    return err;
}

这个函数通过一个while循环不断地调用成员函数talkWithDriver来与Binder驱动程序进行交互,以 便可以将前面准备好的BC_TRANSACTION命令协议发送给Binder驱动程序处理,并等待Binder驱动程 序将进程间通信结果返回来。

status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    if (mProcess->mDriverFD <= 0) {
        return -EBADF;
    }
    //和Binder驱动通信的结构体
    binder_write_read bwr; //1
    //mIn是否有可读的数据,接收的数据存储在mIn
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
    bwr.write_size = outAvail;
    bwr.write_buffer = (uintptr_t)mOut.data();//2
    //这时doReceive的值为true
    if (doReceive && needRead) {
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (uintptr_t)mIn.data();//3
    } else {
        bwr.read_size = 0;
        bwr.read_buffer = 0;
    }
   ...
    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_LOG_COMMANDS() {
            alog << "About to read/write, write size = " << mOut.dataSize() << endl;
        }
#if defined(__ANDROID__)
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)//4
            err = NO_ERROR;
        else
            err = -errno;
#else
        err = INVALID_OPERATION;
#endif
     ...
    } while (err == -EINTR);
    ...
    return err;
}

从前面的调用过程可以知道,缓冲区mOut里面存在一个BC_TRANSACTION命令协议。IPCThreadState 类的成员函数 talkWilhDriver()使用IO控制命令BINDER_WRITE_READ来与Binder驱动程序交互的,因此,它需要定义一个binder_write_read结构体来指定输入缓冲区和输出缓冲区。其中,输出缓冲区保存的是进程发送给Binder驱动程序的命令协议,而输入缓冲区保存的是Binder驱动 程序发送给进程的返回协议,它们分别与IPCThreadState类内部的命令协议缓冲区mOut和返冋协议缓冲区mln对应。最终通过注释4处的ioctl函数和Binder驱动进行通信,这一部分涉及到Kernel Binder的内容了,就不再详细介绍了,只需要知道在Kernel Binder中会创建PMS对应的binder_node结构体实体对象和binder_ref结构体引用对象。具体的通讯步骤如下:
(1) Client进程(这里指System进程注册PMS)向Binder驱动程序发送一个BC_TRANSACTION命令协议。Binder驱动程序根据协议内容找到目标Server进程(这里指的是Service Manager程序进程)之后,就会向Client进程发送一个BR_TRANSACTON_COMPLETE返回协议,表示它的进程间通信请求已经被接受。Client进程接收到Binder驱动程序发送给它的 BR_TRANSACTION_COMPLETE返回协议,并且对它进行处理之后,就会再次进入到Binder驱动程序 中去等待目标Server进程返回进程间通信结果。
(2) Binder驱动程序在向Client进程发送BR_TRANSACT1ON_COMPLETE返回协议的同时,也会向目标Server进程发送一个BR_TRANSACTION返回协议(这里会发送PMS引用对象的handle句柄值给Service Manager),请求目标Server进程处理该进程间通信请求。
(3) Server进程接收到Binder驱动程序发来的BR_TRANSACT1ON返回协议,并且对它进行处理之后(这里把对应服务名称和句柄值插入到Service Manager程序中的一个列表中),就会向Binder驱动程序发送一个BC_REPLY命令协议。Binder驱动程序根据协议内容找到目标Client进程之后,就会向Server进程发送一个BR_TRANSACTION_COMPLETE返回协议,表示它返 回的进程间通信结果已经收到了。Server进程接收到Binder驱动程序发送给它的BR_TRANSACTION_COMPLETE返回协议,并且对它进行处理之后,一次进程间通信过程就结束了。接着它会再次进入到 Binder驱动程序中去等待下一次进程间通信请求。
(4) Binder驱动程序向Server进程发送BR_TRANSACTION_COMPLETE返回协议的同时,也会向目标Client进程发送一个BR_REPLY返回协议,表示Server进程已经处理完成它的进程间通信请求了,并且将进程间通信结果返回给它。
我们知道最终Binder驱动程序会发送一个BR_REPLY协议给到Client程序,我们接下来回到上面waiteForResponse方法中的注释2:我们分析得知会从mIn中读取一个 binder_transaction_data结构体数据,并将其保存到reply返回结果的Parcel对象中。最终会回到Jave层的PowerManagerService进程中,到此PMS的注册流程就完成了。服务端注册完成后还需要启动Binder线程池,等待处理Client的请求。我们知道SystemServer进程是由Zygote进程fork出来的。在Fork出SystemServer进程之后,Zygote进程由如下代码:
/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
                                       ClassLoader classLoader) {
   if (RuntimeInit.DEBUG) {
       Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
   }

   Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
   RuntimeInit.redirectLogStreams();

   RuntimeInit.commonInit();
   // 启动 Binder 线程池
   ZygoteInit.nativeZygoteInit(); 
   // 进入 system_server 的 main 方法
   return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader); 
}

2.4 系统服务代理的获取并调用
接下来分析系统服务代理的获取并调用其方法,如我们在APP中调用PowerManagerService服务的shutdown()关机的方法,是怎么样的流程。
从应用层我们通过Context的getSystemService方法获取一个服务代理对象,如获取PMS的代理对象
PowerManager powermanager=(PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
我们从这里入手看下具体的调用流程:
Context的实现类是ContextImpl

public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
接下来看SystemServiceRegistry中静态代码块中
static{
 ....
 registerService("power", PowerManager.class, new SystemServiceRegistry.CachedServiceFetcher<PowerManager>() {
    public PowerManager createService(ContextImpl ctx) throws ServiceNotFoundException {
        IBinder b = ServiceManager.getServiceOrThrow("power");//1
        IPowerManager service = android.os.IPowerManager.Stub.asInterface(b);//2
        return new PowerManager(ctx.getOuterContext(), service, ctx.mMainThread.getHandler());//3
    }
});
 ....
}

首先分析注释1中获取PMS的代理对象IBinder
frameworks\base\core\java\android\os\ServiceManager.java

   /**
     * Returns a reference to a service with the given name.
     *
     * @param name the name of the service to get
     * @return a reference to the service, or <code>null</code> if the service doesn't exist
     */
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);//1
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(rawGetService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

    /**
     * Returns a reference to a service with the given name, or throws
     * {@link NullPointerException} if none is found.
     *
     * @hide
     */
    public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
        final IBinder binder = getService(name);
        if (binder != null) {
            return binder;
        } else {
            throw new ServiceNotFoundException(name);
        }
    }

我们从注释1中可以发现会从mCache缓存中获取是否有对应的IBinder对象,这割mCache是个HashMap对象,key为服务名称,value为IBinder代理对象。是在应用初始化Application的时候调用填充保存的,如果从mCache中没找到从rawGetService(name)方法中获取。反正最终获取都会通过以下代码获取
IBinder binder=getIServiceManager().getService(name);
前面已经分析过getIServiceManager()方法的获取了返回了一个ServiceManagerProxy对象
我们接下来看下其getService方法
frameworks\base\core\java\android\os\ServiceManagerNative.java

public IBinder getService(String name) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken("android.os.IServiceManager");
    data.writeString(name);
    this.mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
    IBinder binder = reply.readStrongBinder();
    reply.recycle();
    data.recycle();
    return binder;
}

和之前注册Serice调用addService方法一样,只是transact传入的code变成了GET_SERVICE_TRANSACTION代表获取服务。Service Manager处理完成GET_SERVICE_TRANSACTION操作之后,就会将一个Binder代理对象保 存在Parcel对象reply中。因此,第10行就调用Parcel对象reply的成员函数readStrongBinder将它读取出来,以及将它转换为一个Java服务代理对象。我们看下readStrongBinder的实现
frameworks\base\core\jni\android_os_Parcel.cpp

static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}

由于Parcel对象parcel里面保存了一个Binder代理对象,因此,第5行首先调用它的成员函数 readStrongBinder将这个Binder代理对象读取出来,接着再调用函数javaObjectForlBinder获得一个对 应的Java服务代理对象,最后将这个Java服务代理对象返回给调用者。javaOjectForIBinder在前面分析过了,这里会返回一个BinderProxy对象。
回到SystemServiceRegistry中的注释2中:

public interface IPowerManager extends IInterface {

	public abstract static class Stub extends Binder implements IPowerManager {
		public static IPowerManager asInterface(IBinder obj) {
    		if (obj == null) {
        			return null;
    		} else {
          			 IInterface iin =  obj.queryLocalInterface("android.os.IPowerManager");//1
         			 
		return (IPowerManager)(iin != null && iin instanceof IPowerManager ?(IPowerManager)iin : new  	IPowerManager.Stub.Proxy(obj));
    }
}


  	}

	
}

因为obj传入的是BinderProxy代理对象,它的queryLocalInterface方法返回false,所以最终返回的是IPowerManager.stub.Proxy对象。
//注释3直接将IPowerManager的代理对象传进来构造一个PowerManager管理类。

接下来分析怎么通过PowerManager跨进程调用服务端PowerManagerService的shutdown方法
frameworks\base\core\java\android\os\PowerManager.java

public void shutdown(boolean confirm, String reason, boolean wait) {
    try {
        mService.shutdown(confirm, reason, wait);
    } catch (RemoteException e) {
        throw e.rethrowFromSystemServer();
    }
}

从前面知道mService是传过来的IPowerManager.stub.Proxy对象。
我们看看其shutdown方法:

public void shutdown(boolean confirm, String reason, boolean wait) throws RemoteException {
    Parcel _data = Parcel.obtain();
    Parcel _reply = Parcel.obtain();

    try {
        _data.writeInterfaceToken("android.os.IPowerManager");
        _data.writeInt(confirm ? 1 : 0);
        _data.writeString(reason);
        _data.writeInt(wait ? 1 : 0);
        this.mRemote.transact(20, _data, _reply, 0);
        _reply.readException();
    } finally {
        _reply.recycle();
        _data.recycle();
    }

}

这里的mRemote是BinderProxy对象,同样通过transact方法调用,注意这里的20代表的是该shutdown该方法,每一个方法都有一个code。前面提到如果服务端注册的时候如PowerManagerSerivice注册服务时,会启动一个Binder线程池。一个Binder线程的生命周期可以划分为三个阶段:第一阶段是将自己注册到Binder 驱动线程池中;第二个阶段是在一个无限循环中不断地等待和处理进程间通信请求;第三个阶段是退出Binder线程池。
服务端注册线程池会调用如下代码:
frameworks\native\libs\binder\IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)
{
    LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
   //先kernel binder发送命令注册线程池
    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
    
    // This thread may have been spawned by a thread that was in the background
    // scheduling group, so first we will make sure it is in the foreground
    // one to avoid performing an initial transaction in the background.
        set_sched_policy(mMyThreadId, SP_FOREGROUND);

    status_t result;
    do {
        processPendingDerefs();
        // now get the next command to be processed, waiting if necessary
        //循环等待客户端代理请求
        result = getAndExecuteCommand();//2

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

    LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%p\n",
        (void*)pthread_self(), getpid(), (void*)result);
    
    mOut.writeInt32(BC_EXIT_LOOPER);
    talkWithDriver(false);
}

注册线程池后会通过getAndExecuteCommand方法接收客户端的请求。
frameworks\native\libs\binder\IPCThreadState.cpp

status_t IPCThreadState::getAndExecuteCommand()
{
    status_t result;
    int32_t cmd;

    result = talkWithDriver();
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();
        IF_LOG_COMMANDS() {
            alog << "Processing top-level Command: "
                 << getReturnString(cmd) << endl;
        }

        result = executeCommand(cmd);

        // After executing the command, ensure that the thread is returned to the
        // foreground cgroup before rejoining the pool.  The driver takes care of
        // restoring the priority, but doesn't do anything with cgroups so we
        // need to take care of that here in userspace.  Note that we do make
        // sure to go in the foreground after executing a transaction, but
        // there are other callbacks into user code that could have changed
        // our group so we want to make absolutely sure it is put back.
        set_sched_policy(mMyThreadId, SP_FOREGROUND);
    }

    return result;
}

talkwithDriver之前已经分析过了,通过发送BINDER_WRITE_READ与驱动binder进行通讯。读取到命令后最后通过execteCommand()方法处理。最终会调用BBinder的onTransact方法。前面提过PowerManagerSerivice注册的时候会创建一个JavaBBinderHolder 里面有个JavaBBinder成员变量,其JavaBBinder继承了BBinder并且持有IPoerManager.Stub对象。
frameworks\base\core\jni\android_util_Binder.cpp

    virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {
        JNIEnv* env = javavm_to_jnienv(mVM);

        ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);

        IPCThreadState* thread_state = IPCThreadState::self();
        const int32_t strict_policy_before = thread_state->getStrictModePolicy();

        //printf("Transact from %p to Java code sending: ", this);
        //data.print();
        //printf("\n");
           //调用服务代理Binder的onTransact方法这里指的是IPowerManager.Stub的onTransact方法
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);//1

        if (env->ExceptionCheck()) {
            ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
            report_exception(env, excep.get(),
                "*** Uncaught remote exception!  "
                "(Exceptions are not yet supported across processes.)");
            res = JNI_FALSE;
        }

        // Check if the strict mode state changed while processing the
        // call.  The Binder state will be restored by the underlying
        // Binder system in IPCThreadState, however we need to take care
        // of the parallel Java state as well.
        if (thread_state->getStrictModePolicy() != strict_policy_before) {
            set_dalvik_blockguard_policy(env, strict_policy_before);
        }

        if (env->ExceptionCheck()) {
            ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
            report_exception(env, excep.get(),
                "*** Uncaught exception in onBinderStrictModePolicyChange");
        }

        // Need to always call through the native implementation of
        // SYSPROPS_TRANSACTION.
        if (code == SYSPROPS_TRANSACTION) {
            BBinder::onTransact(code, data, reply, flags);
        }

        //aout << "onTransact to Java code; result=" << res << endl
        //    << "Transact from " << this << " to Java code returning "
        //    << reply << ": " << *reply << endl;
        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
    }
    

如注释1会调用服务端的onTransact方法。我们接下来分析下IPowerManager.Stub中的onTransact方法。

public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    String descriptor = "android.os.IPowerManager";
    boolean _arg0;
    int _arg1;
    boolean _arg2;
    int _arg2;
    long _arg0;
    String _arg1;
    int _arg0;
    boolean _arg1;
    int _arg1;
    String _arg2;
    String _arg3;
    IBinder _arg0;
    switch(code) {
   ...
case 20://1
    data.enforceInterface(descriptor);
    _arg0 = 0 != data.readInt();
    _arg1 = data.readString();
    _arg2 = 0 != data.readInt();
    this.shutdown(_arg0, _arg1, _arg2);
    reply.writeNoException();
    return true;

   ...



}





}

如注释1,前面提过调用shutdown的方法code为20,所以会走这个分支。最终调用IPowerManager.Stub的shutdown方法,调用完成后,和之前的流程一样,会发送一个BC_REPLY命令给Binder驱动程序,驱动程序再发送BR_REPLY命令给Client程序。到此调用流程就结束了。

三、总结

这次培训主要讲解了Binder跨进程通讯的整体流程,主要讲解了Service Manager Binder上下文管理者的启动,Service Manager代理对象的获取,以及从Java层如何注册服务和获取服务调用服务端组件的方法。大篇幅的讲解了Java 层Binder和native Binder,至于驱动层的Binder这里没有做过多介绍。Binder层实现还是比较复杂,感兴趣的可以自己阅读相关知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/891026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

半导体退火那些事(3)

4.半导体退火设备 双腔全自动兼容6-8寸快速退火炉RTP 产地:中国 型号: S803 特点: 室温到1250C&#xff0c;应用于SiC&#xff0c;GaN等第三代半导体领域 简介 (Description) S803系列自动快速退火炉&#xff0c;内置Robot可以自动取放片&#xff0c;适用于最大8英寸 (单片200m…

【MySQL系列】-回表、覆盖索引真的懂吗

【MySQL系列】-回表、覆盖索引真的懂吗 文章目录 【MySQL系列】-回表、覆盖索引真的懂吗一、MYSQL索引结构1.1 索引的概念1.2 索引的特点1.3 索引的优点1.4 索引的缺点 二、B-Tree与BTree2.1 B-Tree2.2 BTree2.3 B-Tree 与BTree树的区别2.4 那么为什么InnoDB的主键最好要搞成有…

【数据结构OJ题】链表的回文结构

原题链接&#xff1a;https://www.nowcoder.com/practice/d281619e4b3e4a60a2cc66ea32855bfa?tpId49&&tqId29370&rp1&ru/activity/oj&qru/ta/2016test/question-ranking 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 在做这道…

EMO实战:使用EMO实现图像分类任务(一)

文章目录 摘要安装包安装timm安装 grad-cam安装einops 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集 摘要 论文翻译&#xff1a;https://blog.csdn.net/m0_47867638/article/details/132034098?spm1001.2014.3001.5501 官方源码&#xff1a;https://github.com/…

uniapp项目APP云打包步骤

1.打开hbuilder工具&#xff0c;选择uniapp项目&#xff0c;从上方工具中选择发行 2.证书的生成&#xff0c;点击上面的如何生成证书的网址&#xff0c;按照步骤进行生成&#xff1a; 3.结果&#xff0c;点击打开所在目录&#xff0c;点击直接安装到手机&#xff0c;前提是手机…

excel日期函数篇1

1、DAY(serial_number)&#xff1a;返回序列数表示的某月的天数 在括号内给出一个时间对象或引用一个时间对象&#xff08;年月日&#xff09;&#xff0c;返回多少日 下面结果都为20 2、MONTH(serial_number)&#xff1a;返回序列数表示的某年的月份 在括号内给出一个时间对…

重新认识小米

被镁光灯聚焦的企业&#xff0c;总是会被贴上各种标签。 8月14日&#xff0c;小米科技创始人雷军以“成长”为主题的年度演讲&#xff0c;刷遍社交网络。提到小米&#xff0c;你首先想到什么&#xff1f;手机发烧友、极致性价比&#xff0c;还是最年轻的500强&#xff1f; 这…

手撕单链表

目录 链表的概念和结构 单链表的实现 申请新结点 打印 尾插 头插 尾删 头删 ​编辑 查找 在pos位置前插入元素 在pos位置后插入元素 删除pos位置的元素 删除pos位置之后的位置的元素​编辑 完整代码 SListNode.h SListNode.c 链表的概念和结构 链表是一种物理存储…

VS2022如何查看类成员都在哪里被调用了(VS如何打开Call Hierarchy视图)

文章目录 打开Call Hierarchy视图查看成员的调用 打开Call Hierarchy视图 单击菜单栏的“视图” > “调用层次结构”&#xff0c;即可打卡Call Hierarchy视图。 查看成员的调用 在代码编辑窗口&#xff0c;右键单击想要查看的类成员&#xff0c;然后选择“查看调用层次结…

2003-2021年全国30省市数字关注度数据

1、时间&#xff1a;2003-2021年 2、来源&#xff1a;政府工作报告 3、范围&#xff1a;30省市 不含西藏、其中2004年吉林缺失 4、指标&#xff1a;省份、年份、一级指标、二级指标、关键词、关键词词频、全文词频 5、词频&#xff1a;选取大数据、云计算、区块链、人工智能…

解决一直提示No module named “Crypto” 解决方案

今天跑脚本发现一直提示装Crypto包 已经装好了情况下还是这样&#xff1a; 解决方法&#xff1a; pip uninstall crypto pycryptodome pip install pycryptodome pycrypto和crypto是同一个库&#xff0c;crypto在 python 中又被称为pycrypto&#xff0c;它是一个第三方库&…

归并排序(C++ mpi 并行实现)

文章目录 主要思路1. 串行归并排序2. 进程的分发3. 对接收到的子数组进行排序4. 合并数组5.输出排序后的数组6.进程分发部分的优化7.完整代码 主要思路 我们首先实现串行的归并排序&#xff1b;实现进程的分发&#xff1b;排序其中的每个子部分&#xff1b;进程的合并通信&…

宝藏级画图工具-drawio

今天推荐一款非常好用的免费开源画图工具drawio. Drawio即可以下载安装到本地&#xff0c;也可以在线编辑&#xff0c;在线编辑网址为 https://app.diagrams.net/。 本地版下载地址为https://github.com/jgraph/drawio-desktop/releases 1、支持各类图形 Drawio可以非常便捷…

Docker服务编排Docker Compose介绍

1.服务编排概念 2.Docker Compose介绍 3.Docker Compose安装及使用

【【STM32----I2C通信协议】】

STM32----I2C通信协议 我们会发现I2C有两根通信线&#xff1a; SCL和SDA 同步 半双工 带数据应答 支持总线挂载多设备&#xff08;一主多从&#xff0c;多主多从&#xff09; 硬件电路 所有I2C设备的SCL连在一起&#xff0c;SDA连在一起 设备的SCL和SDA均要配置成开漏输出模式 …

MySQL— 基础语法大全及操作演示!!!(下)

MySQL—— 基础语法大全及操作演示&#xff08;下&#xff09;—— 持续更新 三、函数3.1 字符串函数3.2 数值函数3.3 日期函数3.4 流程函数 四、约束4.1 概述4.2 约束演示4.3 外键约束4.3.1 介绍4.3.2 语法4.3.3 删除/更新行为 五、多表查询5.1 多表关系5.1.1 一对多5.1.2 多对…

hdu8-Congruences(中国剩余定理)

Problem - 7363 (hdu.edu.cn) 参考&#xff1a;2023杭电暑假多校8 题解 3 5 7 10 | JorbanS_JorbanS的博客-CSDN博客 题解&#xff1a;&#xff08;中国剩余定理 增量法&#xff09; 注意验证和特判&#xff0c;此题中 pi 两两互质&#xff0c;可用CRT和增量法&#xff0c;当…

ipkvm之RK3568高温测试

1. 简介 KVM高温测试描述&#xff1a; 将KVM主板放入50℃的温箱中放置4个小时。四个小时后记录VGA小板的温度以及SOC温度和外壳温度。 测试仪器&#xff1a; 两块KVM主板&#xff0c;温度记录仪&#xff0c;两个串口&#xff0c;笔记本&#xff0c;电源 KVM主板上电和串口 …

【回溯】总结

1、 组合和子集问题 组合问题需要满足一定要求才算作一个答案&#xff0c;比如数量要求&#xff08;k个数&#xff09;&#xff0c;累加和要求&#xff08;target&#xff09;。 子集问题是只要构成一个新的子集就算作一个答案。 进阶&#xff1a;去重逻辑。 一般都是要对同…

星际争霸之小霸王之小蜜蜂(二)--类的使用

目录 前言 一、将设置内容写在一个类里 二、设置小蜜蜂的造型 三、设置猫蜜蜂的参数 四、绘制猫蜜蜂到窗口 总结 前言 昨天我们设置好了窗口&#xff0c;下面我们需要向窗口中添加元素了。 一、将设置内容写在一个类里 我个人理解书上的意思是要创建一个类&#xff0c;将所有需…