Linux传统的进程间通信原理
进程隔离
保护系统中进程互不干扰。在操作系统中,进程之间数据是不互通的,相互之间无法访问数据,保证数据的安全星。
在进程隔离的条件下,需要通过IPC(Inter Process Communication)机制进行进程间的通信。
进程空间划分
操作系统的核心是内核 ,独立于普通的应用程序,可以访问受保护的内存空间以及底层的硬件设备。
为了使用户进程不能操作内核,保证内核的安全性。所以操作系统将虚拟空间划分为两部分:
内核空间 (一般占1GB)
系统内核运行的空间
用户空间 (一般占3GB)
用于用户程序执行的空间
用户空间在不同进程之间不能共享,内核空间是各个进程之间共享的。
系统调用
用户空间的权限低于内核空间,导致用户空间无法直接访问内核资源(例如文件操作、网络访问等),就需要借助系统调用 实现内核资源访问。
系统调用 是用户空间访问内核的唯一方式,保证了所有资源访问都是在内核的控制下进行,避免用户程序对系统资源的越级访问,提升系统的安全和稳定性。
Linux采用两级保护机制:
当进程使用系统调用执行内核代码时,进程就进入了内核态 ,此时处理器处于0级·;当进程执行自己的代码时,进程就进入用户态 ,此时处理器位于3级·。
系统调用主要通过以下两个函数实现:
copy_from_user:将数据从用户空间拷贝到内核空间
copy_to_user:将数据从内核空间拷贝到用户空间
传统IPC功能实现
发送进程通过系统调用 copy_from_user·把自己的内存缓存区(发送进程)的数据拷贝到内核缓存区中
内核程序通过系统调用 copy_to_user把内核缓存区的数据拷贝到接收进程的内存缓存区中
传统IPC通信过程中暴露了两个明显的缺点:
性能低下 ,需要经历两次数据拷贝过程:发送进程内存缓存区 -> 内核缓存区 -> 接收进程内存缓存区
空间、时间浪费 ,接收方需要事先开辟一块内存空间准备接受发送方的数据,由于不能确定数据的大小。所以只能开辟一块较大的空间(空间浪费)或者先行获取发送数据的大小(时间浪费)。
传统Linux进程通信手段
管道
消息队列
共享内存 :无需复制,共享缓冲区直接附加到进程的虚拟地址,速度快。但是无法解决进程间同步问题
套接字(Socket) :接口通用,但是传输效率低,主要用于不同机器间的通信
信号量(semaphore) :作为一种锁机制,防止某进程正在访问共享资源时,其他进程也在访问该资源。
信号
Binder基本原理 动态内核可加载模块 模块是具有独立功能的程序,可以被单独编译但是无法独立运行。利用动态内核可加载模块机制,动态的添加一个内核模块到内核空间内,用户进程就可以通过这个模块实现通信。
在Android系统中,加载进内核空间的模块就是Binder驱动。
内存映射-mmap Binder驱动添加完毕后,就需要开始进程间通信。接下来就需要用到mmap()——内存映射。
mmap用于文件或者其他对象映射进内存,通常用在有物理介质的文件系统上的,比如磁盘之类。
在Binder中,通过mmap将用户空间内的一块内存区域映射进内存空间,当映射关系建立完毕后,任何一方对内存区域的改动都会被反映到另一方。
Binder建立了一个虚拟设备/dev/binder,然后在内核空间创建了一块数据接收的缓冲区,这块数据接收缓冲区与内核缓冲区和接收数据的用户空间建立映射,减少了一次数据拷贝 。
实现原理
Binder驱动在内核空间建立一个数据接收缓存区
接着在内核空间开辟一块内核缓存区,建立起内核缓存区和内核数据接收缓存区之间的映射关系,以及数据接收缓存区和用户空间的映射关系
发送方进程通过系统调用copy_from_user将数据复制到内核缓存区,由于各自之间存在映射,等价于直接把数据传递到了接收进程。
Binder优势
性能
Linux上的通信方式例如管道、Socket都需要复制两次数据。而Binder只要一次
拷贝两次过程:发送方数据通过系统调用copy_from_user拷贝到内核缓存区,再由内核缓存区调用系统调用copy_to_user拷贝至接收方。
Binder执行过程:在内核中建立数据接收缓存区,发送方数据通过系统调用copy_from_user拷贝到内核缓存区,此时内核缓存区已与数据接收缓存区和接收进程数据缓存区建立映射,相当于发送方的数据直接到接收方。
安全性
传统的Linux通信是不包含通信双方的身份验证,Binder自带身份验证,提高了安全性。
Binder权限验证
稳定性
Binder基于CS架构,Client的需求都交与Server去完成,职责明确。
Binder通信模型
Client
客户端进程
Client负责向Service Mananger查询所需Service,并且获得一个Binder代理对象,再通过Binder代理对象向Server发起请求
Server
服务端进程
Server进程启动时,会通过Binder驱动注册自身的服务到Service Manager中,并且启动一个Binder线程池,用来接收Client的请求。
Service Manager
服务的管理者,指代的是Native层的ServiceManager,是整个 Binder通信机制的 大管家,也是Android进程间通信的守护进程。
主要有以下功能
Service通过Binder驱动向ServiceManager注册Binder,表示可以对外提供服务。
Client通过Binder驱动从ServiceManager获取Binder的引用。
Service Manager就是一个进程,内部维护了一张表,维护了名字+Binder实体的引用。
Binder完整定义 在不同语境下,Binder有不同含义:
机制层:Android进程间通信机制。
Server层:服务端提供能力的本地Binder实体。
Client层:服务端实体在客户端的代理引用(由驱动转换得到)。
传输层:可跨进程传输的对象能力抽象。
启动 Service Manager进程是在开机时启动的
init进程解析servicemanager.rc之后,找到对应可执行程序/system/bin/servicemanager
继续执行到service_manager.c的main()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 int main (int argc, char ** argv) { struct binder_state *bs ; union selinux_callback cb ; char *driver; if (argc > 1 ) { driver = argv[1 ]; } else { driver = "/dev/binder" ; } bs = binder_open(driver, 128 *1024 ); if (binder_become_context_manager(bs)) { ALOGE("cannot become context manager (%s)\n" , strerror(errno)); return -1 ; } #ifdef VENDORSERVICEMANAGER sehandle = selinux_android_vendor_service_context_handle();#else sehandle = selinux_android_service_context_handle();#endif selinux_status_open(true ); binder_loop(bs, svcmgr_handler); return 0 ; }
binder_open()
打开设备驱动,位置为/dev/binder
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 struct binder_state *binder_open (const char * driver, size_t mapsize) { struct binder_state *bs ; struct binder_version vers ; bs = malloc (sizeof (*bs)); if (!bs) { errno = ENOMEM; return NULL ; } bs->fd = open(driver, O_RDWR | O_CLOEXEC); bs->mapsize = mapsize; bs->mapped = mmap(NULL , mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0 ); return bs; fail_map: close(bs->fd); fail_open: free (bs); return NULL ; }
bidner_open()总共执行了三步:
open()打开/dev/binder设备节点,最终调用到内核中的binder驱动,同样执行到binder_open(),创建了binder_proc,再放入binder_procs中
调用mmap()进行内存映射,映射大小为128k,主要在binder驱动创建Binder_buffer对象
返回binder_state,记录着如下变量:
fd:打开了/dev/binder的文件描述符
mapsize:内存映射大小
mapped:内存映射地址
binder_become_context_manager()
注册成为大管家。
1 2 3 4 int binder_become_context_manager (struct binder_state *bs) { return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0 ); }
通过ioctl向binder驱动发出BINDER_SET_CONTEXT_MGR请求,成为上下文的管理者。
**向Binder驱动注册,它的handle句柄固定为0.**这个binder的引用固定为0。
一个Server若要向Service Manager注册自己的Binder就必需通过0这个引用号和Service Manager的Binder通信。所有需要注册自己的Server对于Service Manager来说都是Client
binder_loop()
不断循环,等待客户请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 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 )); for (;;) { bwr.read_size = sizeof (readbuf); bwr.read_consumed = 0 ; bwr.read_buffer = (uintptr_t ) readbuf; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); res = binder_parse(bs, 0 , (uintptr_t ) readbuf, bwr.read_consumed, func); } }
Service Manager通过binder_write()向binder驱动发送BC_ENTER_LOOPER协议,然后Service Manager进入循环状态。开启for循环,接着通过ioctl()发送BINDER_WRITE_READ请求到Binder驱动,使Service Manager进入内核态,开始等待Client发起请求。未收到请求时,处于等待状态。收到请求后调用binder_parse()解析接收到的请求并切换到用户态。
BINDER_WRITE_READ:向Binder驱动进行读取或写入操作,参数分为两部分write_size和read_size
write_size不为空,取出write_buffer的数据写入到Binder里。
read_size不为空,Binder写数据到read_buffer。read_buffer没有数据,就处于等待状态。
binder_write()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 int binder_write (struct binder_state *bs, void *data, size_t len) { struct binder_write_read bwr ; int res; bwr.write_size = len; bwr.write_consumed = 0 ; bwr.write_buffer = (uintptr_t ) data; bwr.read_size = 0 ; bwr.read_consumed = 0 ; bwr.read_buffer = 0 ; res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); if (res < 0 ) { fprintf (stderr ,"binder_write: ioctl failed (%s)\n" , strerror(errno)); } return res; }
binder_write()实质调用ioctl(),负责的是向Binder驱动写入数据。除了BC_ENTER_LOOP,还有其他类型的命令(以BC_开头)
BC可以理解为向Binder写入数据 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 enum binder_driver_command_protocol { BC_TRANSACTION = _IOW('c' , 0 , struct binder_transaction_data), BC_REPLY = _IOW('c' , 1 , struct binder_transaction_data), BC_ACQUIRE_RESULT = _IOW('c' , 2 , __s32), BC_FREE_BUFFER = _IOW('c' , 3 , binder_uintptr_t ), BC_INCREFS = _IOW('c' , 4 , __u32), BC_ACQUIRE = _IOW('c' , 5 , __u32), BC_RELEASE = _IOW('c' , 6 , __u32), BC_DECREFS = _IOW('c' , 7 , __u32), BC_INCREFS_DONE = _IOW('c' , 8 , struct binder_ptr_cookie), BC_ACQUIRE_DONE = _IOW('c' , 9 , struct binder_ptr_cookie), BC_ATTEMPT_ACQUIRE = _IOW('c' , 10 , struct binder_pri_desc), BC_REGISTER_LOOPER = _IO('c' , 11 ), BC_ENTER_LOOPER = _IO('c' , 12 ), BC_EXIT_LOOPER = _IO('c' , 13 ), BC_REQUEST_DEATH_NOTIFICATION = _IOW('c' , 14 , struct binder_handle_cookie), BC_CLEAR_DEATH_NOTIFICATION = _IOW('c' , 15 , struct binder_handle_cookie), BC_DEAD_BINDER_DONE = _IOW('c' , 16 , binder_uintptr_t ), BC_TRANSACTION_SG = _IOW('c' , 17 , struct binder_transaction_data_sg), BC_REPLY_SG = _IOW('c' , 18 , struct binder_transaction_data_sg), };
其中和linkToDeath直接相关的是三条命令:
BC_REQUEST_DEATH_NOTIFICATION:向驱动注册死亡通知。
BC_CLEAR_DEATH_NOTIFICATION:取消死亡通知。
BC_DEAD_BINDER_DONE:用户态处理完死亡回调后,回写完成确认。
linkToDeath在用户态是一次API调用,在驱动侧本质是“注册一条死亡监听关系”。
binder_parse()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 int binder_parse (struct binder_state *bs, struct binder_io *bio, uintptr_t ptr, size_t size, binder_handler func) { int r = 1 ; uintptr_t end = ptr + (uintptr_t ) size; while (ptr < end) { switch (cmd) { ... case BR_TRANSACTION: { struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; if ((end - ptr) < sizeof (*txn)) { ALOGE("parse: txn too small!\n" ); return -1 ; } binder_dump_txn(txn); if (func) { unsigned rdata[256 /4 ]; struct binder_io msg ; struct binder_io reply ; int res; bio_init(&reply, rdata, sizeof (rdata), 4 ); bio_init_from_txn(&msg, txn); res = func(bs, txn, &msg, &reply); if (txn->flags & TF_ONE_WAY) { binder_free_buffer(bs, txn->data.ptr.buffer); } else { binder_send_reply(bs, &reply, txn->data.ptr.buffer, res); } } ptr += sizeof (*txn); break ; } case BR_REPLY: { struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; if ((end - ptr) < sizeof (*txn)) { ALOGE("parse: reply too small!\n" ); return -1 ; } binder_dump_txn(txn); if (bio) { bio_init_from_txn(bio, txn); bio = 0 ; } else { } ptr += sizeof (*txn); r = 0 ; break ; } case BR_DEAD_BINDER: { struct binder_death *death = (struct binder_death *)(uintptr_t ) *(binder_uintptr_t *)ptr; ptr += sizeof (binder_uintptr_t ); death->func(bs, death->ptr); break ; } ... } return r; }
binder_parse()负责解析read_buffer读取到的数据。
binder_parse()主要就是解析BR_开头的指令,上面重要的就是BR_TRANSACTION和BR_REPLY。除此之外还有其他的BR_指令
BR可以理解为从Binder读取数据 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 enum binder_driver_return_protocol { BR_ERROR = _IOR('r' , 0 , __s32), BR_OK = _IO('r' , 1 ), BR_TRANSACTION = _IOR('r' , 2 , struct binder_transaction_data), BR_REPLY = _IOR('r' , 3 , struct binder_transaction_data), BR_ACQUIRE_RESULT = _IOR('r' , 4 , __s32), BR_DEAD_REPLY = _IO('r' , 5 ), BR_TRANSACTION_COMPLETE = _IO('r' , 6 ), BR_INCREFS = _IOR('r' , 7 , struct binder_ptr_cookie), BR_ACQUIRE = _IOR('r' , 8 , struct binder_ptr_cookie), BR_RELEASE = _IOR('r' , 9 , struct binder_ptr_cookie), BR_DECREFS = _IOR('r' , 10 , struct binder_ptr_cookie), BR_ATTEMPT_ACQUIRE = _IOR('r' , 11 , struct binder_pri_ptr_cookie), BR_NOOP = _IO('r' , 12 ), BR_SPAWN_LOOPER = _IO('r' , 13 ), BR_FINISHED = _IO('r' , 14 ), BR_DEAD_BINDER = _IOR('r' , 15 , binder_uintptr_t ), BR_CLEAR_DEATH_NOTIFICATION_DONE = _IOR('r' , 16 , binder_uintptr_t ), BR_FAILED_REPLY = _IO('r' , 17 ), };
BR_DEAD_BINDER就是linkToDeath对应的关键返回信号:
当远端Binder对象/进程失效时,驱动把BR_DEAD_BINDER投递给持有该引用的进程。
用户态解析到该命令后,会执行已注册的死亡回调(DeathRecipient.binderDied())。
简化链路:
1 2 3 4 5 6 linkToDeath() -> BC_REQUEST_DEATH_NOTIFICATION remote binder dies -> BR_DEAD_BINDER -> binderDied() -> BC_DEAD_BINDER_DONE
其中BR_TRANSACTION需要进行特殊处理,实现对外提供服务功能。例如提供获取服务、注册服务功能。后面会简单的讲解
当binder_parse()收到BR_TRANSACTION之后,就会执行到svcmgr_handler()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 int svcmgr_handler (struct binder_state *bs, struct binder_transaction_data *txn, struct binder_io *msg, struct binder_io *reply) { struct svcinfo *si ; uint16_t *s; size_t len; uint32_t handle; uint32_t strict_policy; ... switch (txn->code) { case SVC_MGR_GET_SERVICE: case SVC_MGR_CHECK_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL ) { return -1 ; } handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid); if (!handle) break ; bio_put_ref(reply, handle); return 0 ; case SVC_MGR_ADD_SERVICE: s = bio_get_string16(msg, &len); if (s == NULL ) { return -1 ; } handle = bio_get_ref(msg); allow_isolated = bio_get_uint32(msg) ? 1 : 0 ; dumpsys_priority = bio_get_uint32(msg); if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority, txn->sender_pid)) return -1 ; break ; case SVC_MGR_LIST_SERVICES: { uint32_t n = bio_get_uint32(msg); uint32_t req_dumpsys_priority = bio_get_uint32(msg); if (!svc_can_list(txn->sender_pid, txn->sender_euid)) { ALOGE("list_service() uid=%d - PERMISSION DENIED\n" , txn->sender_euid); return -1 ; } si = svclist; while (si) { if (si->dumpsys_priority & req_dumpsys_priority) { if (n == 0 ) break ; n--; } si = si->next; } if (si) { bio_put_string16(reply, si->name); return 0 ; } return -1 ; } default : ALOGE("unknown code %d\n" , txn->code); return -1 ; } bio_put_uint32(reply, 0 ); return 0 ; }
svcmgr_handler()主要提供服务相关的功能,根据不同的code有对应的功能:
SVG_MGR_GET_SERVICE,SVC_MGR_CHECK_SERVICE:获取服务
SVC_MGR_ADD_SERVICE:注册服务
SVC_MGR_LIST_SERVICES:列举所有服务
Service Manager存储的是一个svclist的一个链表结构,里面存储的对象为svcinfo
1 2 3 4 5 6 7 8 9 10 struct svcinfo { struct svcinfo *next ; uint32_t handle; struct binder_death death ; int allow_isolated; uint32_t dumpsys_priority; size_t len; uint16_t name[0 ]; };
总结 ServiceManager启动过程主要执行以下几步:
binder_open():打开驱动,/dev/binder
binder_become_context_manager():成为管家,并准备进入循环
binder_loop():开启循环,等待新消息并处理
获取Service Manager代理对象 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 [[clang::no_destroy]] static sp<IServiceManager> gDefaultServiceManager;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; }
gDefaultServiceManager的创建过程主要分为以下几步:
ProcessState::self()
用于创建ProcessState对象,每个进程有且只有一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 #define DEFAULT_BINDER_VM_SIZE ((1 * 1024 * 1024) - sysconf(_SC_PAGE_SIZE) * 2) #define DEFAULT_MAX_BINDER_THREADS 15 sp<ProcessState> ProcessState::self () { Mutex::Autolock _l(gProcessMutex); if (gProcess != NULL ) { return gProcess; } gProcess = new ProcessState (DEFAULT_BINDER_VM_SIZE); 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 ) , mThreadPoolStarted (false ) , mThreadPoolSeq (1 ) , mCallRestriction (CallRestriction::NONE) { if (mDriverFD >= 0 ) { mVMStart = mmap (nullptr , BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0 ); if (mVMStart == MAP_FAILED) { ALOGE ("Using %s failed: unable to mmap transaction memory.\n" , mDriverName.c_str ()); close (mDriverFD); mDriverFD = -1 ; mDriverName.clear (); } } }static int open_driver (const char *driver) { int fd = open (driver, O_RDWR | O_CLOEXEC); if (fd >= 0 ) { int vers = 0 ; status_t result = ioctl (fd, BINDER_VERSION, &vers); if (result == -1 ) { ALOGE ("Binder ioctl to obtain version failed: %s" , strerror (errno)); close (fd); fd = -1 ; } size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; result = ioctl (fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1 ) { ALOGE ("Binder ioctl to set max threads failed: %s" , strerror (errno)); } } else { ALOGW ("Opening '%s' failed: %s\n" , driver, strerror (errno)); } return fd; }
ProcessState可以保证每个进程打开binder设备一次,通过mDriverFd记录binder驱动的fd,可以用于后续访问Binder设备。
ProcessState的初始化过程主要执行了以下几步:
1⃣️open_driver():打开binder驱动设备,并且验证binder驱动版本是否一致。
2⃣️ioctl():为binder驱动设置最大线程数,默认为15。加上主binder线程,所以最多为16个。
3⃣️mmap():在binder驱动中分配一块1016KB大小的空间,用于处理事务。
getContextObject()
主要为了获取BpBinder对象
1 2 3 4 5 6 7 sp<IBinder> ProcessState::getContextObject (const sp<IBinder>& ) { sp<IBinder> context = getStrongProxyForHandle (0 ); return context; }
获取handle==0的IBinder对象,实际就是ServiceManager的BpBinder对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 sp<IBinder> ProcessState::getStrongProxyForHandle (int32_t handle) { sp<IBinder> result; AutoMutex _l(mLock); handle_entry* e = lookupHandleLocked (handle); if (e != nullptr ) { IBinder* b = e->binder; if (b == nullptr || !e->refs->attemptIncWeak (this )) { if (handle == 0 ) { IPCThreadState* ipc = IPCThreadState::self (); CallRestriction originalCallRestriction = ipc->getCallRestriction (); ipc->setCallRestriction (CallRestriction::NONE); Parcel data; status_t status = ipc->transact ( 0 , IBinder::PING_TRANSACTION, data, nullptr , 0 ); ipc->setCallRestriction (originalCallRestriction); if (status == DEAD_OBJECT) return nullptr ; } b = BpBinder::create (handle); e->binder = b; if (b) e->refs = b->getWeakRefs (); result = b; } else { result.force_set(b); e->refs->decWeak (this ); } } return result; }
getContextObj()主要执行了以下几步:
getStrongProxyforHandle():获取handle==0的IBinder对象
IPCThreadState::self()->transact():向Binder驱动传递对象,判断Binder驱动是否就绪
BpBinder::create():创建ServiceManager的BpBinder对象
interface_cast()
创建BpServiceManager对象
1 2 3 4 5 6 inline sp<INTERFACE> interface_cast (const sp<IBinder>& obj) { return INTERFACE::asInterface(obj); }
interface_cast()是一个模板函数,经过操作后最后得到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 const android::String16 IServiceManager::descriptor (“android.os.IServiceManager”) ;const android::String16& IServiceManager::getInterfaceDescriptor () const { return IServiceManager::descriptor; } android::sp<IServiceManager> IServiceManager::asInterface (const android::sp<android::IBinder>& obj) { android::sp<IServiceManager> intr; if (obj != NULL ) { intr = static_cast <IServiceManager *>( obj->queryLocalInterface (IServiceManager::descriptor).get ()); if (intr == NULL ) { intr = new BpServiceManager (obj); } } return intr; }
此时初始化BpServiceManager对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 explicit BpServiceManager (const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl) { }inline BpRefBase<IServiceManager>::BpInterface (const sp<IBinder>& remote) :BpRefBase (remote) { } BpRefBase::BpRefBase (const sp<IBinder>& o) : mRemote (o.get ()), mRefs (NULL ), mState (0 ) { extendObjectLifetime (OBJECT_LIFETIME_WEAK); if (mRemote) { mRemote->incStrong (this ); mRefs = mRemote->createWeak (this ); } }
BpServiceManager初始化过程中,依次调用BpRefBase,BpRefBase,BpServiceManager的构造函数,赋予BpRefBase的mRemote的值为BpBinder(0)。
最后可知defaultServiceManager 等价于 new BpServiceManager(new BpBinder(0))
总结
open: 创建binder_proc
BINDER_SET_MAX_THREADS: 设置proc->max_threads
mmap: 创建创建binder_buffer
javaObjectForIBinder()
主要为了获取BinderProxy对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 jobject javaObjectForIBinder (JNIEnv* env, const sp<IBinder>& val) { BinderProxyNativeData* nativeData = new BinderProxyNativeData (); nativeData->mOrgue = new DeathRecipientList; nativeData->mObject = val; jobject object = env->CallStaticObjectMethod (gBinderProxyOffsets.mClass, gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get ()); if (env->ExceptionCheck ()) { return NULL ; } BinderProxyNativeData* actualNativeData = getBPNativeData (env, object); if (actualNativeData == nativeData) { uint32_t numProxies = gNumProxies.fetch_add (1 , std::memory_order_relaxed); uint32_t numLastWarned = gProxiesWarned.load (std::memory_order_relaxed); if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) { if (gProxiesWarned.compare_exchange_strong (numLastWarned, numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) { ALOGW ("Unexpectedly many live BinderProxies: %d\n" , numProxies); } } } else { delete nativeData; } return object; }
执行完成后BinderInternal.getContextObject()得到BinderProxy
继续调用到ServiceManagerNative.asInterface()
1 2 3 4 5 6 7 8 9 public static IServiceManager asInterface (IBinder obj) { if (obj == null ) { return null ; } return new ServiceManagerProxy (obj); }
等价于最后生成的代理对象就是ServiceManagerProxy。
Service Manager 注册服务
Service 向 Service Manager 注册服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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); } } private static IServiceManager getIServiceManager () { if (sServiceManager != null ) { return sServiceManager; } sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); return sServiceManager; }
sServiceManager最后得到的就是上节中的BpServiceManager对象
1 2 3 4 5 6 7 8 9 10 11 12 13 virtual status_t addService (const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority) { Parcel data, reply; data.writeInterfaceToken (IServiceManager::getInterfaceDescriptor ()); data.writeString16 (name); data.writeStrongBinder (service); data.writeInt32 (allowIsolated ? 1 : 0 ); data.writeInt32 (dumpsysPriority); status_t err = remote ()->transact (ADD_SERVICE_TRANSACTION, data, &reply); return err == NO_ERROR ? reply.readExceptionCode () : err; }
addService()具体就是向Service Manager注册服务,将相关数据封装到Parcel对象。
接下来通过BpBinder调用transact()传输数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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; }
IPCThreadState->transact
初始化IPCThreadState之后,向Binder驱动发送数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 IPCThreadState* IPCThreadState::self () { if (gHaveTLS) { restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific (k); if (st) return st; return new IPCThreadState; } pthread_mutex_lock (&gTLSMutex); if (!gHaveTLS) { int key_create_value = pthread_key_create (&gTLS, threadDestructor); if (key_create_value != 0 ) { pthread_mutex_unlock (&gTLSMutex); ALOGW ("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n" , strerror (key_create_value)); return NULL ; } gHaveTLS = true ; } pthread_mutex_unlock (&gTLSMutex); goto restart; } IPCThreadState::IPCThreadState () : mProcess (ProcessState::self ()), mStrictModePolicy (0 ), mLastTransactionBinderFlags (0 ) { pthread_setspecific (gTLS, this ); clearCaller (); mIn.setDataCapacity (256 ); mOut.setDataCapacity (256 ); }void IPCThreadState::clearCaller () { mCallingPid = getpid (); mCallingUid = getuid (); }
每个线程都有一个IPCThreadState,内部包含如下参数:
mIn:接收来自Binder设备的数据
mOut:存储发送Binder设备的数据
mProcess:当前进程的ProcessState
mCallingPid:当前进程的Pid
mCallingUid:当前进程的Uid
接下来执行transact()传输数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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 ); if ((flags & TF_ONE_WAY) == 0 ) { if (reply) { err = waitForResponse (reply); } else { Parcel fakeReply; err = waitForResponse (&fakeReply); } 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; }
transact()主要过程:
执行writeTransactionData()向Parcel中的mOut写入数据
写入的数据主要是BC_TRANSACTION协议以及binder_transaction_data数据。
执行waitForResponse()循环执行,等待应答消息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 status_t IPCThreadState::waitForResponse (Parcel *reply, status_t *acquireResult) { int32_t cmd; int32_t err; while (1 ) { if ((err=talkWithDriver ()) < NO_ERROR) break ; ... if (mIn.dataAvail () == 0 ) continue ; cmd = mIn.readInt32 (); switch (cmd) { case BR_TRANSACTION_COMPLETE: if (!reply && !acquireResult) goto finish; break ; case BR_DEAD_REPLY: ... case BR_FAILED_REPLY: ... case BR_ACQUIRE_RESULT: ... case BR_REPLY: ... goto finish; default : err = executeCommand (cmd); if (err != NO_ERROR) goto finish; break ; } } ... return err; }
IPCThreadState.talkWithDrive()
负责与 Binder驱动进行通信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 status_t IPCThreadState::talkWithDriver (bool doReceive) { ... binder_write_read bwr; 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 (); if (doReceive && needRead) { bwr.read_size = mIn.dataCapacity (); bwr.read_buffer = (uintptr_t )mIn.data (); } 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 (ioctl (mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0 ) err = NO_ERROR; ... } while (err == -EINTR); ... return err; }
binder_ioctl()
与Binder驱动进行通信
binder_ioctl()过程解析ioctl参数BINDER_WRITE_READ,则调用binder_ioctl_write_read()方法;
binder_ioctl_write_read()过程将用户空间binder_write_read结构体拷贝到内核空间, 写缓存中存在数据,则调用binder_thread_write()方法;
binder_thread_write()过程解析到传输协议为BC_TRANSACTION,则调用binder_transaction()方法;
binder_transaction()过程将用户空间binder_transaction_data结构体拷贝到内核空间,内核创建一个binder_transaction结构体,
binder_parse()
解析Binder驱动返回的数据
前面讲到Service Manager的启动时,就介绍到在binder_loop()中负责接收消息,收到消息后通过binder_parse进行解析。
收到的指令为``
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 case BR_TRANSACTION: { struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr; if ((end - ptr) < sizeof (*txn)) { ALOGE ("parse: txn too small!\n" ); return -1 ; } binder_dump_txn (txn); if (func) { unsigned rdata[256 /4 ]; struct binder_io msg; struct binder_io reply; int res; bio_init (&reply, rdata, sizeof (rdata), 4 ); bio_init_from_txn (&msg, txn); res = func (bs, txn, &msg, &reply); if (txn->flags & TF_ONE_WAY) { binder_free_buffer (bs, txn->data.ptr.buffer); } else { binder_send_reply (bs, &reply, txn->data.ptr.buffer, res); } } ptr += sizeof (*txn); break ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 int svcmgr_handler (struct binder_state *bs, struct binder_transaction_data *txn, struct binder_io *msg, struct binder_io *reply) { ... case SVC_MGR_ADD_SERVICE: s = bio_get_string16 (msg, &len); if (s == NULL ) { return -1 ; } handle = bio_get_ref (msg); allow_isolated = bio_get_uint32 (msg) ? 1 : 0 ; dumpsys_priority = bio_get_uint32 (msg); if (do_add_service (bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority, txn->sender_pid)) return -1 ; break ; }
do_add_service()
向Service Manager添加服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 int do_add_service (struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle, uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) { struct svcinfo *si; if (!handle || (len == 0 ) || (len > 127 )) return -1 ; if (!svc_can_register (s, len, spid, uid)) { ALOGE ("add_service('%s',%x) uid=%d - PERMISSION DENIED\n" , str8 (s, len), handle, uid); return -1 ; } si = find_svc (s, len); if (si) { if (si->handle) { ALOGE ("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n" , str8 (s, len), handle, uid); svcinfo_death (bs, si); } si->handle = handle; } else { si = malloc (sizeof (*si) + (len + 1 ) * sizeof (uint16_t )); if (!si) { ALOGE ("add_service('%s',%x) uid=%d - OUT OF MEMORY\n" , str8 (s, len), handle, uid); return -1 ; } si->handle = handle; si->len = len; memcpy (si->name, s, (len + 1 ) * sizeof (uint16_t )); si->name[len] = '\0' ; si->death.func = (void *) svcinfo_death; si->death.ptr = si; si->allow_isolated = allow_isolated; si->dumpsys_priority = dumpsys_priority; si->next = svclist; svclist = si; } binder_acquire (bs, handle); binder_link_to_death (bs, handle, &si->death); return 0 ; }
这里的binder_link_to_death()说明:
ServiceManager在“服务注册”阶段就挂上死亡监听。
一旦该服务进程死亡,svcinfo_death会被回调,ServiceManager可以及时清理svclist中的无效服务项。
这样可以避免客户端持续拿到失效句柄,属于系统服务治理的关键机制。
Java 注册服务 上面讲的都是Native层的相关过程,接下来简单分析下Java层 如何注册服务
一般都是通过ServiceManager.addService()去在Service Manager注册服务,这一类方式主要面向的是系统服务。
系统服务相关的分析完毕后,会简单介绍开发者自定义Service的注册过程。
注册服务的操作都是由Server执行的,所以下面的流程基本都是在Server端操作的。
系统服务(SystemServer) 注册服务
系统服务:一般指的是由SystemServer进程启动的服务,例如InputManagerService、WindowManagerService
1 2 3 4 inputManager = new InputManagerService (context); ServiceManager.addService(Context.INPUT_SERVICE, inputManager, false , DUMP_FLAG_PRIORITY_CRITICAL);
都是通过ServiceManager.addService()进行注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 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); } } private static IServiceManager getIServiceManager () { if (sServiceManager != null ) { return sServiceManager; } sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); return sServiceManager; } 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); }
前面有讲到具体的处理过程,这边直接贴一个结论:
sServiceManager最后得到的是ServiceManagerProxy对象,且IBinder对象为BinderProxy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy (IBinder remote) { mRemote = remote; } 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); data.writeInt(allowIsolated ? 1 : 0 ); data.writeInt(dumpPriority); mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0 ); reply.recycle(); data.recycle(); }
writeStrongBinder()
将Binder实体写入Parcel中,就可以传递到对端。
1 2 3 4 public final void writeStrongBinder (IBinder val) { nativeWriteStrongBinder(mNativePtr, val); }
1 2 3 4 5 6 7 8 9 10 11 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); } } }
ibinderForJavaObject()
将Binder(Java)转化成Binder(c++)对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 sp<IBinder> ibinderForJavaObject (JNIEnv* env, jobject obj) { if (obj == NULL ) return NULL ; if (env->IsInstanceOf (obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField (obj, gBinderOffsets.mObject); return jbh->get (env, obj); } if (env->IsInstanceOf (obj, gBinderProxyOffsets.mClass)) { return getBPNativeData (env, obj)->mObject; } ALOGW ("ibinderForJavaObject: %p is not a Binder object" , obj); return NULL ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 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; }
iBinderForJavaObject()最后转换出一个JavaBBinder对象
parcel->writeStrongBinder()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 status_t Parcel::writeStrongBinder (const sp<IBinder>& val) { return flatten_binder (ProcessState::self (), val, this ); }status_t flatten_binder (const sp<ProcessState>& , const sp<IBinder>& binder, Parcel* out) { flat_binder_object obj; if (IPCThreadState::self ()->backgroundSchedulingDisabled ()) { obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS; } else { obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS; } if (binder != NULL ) { IBinder *local = binder->localBinder (); if (!local) { BpBinder *proxy = binder->remoteBinder (); if (proxy == NULL ) { ALOGE ("null proxy" ); } const int32_t handle = proxy ? proxy->handle () : 0 ; obj.hdr.type = BINDER_TYPE_HANDLE; obj.binder = 0 ; obj.handle = handle; obj.cookie = 0 ; } else { obj.hdr.type = BINDER_TYPE_BINDER; obj.binder = reinterpret_cast <uintptr_t >(local->getWeakRefs ()); obj.cookie = reinterpret_cast <uintptr_t >(local); } } else { obj.hdr.type = BINDER_TYPE_BINDER; obj.binder = 0 ; obj.cookie = 0 ; } return finish_flatten_binder (binder, obj, out); }
writeStrongBinder()负责转换IBinder对象到flat_bidner_object
mRemote.transact(ADD_SERVICE_TRANSACTION)
通过BinderProxy传输Binder对象到Binder驱动
1 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0 );
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 final class BinderProxy implements IBinder { public boolean transact (int code, Parcel data, Parcel reply, int flags) throws RemoteException { Binder.checkParcel(this , code, data, "Unreasonably large binder buffer" ); try { return transactNative(code, data, reply, flags); } finally { if (tracingEnabled) { Trace.traceEnd(Trace.TRACE_TAG_ALWAYS); } } } } public native boolean transactNative (int code, Parcel data, Parcel reply, int flags) throws RemoteException;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 static jboolean android_os_BinderProxy_transact (JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) { Parcel* data = parcelForJavaObject (env, dataObj); Parcel* reply = parcelForJavaObject (env, replyObj); IBinder* target = getBPNativeData (env, obj)->mObject.get (); status_t err = target->transact (code, *data, reply, flags); signalExceptionForError (env, obj, err, true , data->dataSize ()); return JNI_FALSE; }BinderProxyNativeData* getBPNativeData (JNIEnv* env, jobject obj) { return (BinderProxyNativeData *) env->GetLongField (obj, gBinderProxyOffsets.mNativeData); }struct BinderProxyNativeData { sp<IBinder> mObject; sp<DeathRecipientList> mOrgue; };
继续执行的就是IPCThreadState->transact
总结 ServiceManager.addService()主要执行了以下几步:
Parcel.obtain():构建Native层的Parcel对象
parcel.writeStrongBinder():构造JavaBBinder对象写入到falt_binder_object,准备传到Binder驱动
BpBinder.transact(ADD_SERVICE_TRANSACTION):通过IPCThreadState.talkWithDriver()发送数据到Binder驱动
自定义服务(CustomServer) 注册服务
ServiceManager.addService()主要面向的是系统服务,应用自定义服务是无法通过这种方式注册的。
1 2 3 4 5 6 7 8 9 10 11 12 static int svc_can_register (const uint16_t *name, size_t name_len, pid_t spid, uid_t uid) { const char *perm = "add" ; if (multiuser_get_app_id (uid) >= AID_APP) { return 0 ; } return check_mac_perms_from_lookup (spid, uid, perm, str8 (name, name_len)) ? 1 : 0 ; }
自定义Service被分配到的uid都是大于10000的,当自定义Service执行到的时候,会在这一步被拒绝。
一般情况下通过startService()启动服务,bindService()来绑定服务并与其他Service进行交互。
Service Manager 获取服务
Client 向 Service Manager 获取服务
获取服务流程大致与注册服务流程一致
只是最后执行的do_find_service()方法,从Service Manager获取注册的服务。
Java 获取服务
一般通过ServiceManager.getService()获取服务。
由于ServiceManager无法被直接调用,就需要通过底层进行调用。
Context#getSystemService
最常用的就是getSystemService
1 2 3 4 5 6 7 8 9 public abstract @Nullable Object getSystemService (@ServiceName @NonNull String name) ; @Override public Object getSystemService (String name) { return SystemServiceRegistry.getSystemService(this , name); }
接下来就切换到SystemServiceRegistry执行SystemService相关流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new HashMap <String, ServiceFetcher<?>>(); static abstract interface ServiceFetcher <T> { T getService (ContextImpl ctx) ; } static { ... registerService(Context.LAYOUT_INFLATER_SERVICE, LayoutInflater.class, new CachedServiceFetcher <LayoutInflater>() { @Override public LayoutInflater createService (ContextImpl ctx) { return new PhoneLayoutInflater (ctx.getOuterContext()); }}); ... registerService(Context.CONNECTIVITY_SERVICE, ConnectivityManager.class, new StaticApplicationContextServiceFetcher <ConnectivityManager>() { @Override public ConnectivityManager createService (Context context) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(Context.CONNECTIVITY_SERVICE); IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); return new ConnectivityManager (context, service); }}); ... registerService(Context.WIFI_P2P_SERVICE, WifiP2pManager.class, new StaticServiceFetcher <WifiP2pManager>() { @Override public WifiP2pManager createService () throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(Context.WIFI_P2P_SERVICE); IWifiP2pManager service = IWifiP2pManager.Stub.asInterface(b); return new WifiP2pManager (service); }}); ... } private static <T> void registerService (String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); } public static Object getSystemService (ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null ; }
根据上述源码得知ServiceFetcher主要有以下3种实现类
CachedServiceFetcher:进程内部缓存SystemService,切换进程需要重新获取
StaticServiceFetcher:系统内部缓存,所有进程获取的都是同一个SystemService
StaticApplicationContextServiceFetcher:应用内部缓存SystemService,其他应用需要重新获取。
在ServiceFetcher的实现类中,需要实现createService(),其中内部调用到了ServiceManager.getServiceOrThrow()
ServiceManager#getService() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public static IBinder getServiceOrThrow (String name) throws ServiceNotFoundException { final IBinder binder = getService(name); if (binder != null ) { return binder; } else { throw new ServiceNotFoundException (name); } } public static IBinder getService (String name) { try { IBinder service = sCache.get(name); if (service != null ) { return service; } else { return Binder.allowBlocking(rawGetService(name)); } } catch (RemoteException e) { Log.e(TAG, "error in getService" , e); } return null ; } private static IBinder rawGetService (String name) throws RemoteException { final long start = sStatLogger.getTime(); final IBinder binder = getIServiceManager().getService(name); ... }
getIServiceManager()最后指向的就是ServiceManagerProxy
1 2 3 4 5 6 7 8 9 10 11 12 13 public IBinder getService (String name) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0 ); IBinder binder = reply.readStrongBinder(); reply.recycle(); data.recycle(); return binder; }
mRemote.transact(GET_SERVICE_TRANSACTION)通过IPCThreadState.talkWithDriver()发送数据GET_SERVICE_TRANSACTION到Binder驱动
readStrongBinder()基本就是writeStrongBinder()的逆向过程
1 2 3 4 5 6 7 8 9 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 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 sp<IBinder> Parcel::readStrongBinder () const { sp<IBinder> val; readNullableStrongBinder (&val); return val; }status_t Parcel::readNullableStrongBinder (sp<IBinder>* val) const { return unflattenBinder (val); }status_t Parcel::unflattenBinder (sp<IBinder>* out) const { const flat_binder_object* flat = readObject (false ); if (flat) { switch (flat->hdr.type) { case BINDER_TYPE_BINDER: { sp<IBinder> binder = reinterpret_cast <IBinder*>(flat->cookie); return finishUnflattenBinder (binder, out); } case BINDER_TYPE_HANDLE: { sp<IBinder> binder = ProcessState::self ()->getStrongProxyForHandle (flat->handle); return finishUnflattenBinder (binder, out); } } } return BAD_TYPE; }
从flat_binder_obj读取得到IBinder对象,实质就是BpBinder对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 jobject javaObjectForIBinder (JNIEnv* env, const sp<IBinder>& val) { if (val == NULL ) return NULL ; if (val->checkSubclass (&gBinderOffsets)) { jobject object = static_cast <JavaBBinder*>(val.get ())->object (); LOGDEATH ("objectForBinder %p: it's our own %p!\n" , val.get (), object); return object; } AutoMutex _l(gProxyLock); BinderProxyNativeData* nativeData = gNativeDataCache; if (nativeData == nullptr ) { nativeData = new BinderProxyNativeData (); } jobject object = env->CallStaticObjectMethod (gBinderProxyOffsets.mClass, gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get ()); if (env->ExceptionCheck ()) { gNativeDataCache = nullptr ; return NULL ; } BinderProxyNativeData* actualNativeData = getBPNativeData (env, object); if (actualNativeData == nativeData) { nativeData->mOrgue = new DeathRecipientList; nativeData->mObject = val; gNativeDataCache = nullptr ; ++gNumProxies; if (gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) { ALOGW ("Unexpectedly many live BinderProxies: %d\n" , gNumProxies); gProxiesWarned = gNumProxies; } } else { gNativeDataCache = nativeData; } return object; }
经过javaObjectForIBinder()之后转换BpBinder对象到BinderProxy对象.
nativeData->mOrgue = new DeathRecipientList用于保存Java层死亡回调列表:
App侧调用linkToDeath注册DeathRecipient,最终会挂到这个列表。
远端死亡后,框架会遍历列表分发binderDied()。
正常解绑时应unlinkToDeath,避免监听器泄漏和重复回调。
通过ServiceManager.getService()最后Client持有的就是BinderProxy对象。
Binder驱动 下面源码分析基于android-goldfish-4.4-dev内核版本
Android专用,主要以misc设备进行注册,节点是/dev/binder,直接操作设备内存。
Binder驱动源码位于内核,具体代码路径位于/drivers/android/binder.c
加载过程 Binder初始化-binder_init()
注册misc设备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 static int __init binder_init (void ) { int ret; char * device_name, * device_names; struct binder_device * device ; struct hlist_node * tmp ; binder_alloc_shrinker_init(); atomic_set (& binder_transaction_log.cur, ~0U ); atomic_set (& binder_transaction_log_failed.cur, ~0U ); binder_deferred_workqueue = create_singlethread_workqueue("binder" ); if (!binder_deferred_workqueue) return -ENOMEM; while ((device_name = strsep(& device_names, "," ))) { ret = init_binder_device(device_name); if (ret) goto err_init_binder_device_failed; } return ret; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 static int __init init_binder_device (const char *name) { int ret; struct binder_device *binder_device ; binder_device->miscdev.fops = &binder_fops; binder_device->miscdev.minor = MISC_DYNAMIC_MINOR; binder_device->miscdev.name = name; binder_device->context.binder_context_mgr_uid = INVALID_UID; binder_device->context.name = name; mutex_init(&binder_device->context.context_mgr_node_lock); ret = misc_register(&binder_device->miscdev); hlist_add_head(&binder_device->hlist, &binder_devices); return ret; }
通过misc_register注册Binder设备,具体配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 miscdev.fops = &binder_fops; miscdev.minor = MISC_DYNAMIC_MINOR; miscdev.name = name static const struct file_operations binder_fops = { .owner = THIS_MODULE, .poll = binder_poll, .unlocked_ioctl = binder_ioctl, .compat_ioctl = binder_ioctl, .mmap = binder_mmap, .open = binder_open, .flush = binder_flush, .release = binder_release, };
打开Binder设备-binder_open()
打开binder驱动设备
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 static int binder_open (struct inode *nodp, struct file *filp) { struct binder_proc *proc; struct binder_device *binder_dev; binder_debug (BINDER_DEBUG_OPEN_CLOSE, "binder_open: %d:%d\n" , current->group_leader->pid, current->pid); proc = kzalloc (sizeof (*proc), GFP_KERNEL); if (proc == NULL ) return -ENOMEM; spin_lock_init (&proc->inner_lock); spin_lock_init (&proc->outer_lock); get_task_struct (current->group_leader); proc->tsk = current->group_leader; INIT_LIST_HEAD (&proc->todo); if (binder_supported_policy (current->policy)) { proc->default_priority.sched_policy = current->policy; proc->default_priority.prio = current->normal_prio; } else { proc->default_priority.sched_policy = SCHED_NORMAL; proc->default_priority.prio = NICE_TO_PRIO (0 ); } binder_dev = container_of (filp->private_data, struct binder_device, miscdev); proc->context = &binder_dev->context; binder_alloc_init (&proc->alloc); binder_stats_created (BINDER_STAT_PROC); proc->pid = current->group_leader->pid; INIT_LIST_HEAD (&proc->delivered_death); INIT_LIST_HEAD (&proc->waiting_threads); filp->private_data = proc; mutex_lock (&binder_procs_lock); hlist_add_head (&proc->proc_node, &binder_procs); mutex_unlock (&binder_procs_lock); return 0 ; }
创建binder_proc对象,并保存当前进程信息,内部结构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 struct binder_proc { struct hlist_node proc_node; struct rb_root threads; struct rb_root nodes; struct rb_root refs_by_desc; struct rb_root refs_by_node; struct list_head waiting_threads; int pid; struct task_struct *tsk; struct hlist_node deferred_work_node; int deferred_work; bool is_dead; struct list_head todo; struct binder_stats stats; struct list_head delivered_death; int max_threads; int requested_threads; int requested_threads_started; int tmp_ref; struct binder_priority default_priority; struct dentry *debugfs_entry; struct binder_alloc alloc; struct binder_context *context; spinlock_t inner_lock; spinlock_t outer_lock; };
Binder内存映射-binder_mmap()
首先申内核申请虚拟地址空间,申请一块与用户虚拟内存(*vma)相同大小的内存; 再申请一个1个page大小的物理内存,再将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间。
从而实现了用户空间和内核空间的buffer同步操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 static int binder_mmap (struct file *filp, struct vm_area_struct *vma) { int ret; struct binder_proc *proc = filp->private_data; const char *failure_string; if ((vma->vm_end - vma->vm_start) > SZ_4M) vma->vm_end = vma->vm_start + SZ_4M; vma->vm_flags = (vma->vm_flags | VM_DONTCOPY) & ~VM_MAYWRITE; vma->vm_ops = &binder_vm_ops; vma->vm_private_data = proc; ret = binder_alloc_mmap_handler(&proc->alloc, vma); return ret; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 int binder_alloc_mmap_handler (struct binder_alloc *alloc, struct vm_area_struct *vma) { mutex_lock(&binder_alloc_mmap_lock); if (alloc->buffer) { ret = -EBUSY; failure_string = "already mapped" ; goto err_already_mapped; } area = get_vm_area(vma->vm_end - vma->vm_start, VM_IOREMAP); ... alloc->pages = kzalloc(sizeof (alloc->pages[0 ]) * ((vma->vm_end - vma->vm_start) / PAGE_SIZE), GFP_KERNEL); if (alloc->pages == NULL ) { ret = -ENOMEM; failure_string = "alloc page array" ; goto err_alloc_pages_failed; } alloc->buffer_size = vma->vm_end - vma->vm_start; buffer = kzalloc(sizeof (*buffer), GFP_KERNEL); if (!buffer) { ret = -ENOMEM; failure_string = "alloc buffer struct" ; goto err_alloc_buf_struct_failed; } buffer->data = alloc->buffer; list_add(&buffer->entry, &alloc->buffers); buffer->free = 1 ; binder_insert_free_buffer(alloc, buffer); alloc->free_async_space = alloc->buffer_size / 2 ; barrier(); alloc->vma = vma; alloc->vma_vm_mm = vma->vm_mm; atomic_inc (&alloc->vma_vm_mm->mm_count); return 0 ; }
当把同一块物理页面同时映射到进程空间和内核空间时,当需要在两者之间传递数据时,只需要其中任意一方把数据拷贝到物理页面,另一方直接读取即可,也就是说,数据的跨进程传递,只需要一次拷贝就可以完成。
Binder内存管理-binder_ioctl()
负责在两个进程间收发IPC 数据和IPC Reply数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 static long binder_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) { ...switch (cmd) { case BINDER_WRITE_READ: ret = binder_ioctl_write_read (filp, cmd, arg, thread); if (ret) goto err; break ; case BINDER_SET_MAX_THREADS: { int max_threads; if (copy_from_user (&max_threads, ubuf, sizeof (max_threads))) { ret = -EINVAL; goto err; } binder_inner_proc_lock (proc); proc->max_threads = max_threads; binder_inner_proc_unlock (proc); break ; } case BINDER_SET_CONTEXT_MGR: ret = binder_ioctl_set_ctx_mgr (filp); if (ret) goto err; break ; } }
binder驱动将业务分为多种不同的命令,再根据具体的命令执行不同的业务。常用命令有以下几种:
BINDER_WRITE_READ :负责收发Binder IPC数据
使用场景:Service Manager通过发送BINDER_WRITE_READ命令向Binder驱动读写数据
BINDER_SET_MAX_THREADS:设置进程最大binder线程个数
使用场景:在ProcessState初始化的时候,会设置当前进程支持的最大个数,默认为15,设置的命令为BINDER_SET_MAX_THREADS
BINDER_SET_CONTEXT_MGR:设置Service Manager为大管家。
使用场景:ServiceManager启动过程中调用binder_become_context_manager()命令为BINDER_SET_CONTEXT_MGR
使用最频繁的就是BINDER_WRITE_READ,下面简单的分析一下流程:
1 2 3 4 5 6 7 8 9 10 11 12 static long binder_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) { ... switch (cmd) { case BINDER_WRITE_READ: ret = binder_ioctl_write_read (filp, cmd, arg, thread); if (ret) goto err; break ; ... }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 static int binder_ioctl_write_read (struct file *filp, unsigned int cmd, unsigned long arg, struct binder_thread *thread) { int ret = 0 ; struct binder_proc *proc = filp->private_data; unsigned int size = _IOC_SIZE(cmd); void __user *ubuf = (void __user *)arg; struct binder_write_read bwr; if (size != sizeof (struct binder_write_read)) { ret = -EINVAL; goto out; } if (copy_from_user (&bwr, ubuf, sizeof (bwr))) { ret = -EFAULT; goto out; } if (bwr.write_size > 0 ) { ret = binder_thread_write (proc, thread, bwr.write_buffer, bwr.write_size, &bwr.write_consumed); trace_binder_write_done (ret); if (ret < 0 ) { bwr.read_consumed = 0 ; if (copy_to_user (ubuf, &bwr, sizeof (bwr))) ret = -EFAULT; goto out; } } if (bwr.read_size > 0 ) { ret = binder_thread_read (proc, thread, bwr.read_buffer, bwr.read_size, &bwr.read_consumed, filp->f_flags & O_NONBLOCK); trace_binder_read_done (ret); binder_inner_proc_lock (proc); if (!binder_worklist_empty_ilocked (&proc->todo)) binder_wakeup_proc_ilocked (proc); binder_inner_proc_unlock (proc); if (ret < 0 ) { if (copy_to_user (ubuf, &bwr, sizeof (bwr))) ret = -EFAULT; goto out; } } if (copy_to_user (ubuf, &bwr, sizeof (bwr))) { ret = -EFAULT; goto out; } out: return ret; }
binder_write_read时内核层定义的结构
1 2 3 4 5 6 7 8 struct binder_write_read { binder_size_t write_size; binder_size_t write_consumed; binder_uintptr_t write_buffer; binder_size_t read_size; binder_size_t read_consumed; binder_uintptr_t read_buffer; };
binder_ioctl_write_read()主要执行以下几步:
通过copy_from_user()拷贝用户空间数据到内核空间
存在write_size > 0,意味着外部有数据传入,需要执行binder_thread_write(),读取外部传入数据
存在read_size > 0,意味着有数据要传出,需要执行binder_thread_read(),写入数据准备传到外部
最后执行copy_to_user()拷贝内核空间数据到用户空间
总结
Binder通信过程
Binder权限验证 进程A通过Binder调用进程B,然后进程B又Binder调用进程C,此时进程C中的IPCThreadState存储的就是进程A的PID和UID。此时假如进程B想调用进程C,就会抛出异常Bad call: specified package com.providers.xxx under uid 10032 but it is really 10001。
Binder的权限验证回导致进程A调用进程B后,进程B调用原进程方法时失败。
上述流程就是Binder权限验证的流程。
在被调用时进程回去检测是否与自身IPCThreadState存储的uid与pid一致,只有一致才会请求成功。否则抛出异常
解决方案 1 2 3 final long origId = Binder.clearCallingIdentity(); Binder.restoreCallingIdentity(origId);
clearCallingIndetity()
在当前线程中重置到来的IPC标识(uid/pid),然后设置mCallingUid和mCallingPid为当前进程的值
restoreCallingIdentity(id)
还原前面存储的初始调用者的mCallingPid和mCallingUid
组件级权限控制(Manifest) 除调用链身份校验外,还可以通过组件权限限制可绑定方:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <permission android:name ="com.example.wxy.permission.checkBook" android:protectionLevel ="normal" /> <uses-permission android:name ="com.example.wxy.permission.checkBook" /> <service android:name =".service.AIDLService" android:exported ="true" > <intent-filter > <action android:name ="com.example.wxy" /> <category android:name ="android.intent.category.DEFAULT" /> </intent-filter > </service >
Binder-AIDL
全称为Android Interface Definition Language——Android接口定义语言。
Messenger是基于AIDL的,不过只能处理串行的消息,存在大量消息需要同时处理时,也只能一个个处理,这时就需要使用AIDL来处理多消息的情况。
AIDL本质就是系统提供的一种快速实现Binder的工具,不一定需要依赖AIDL去实现功能。
AIDL支持的数据类型
基本数据类型:byte、int、long、float、double、boolean,char
String 和 CharSequence
ArrayList,HashMap(包括key,每个元素必须可以被AIDL支持 )
实现了Parcelabe接口的对象 必须要显示Import进来
所有AIDL接口本身也会被调用必须要显示Import进来
定向tag
除了基本数据类型,其他类型的参数必须加上方向 in,out,inout ,用于表示在跨进程通信中的数据流向。
in:表示数据只能由客户端流向服务端。服务端会收到这个对象的完整数据,但在服务端对对象进行修改不会对客户端传递进来的对象造成影响。
out:表示数据只能由服务端传递到客户端。服务端会接受到这个对象的空对象,但在服务端接收到的空对象有任何修改之后客户端会同步发生变化。
inout:表示数据可以在服务端和客户端之间双向流通。服务端会收到这个对象的完整数据,且客户端会同步服务端对该对象的任何改动。
关键类与方法 AIDL文件代码
1 2 3 interface BookManager { int getResult (int a,out List<String> b,inout List<String> c ,in String d) ; }
AIDL文件便已完成后会得到一个Java文件,生成内容主要如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 public interface BookManager extends IInterface { public static abstract class Stub extends Binder implements BookManager { public static BookManager asInterface (IBinder obj) { if ((obj == null )) { return null ; } IInterface iin = obj.queryLocalInterface(DESCRIPTOR); if (((iin != null ) && (iin instanceof BookManager))) { return ((BookManager) iin); } return new Proxy (obj); } @Override public android.os.IBinder asBinder () { return this ; } @Override public boolean onTransact (int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case TRANSACTION_getResult: { data.enforceInterface(descriptor); int _arg0; _arg0 = data.readInt(); java.util.List<java.lang.String> _arg1; _arg1 = new java .util.ArrayList<java.lang.String>(); java.util.List<java.lang.String> _arg2; _arg2 = data.createStringArrayList(); java.lang.String _arg3; _arg3 = data.readString(); int _result = this .getResult(_arg0, _arg1, _arg2, _arg3); reply.writeNoException(); reply.writeInt(_result); reply.writeStringList(_arg1); reply.writeStringList(_arg2); return true ; } } } private static class Proxy implements BookManager { private android.os.IBinder mRemote; Proxy(android.os.IBinder remote) { mRemote = remote; } @Override public android.os.IBinder asBinder () { return mRemote; } @Override public int getResult (int a, java.util.List<java.lang.String> b, java.util.List<java.lang.String> c, java.lang.String d) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); int _result; try { _data.writeInterfaceToken(DESCRIPTOR); _data.writeInt(a); _data.writeStringList(c); _data.writeString(d); mRemote.transact(Stub.TRANSACTION_getResult, _data, _reply, 0 ); _reply.readException(); _result = _reply.readInt(); _reply.readStringList(b); _reply.readStringList(c); } finally { _reply.recycle(); _data.recycle(); } return _result; } static final int TRANSACTION_getResult = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1 ); } public int getResult (int a, List<String> b, List<String> c, String d) throws RemoteException; }
根据上述生成的代码:
类/接口 IInterface
表示Server进程需要具备什么功能,对应的就是Client进程可以调用的方法。
Stub
一个跨进程调用对象,继承自Binder,表示为Server进程的本地Binder对象,需要实现Server进程可以提供的功能。
Proxy
Binder代理对象,位于Client进程,由其发起transcat()与Binder驱动进行通信。
方法 asBinder()
返回当前进程的Binder对象。
对于Client进程:返回远端进程的BinderProxy代理对象
对于Server进程:返回当前进程的IBinder对象
asInterface()
通常用在bindService()之后,继续在onServiceConnected()调用该方法,就可以把IBinder对象转换成IInterface,就可以直接调用对应Server进程的方法。
onTrancast(int code, Parcel data, Parcel reply, int flags)
参数说明:
code:根据code确定Client端请求的方法
data:Client方法请求参数
reply:Server方法返回参数
flags:设置IPC模式。
对应的就是Proxy中各个方法内部调用的mRemote.transcat()传递的参数。
代理机制补充 Client通过ServiceManager拿到Server引用后,得到的通常不是Server端本地实体,而是一个代理对象(Proxy / BinderProxy)。
代理对象与本地对象对外暴露的方法看起来一致,但其核心职责是:
组装参数到Parcel
调用transact()把请求交给Binder驱动
等待并解析返回结果
因此,Binder代理机制的本质是:
本地调用语义 + 跨进程传输实现 的桥接。
//TODO 关系图
根据上述生成代码,可以大致分析出AIDL内部代码的工作机制
Client调用远程Binder对象,然后Client挂起,等待Server响应数据
Binder代理对象将请求发送给Binder驱动
Binder驱动转发请求给Server
Server处理完请求后,返回结果到Binder驱动,再回到Client并唤醒
AIDL实战常见问题
可能产生ANR
客户端同步调用耗时服务端方法,调用线程被挂起。
在onServiceConnected/onServiceDisconnected中执行耗时逻辑。
服务端回调客户端listener时,客户端binder线程池执行耗时任务。
建议:远程调用放在非UI线程,Binder回调中避免重任务。
AIDL解注册失败
跨进程listener经过序列化/反序列化后通常不是同一对象引用,服务端可能无法正确匹配原注册对象。
建议:使用RemoteCallbackList管理远程回调,并确保beginBroadcast()与finishBroadcast()成对使用。
性能损耗较大
高频同步IPC会带来明显开销。可通过“变更通知 + 批量拉取”降低调用频率。
Binder-系统调用 system_call的实现位于内核之中,。
各个地方调用ioctl如何控制可以准确的调用到对应的方法?
通过system_call(),其中第一个参数表示的是对应构造函数的参数个数,第二个就表示可对应要调用的方法
Binder拓展知识 Binder传输数据上限,以及超出会如何?
Binder传输数据的最大限制为1016KB(默认情况下),如果是异步执行,最多只有508KB。
调用mmap映射的大小就为1016KB,如果超出这块区域,Binder驱动就无法处理Binder调用,然后会抛出DeadObjectException异常。
每个进程最大Binder线程数,以及超出会如何?
每个进程最多可以运行16个Binder线程
当所有的16个binder线程都在工作时,就会出现线程饥饿状态。如果此时有新的binder线程请求,就会进入阻塞状态。
oneway的作用异步调用和串行化处理
异步调用:应用向Binder驱动发送数据后不需要挂起线程等待Binder驱动的回复,接收到BR_TRANSACTION_COMPLETE之后就直接结束。
串行化处理:所有oneway方法不会同时执行,Binder驱动会进行串行化处理,保证一个个执行。
oneway都是需要等待BR_TRANSACTION_COMPLETE消息。
不过oneway的请求方式在收到BR_TRANSACTION_COMPLETE消息后,立即返回;
非oneway的请求方式,还需要等到BR_REPLY之后才返回。此时线程就会处于Sleep状态,底层调用的就是wait_event_interruptible()
1 2 3 4 5 interface IXX { oneway void xx () ; }
Binder连接池(BinderPool) 当业务模块变多后,如果每个模块都创建独立Service + AIDL,会增加组件数量与连接治理成本。
BinderPool的核心思路:
统一一个远程Service作为入口。
通过queryBinder(binderCode)按标识返回不同业务Binder。
用一条连接管理多业务能力,降低重复建设成本。
工作原理:
实现步骤(简版):
定义各业务AIDL接口与实现。
定义IBinderPool.aidl。
实现BinderPoolService并在onBind()返回BinderPool。
在queryBinder()中根据binderCode分发。
客户端连接后按需获取目标Binder。
Binder跨进程传输大文件 Intent和Binder事务都存在大小限制,大文件不建议直接走Binder事务。
可选方案:
文件共享(FileProvider)。
分块传输。
共享内存(如ashmem)。
ContentProvider或流式读取。
参考链接 Binder介绍
Binder系列讲解
图解Android - Binder 和 Service
深入理解Binder通信原理及面试问题
Android Binder设计与实现-设计篇
Bidner|内存拷贝的本质和变迁