经过上一篇博客的介绍,相信大家已经对于 binder 机制有了一定的了解,这篇博客将会解读 AMS 注册的代码流程,篇幅会很长,请大家耐心看完!
(以下分析的是 Android 6.0 的源码)
ServiceManager 是如何启动的?
AMS 在启动后会注册到 ServiceManager(之后简称为SM)中
那么 SM 是如何启动的?
SM 是由 init 进程通过解析 init.rc 文件而创建的,其所对应的可执行程序 servicemanager, 所对应的源文件是 service_manager.c,进程名为 servicemanager
启动 SM 的入口函数是 service_manager.c 中的 main
函数
int main(int argc, char **argv)
{
struct binder_state *bs;
// 打开binder驱动,映射 128K 大小的内存空间
bs = binder_open(128*1024);
......
// 把当前进程注册成为 SM
if (binder_become_context_manager(bs))
{
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
......
// 进入 loop 无限循环,监听处理 AMS 端发来的请求
binder_loop(bs, svcmgr_handler);
return 0;
}
binder_open()
// frameworks/native/cmds/servicemanager/binder.c
struct binder_state *binder_open(size_t mapsize)
{
struct binder_state *bs;
struct binder_version vers;
......
// 打开binder驱动,得到文件描述符,通过系统调用到 binder 驱动中的 binder_open 函数
bs->fd = open("/dev/binder", O_RDWR);
......
// 映射内存大小:128K
bs->mapsize = mapsize;
// 通过系统调用到 binder 驱动中的 binder_mmap 函数,
// 在当前进程的用户空间和内核空间之间映射 128K 大小的内存空间
bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
......
return bs;
......
}
这里有个知识点,SM 的跨进程通信数据大小不能超过 128K
因为 SM 中记录的只是所注册服务在 binder 驱动中实体节点的引用(这个后面会介绍到),所以 128K 的大小足够了
binder_become_context_manager()
// frameworks/native/cmds/servicemanager/binder.c
int binder_become_context_manager(struct binder_state *bs)
{
// 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_SET_CONTEXT_MGR
return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}
binder_ioctl()
// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp,
unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
unsigned long arg // arg 就是我们传入的 bwr
){
// 获取 binder 驱动的设备节点
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
......
// 获取 binder 线程
// (当前 pid 此时没有创建过 binder 线程,则创建一个 binder 线程并返回)
// thread->looper = BINDER_LOOPER_STATE_NEED_RETURN
// thread->return_error = BR_OK
// thread->return_error2 = BR_OK
thread = binder_get_thread(proc);
......
switch (cmd)
{
......
case BINDER_SET_CONTEXT_MGR:
ret = binder_ioctl_set_ctx_mgr(filp);
......
break;
......
}
......
return ret;
}
binder_ioctl_set_ctx_mgr()
// kernel/drivers/staging/android/binder.c
static int binder_ioctl_set_ctx_mgr(struct file *filp)
{
// 获取 binder 驱动的设备节点实体,可以通过 filp->private_data 获取
struct binder_proc *proc = filp->private_data;
......
// 保证只创建一次 binder_context_mgr_node,不为null就直接返回
if (context->binder_context_mgr_node)
{
......
goto out;
}
......
// uid 是否有效,当前是无效的
if (uid_valid(context->binder_context_mgr_uid))
{
if (!uid_eq(context->binder_context_mgr_uid, curr_euid))
{
......
goto out;
}
}
else
{
// 设置当前线程的 euid 作为 SM 的 uid
context->binder_context_mgr_uid = curr_euid;
}
// 创建 SM 在 binder 驱动中的 binder 节点实体
context->binder_context_mgr_node = binder_new_node(proc, 0, 0);
......
out:
return ret;
}
binder_new_node()
// kernel/drivers/staging/android/binder.c
static struct binder_node *binder_new_node(
struct binder_proc *proc, // binder 驱动的设备节点实体
binder_uintptr_t ptr,
binder_uintptr_t cookie
){
struct rb_node **p = &proc->nodes.rb_node;
struct rb_node *parent = NULL;
struct binder_node *node;
......
// 给新创建的 binder_node 分配内核空间的内存
node = kzalloc(sizeof(*node), GFP_KERNEL);
......
// 将新创建的 binder_node 添加到设备节点的 binder_node 红黑树中
rb_link_node(&node->rb_node, parent, p);
rb_insert_color(&node->rb_node, &proc->nodes);
......
// 初始化新创建的 binder_node
node->proc = proc;
node->ptr = ptr;
node->cookie = cookie;
node->work.type = BINDER_WORK_NODE;
// 初始化 todo 和 wait 队列
INIT_LIST_HEAD(&node->work.entry);
INIT_LIST_HEAD(&node->async_todo);
......
return node;
}
在 binder_become_context_manager
函数中主要是创建了 SM 在 binder 驱动中的节点实体
binder_loop()
// frameworks/native/cmds/servicemanager/binder.c
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;
// 发送指令 BC_ENTER_LOOPER 给 binder 驱动
binder_write(bs, readbuf, sizeof(uint32_t));
......
}
binder_write()
// frameworks/native/cmds/servicemanager/binder.c
int binder_write(struct binder_state *bs,
void *data, // readbuf 的起始地址
size_t len // readbuf 的长度
){
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;
// 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_WRITE_READ
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
if (res < 0) {
fprintf(stderr,"binder_write: ioctl failed (%s)\n",
strerror(errno));
}
return res;
}
binder_ioctl()
// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp,
unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
unsigned long arg // arg 就是我们传入的 bwr
){
// 获取 binder 驱动的设备节点
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
......
// 获取 binder 线程
// (当前 pid 此时已经创建过 binder 线程,则返回对应的 binder 线程)
// thread->looper = BINDER_LOOPER_STATE_NEED_RETURN
// thread->return_error = BR_OK
// thread->return_error2 = BR_OK
thread = binder_get_thread(proc);
......
switch (cmd)
{
case BINDER_WRITE_READ:
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
......
break;
......
}
......
return ret;
}
binder_get_thread()
static struct binder_thread *binder_get_thread(struct binder_proc *proc)
{
struct binder_thread *thread = NULL;
struct rb_node *parent = NULL;
// binder 线程池的根节点指针
struct rb_node **p = &proc->threads.rb_node;
// 遍历 binder 线程池,查找和当前线程匹配(pid相同)的 binder 线程
while (*p)
{
parent = *p;
// 类型转换(rb_node -> binder_thread)
thread = rb_entry(parent, struct binder_thread, rb_node);
if (current->pid < thread->pid)
p = &(*p)->rb_left;
else if (current->pid > thread->pid)
p = &(*p)->rb_right;
else
// 如果找到了就 break 跳出循环,停止遍历
break;
}
// 如果 binder 线程池中没有记录,就创建新的 binder 线程
if (*p == NULL)
{
thread = kzalloc(sizeof(*thread), GFP_KERNEL);
if (thread == NULL)
return NULL;
binder_stats_created(BINDER_STAT_THREAD);
// 记录 binder 线程所属进程
thread->proc = proc;
// 记录 binder 线程的 pid
thread->pid = current->pid;
// 初始化 binder 线程的 wait 队列
init_waitqueue_head(&thread->wait);
// 初始化 binder 线程的 todo 队列
INIT_LIST_HEAD(&thread->todo);
// 将 binder 线程放入 binder 线程池中
rb_link_node(&thread->rb_node, parent, p);
rb_insert_color(&thread->rb_node, &proc->threads);
thread->looper |= BINDER_LOOPER_STATE_NEED_RETURN;
thread->return_error = BR_OK;
thread->return_error2 = BR_OK;
}
return thread;
}
binder 线程池本质上是一个红黑树的数据结构,binder 线程被转换成 rb_node 类型进行存储
binder_ioctl_write_read()
// kernel/drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread
){
struct binder_proc *proc = filp->private_data;
......
void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;
// 将描述数据的 binder_write_read 结构体(ubuf)从用户空间拷贝到内核空间(bwr)中去
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
......
// 此时 bwr.write_size > 0,if 命中
if (bwr.write_size > 0)
{
// 发送指令给 binder 驱动
ret = binder_thread_write(proc, thread,
bwr.write_buffer,
bwr.write_size,
&bwr.write_consumed);
......
}
// 此时 bwr.read_size = 0,if 不命中
if (bwr.read_size > 0)
{
......
}
......
return ret;
}
binder_thread_write()
// kernel/drivers/staging/android/binder.c
static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, // readbuf 的起始地址
size_t size, // readbuf 的长度
binder_size_t *consumed
){
uint32_t cmd;
struct binder_context *context = proc->context;
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
// 指向 readbuf 内存起始地址的指针
void __user *ptr = buffer + *consumed;
// 指向 readbuf 内存结束地址的指针
void __user *end = buffer + size;
// 遍历 readbuf 的内存指针,取出指令
while (ptr < end && thread->return_error == BR_OK)
{
// 从 readbuf 中读取指令,此时读取到的指令是 BC_ENTER_LOOPER
if (get_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
// 指针后移
ptr += sizeof(uint32_t);
switch (cmd)
{
......
case BC_ENTER_LOOPER:
......
// 给 binder 线程的 looper 标志位添加 BINDER_LOOPER_STATE_ENTERED
thread->looper |= BINDER_LOOPER_STATE_ENTERED;
break;
......
}
......
}
return 0;
}
binder_thread_write
函数执行完成后,一直返回到 binder_loop
函数,继续执行,陷入死循环
// frameworks/native/cmds/servicemanager/binder.c
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;
......
for (;;)
{
bwr.read_size = sizeof(readbuf);
bwr.read_consumed = 0;
bwr.read_buffer = (uintptr_t) readbuf;
// 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_WRITE_READ
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
......
}
}
binder_ioctl()
// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp,
unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
unsigned long arg // arg 就是我们传入的 bwr
){
// 获取 binder 驱动的设备节点
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
......
// 获取 binder 线程
// (当前 pid 此时已经创建过 binder 线程,则返回对应的 binder 线程)
// thread->looper = BINDER_LOOPER_STATE_NEED_RETURN + BINDER_LOOPER_STATE_ENTERED
// thread->return_error = BR_OK
// thread->return_error2 = BR_OK
thread = binder_get_thread(proc);
......
switch (cmd)
{
case BINDER_WRITE_READ:
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
......
break;
......
}
......
return ret;
}
binder_ioctl_write_read()
// kernel/drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread
){
struct binder_proc *proc = filp->private_data;
......
void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;
// 将描述数据的 binder_write_read 结构体(ubuf)从用户空间拷贝到内核空间(bwr)中去
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
......
// 此时 bwr.write_size = 0,if 不命中
if (bwr.write_size > 0)
{
......
}
// 此时 bwr.read_size > 0,if 命中
if (bwr.read_size > 0)
{
// 读取 binder 驱动返回的指令
ret = binder_thread_read(proc, thread, bwr.read_buffer,
bwr.read_size,
&bwr.read_consumed,
filp->f_flags & O_NONBLOCK);
......
}
......
return ret;
}
binder_thread_read()
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block
){
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
// 指向 readbuf 内存起始地址的指针
void __user *ptr = buffer + *consumed;
// 指向 readbuf 内存结束地址的指针
void __user *end = buffer + size;
int ret = 0;
int wait_for_proc_work;
// 此时 consumed = 0,if命中
if (*consumed == 0)
{
// 将指令 BR_NOOP 添加到 readbuf 中
if (put_user(BR_NOOP, (uint32_t __user *)ptr))
return -EFAULT;
// 指针后移
ptr += sizeof(uint32_t);
}
// 此时 thread->todo = NULL,thread->transaction_stack = NULL,
// wait_for_proc_work = true
wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
......
thread->looper |= BINDER_LOOPER_STATE_WAITING;
if (wait_for_proc_work)
// 当前进程可用的 binder 线程数 +1
proc->ready_threads++;
......
if (wait_for_proc_work)
{
......
// 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
// 此时 non_block > 0,执行else
if (non_block)
{
......
}
else
// 此时 thread->todo = NULL,binder_has_proc_work 返回 false,
// 将 binder 线程挂起
ret = wait_event_freezable_exclusive(proc->wait,
binder_has_proc_work(proc, thread));
}
else
{
......
}
......
}
执行到这后 SM 线程就会被挂起,等待别的进程与之通信将其唤醒
被唤醒后的 SM 线程会继续执行此处未完成的 binder_thread_read
函数
此时 readbuf 的结构如下
AMS 是如何注册的?
将 AMS 注册到 SM 中的过程也是 AMS 与 SM 通信的过程
AMS 的注册是在 SystemServer#main
中执行的
// frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args)
{
new SystemServer().run();
}
private void run()
{
......
// 创建 SystemServiceManager
mSystemServiceManager = new SystemServiceManager(mSystemContext);
......
startBootstrapServices();
}
private void startBootstrapServices()
{
......
// 通过反射创建 ActivityManagerService.Lifecycle 并获取 AMS 对象
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
......
// 为 AMS 启动系统进程
mActivityManagerService.setSystemProcess();
}
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setSystemProcess()
{
......
// 将 AMS 注册到 SM 中
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
......
}
// frameworks/base/core/java/android/os/ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated)
{
......
getIServiceManager().addService(name, service, allowIsolated);
......
}
ServiceManager.getIServiceManager()
// frameworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager getIServiceManager()
{
if (sServiceManager != null)
{
return sServiceManager;
}
// 返回 ServiceManagerProxy
sServiceManager =
ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
BinderInternal.getContextObject()
// frameworks/base/core/java/com/android/internal/os/BinderInternal.java
public static final native IBinder getContextObject();
// frameworks/base/core/jni/android_util_Binder.cpp
static const JNINativeMethod gBinderInternalMethods[] = {
......
{ "getContextObject", "()Landroid/os/IBinder;",
(void*)android_os_BinderInternal_getContextObject },
......
};
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
// ProcessState::self() --> 打开 binder驱动并创建 ProcessState(ProcessState是单例的)
// ProcessState::getContextObject(NULL) --> 创建 BpBinder 对象并返回
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
// 创建 BinderProxy 对象并返回
return javaObjectForIBinder(env, b);
}
ProcessState::self()
// frameworks/native/libs/binder/ProcessState.cpp
sp<ProcessState> ProcessState::self()
{
Mutex::Autolock _l(gProcessMutex);
// 单例模式
if (gProcess != NULL)
{
return gProcess;
}
// 创建 ProcessState
gProcess = new ProcessState;
return gProcess;
}
// BINDER_VM_SIZE 的大小为 1M-8K
#define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2))
ProcessState::ProcessState()
: mDriverFD(open_driver()) // 开启 binder 驱动
......
{
// 如果开启 binder 驱动成功,得到了 binder 驱动设备节点
if (mDriverFD >= 0)
{
// 通过系统调用到 binder 驱动中的 binder_mmap 函数,
// 在当前进程的用户空间和内核空间之间映射 BINDER_VM_SIZE (1M-8K)大小的内存空间
mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
......
}
......
}
这里又有个知识点,AMS 的跨进程通信数据大小不能超过 1M-8K
这是一个面试常问的点,通常面试是这么问的:Intent 传输数据有大小限制吗?大小限制是多大?
答案就是 1M-8K
因为 Intent 是四大组件之间通信的方式,而 AMS 管理着四大组件,所以使用 Intent 就需要与 AMS 进行通信,由于 binder 机制的限制,与 AMS 的通信数据大小不能超过 1M-8K
ProcessState::getContextObject()
// frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
......
// 当前 handle 为 0,if 命中
if (handle == 0)
{
Parcel data;
// 通过 ping 操作测试 SM 是否准备就绪
status_t status = IPCThreadState::self()->transact(0, IBinder::PING_TRANSACTION,
data, NULL, 0);
if (status == DEAD_OBJECT)
return NULL;
}
// 创建 BpBinder 对象,handle 为 0
b = new BpBinder(handle);
......
result = b;
......
return result;
}
javaObjectForIBinder()
// frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env,
const sp<IBinder>& val // val = BpBinder
){
......
// 从 gBinderProxyOffsets 中查找 BinderProxy 对象
// 因为此时 BinderProxy 没有创建过,此时 object 为 null
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL)
{
// 通过查找 BinderProxy 对象的引用链,判断其是否正在被引用,返回其引用对象
jobject res = jniGetReferent(env, object);
// 如果 BinderProxy 对象正在被引用
if (res != NULL)
{
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
// 返回引用对象
return res;
}
......
// 移除与当前 BinderProxy 对象的所有引用
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
// 创建一个新的 BinderProxy 对象
object = env->NewObject(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mConstructor);
if (object != NULL)
{
// 将 gBinderProxyOffsets 结构体中的成员变量 mObject 赋值(BpBinder),
// 记录 BpBinder 对象
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
// 创建智能指针,相当于当前函数把 BpBinder 强引用了
val->incStrong((void*)javaObjectForIBinder);
// jni 环境变量(env)生成一个对于 BinderProxy 对象的弱引用,用于检索
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
// 将 BinderProxy 对象信息添加到 BpBinder 的成员变量 mObjects 中,
// 将 BinderProxy 与 BpBinder 互相绑定
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
......
// BinderProxy.mOrgue 成员变量记录死亡通知对象
env->SetLongField(object, gBinderProxyOffsets.mOrgue,
reinterpret_cast<jlong>(drl.get()));
......
// BinderProxy 对象引用计数加一,标志 BinderProxy 对象已被引用
android_atomic_inc(&gNumProxyRefs);
......
}
return object;
}
每个 BinderProxy 对象都会绑定一个 BpBinder 对象,每次调用 javaObjectForIBinder()
函数时都会重新生成一个 BinderProxy 对象,并重新绑定一个 BpBinder 对象
此时 BinderProxy 对象绑定的 BpBinder 对象对应的是 SM(handle 为 0)
BinderInternal.getContextObject()
函数会返回一个 BinderProxy 对象,其在 Native 层绑定了一个 BpBinder 对象(对应 SM)
ServiceManagerNative.asInterface()
// frameworks/base/core/java/android/os/ServiceManagerNative.java
static public IServiceManager asInterface(
IBinder obj // obj = BinderProxy
){
if (obj == null)
{
return null;
}
IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null)
{
return in;
}
return new ServiceManagerProxy(obj);
}
// frameworks/base/core/java/android/os/BinderProxy.java
public IInterface queryLocalInterface(String descriptor)
{
return null;
}
getIServiceManager()
函数会返回一个 ServiceManagerProxy 对象,其内部持有了一个 BinderProxy 对象
ServiceManagerProxy.addService()
// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
{
// 创建 data
Parcel data = Parcel.obtain();
// 创建 reply
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
// 将 AMS 名称写入 data
data.writeString(name);
// 将 AMS 写入 data
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
// mRemote = BinderProxy,相当于调用到 BinderProxy.transact
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
AMS 是如何将自己打包的?
// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
{
// 创建 data
Parcel data = Parcel.obtain();
......
// 将 AMS 写入 data
data.writeStrongBinder(service);
......
}
Parcel.writeStrongBinder()
// frameworks/base/core/java/android/os/Parcel.java
public final void writeStrongBinder(IBinder val)
{
nativeWriteStrongBinder(mNativePtr, val);
}
// frameworks/base/core/jni/android_os_Parcel.cpp
static const JNINativeMethod gParcelMethods[] = {
......
{"nativeWriteStrongBinder", "(JLandroid/os/IBinder;)V", (void*)android_os_Parcel_writeStrongBinder},
......
}
static void android_os_Parcel_writeStrongBinder(JNIEnv* env,
jclass clazz, jlong nativePtr,
jobject object // object = AMS
){
// 将 Java 层的 Parcel 类型(Java的Parcel)对象强制类型转换成 Native 层的 Parcel 类型对象(Native的Parcel)
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL)
{
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
......
}
}
ibinderForJavaObject()
// frameworks/base/core/jni/android_util_Binder.cpp
sp<IBinder> ibinderForJavaObject(JNIEnv* env,
jobject obj // object = AMS
){
if (obj == NULL)
return NULL;
// 如果 obj 的类型是 Binder,此时 obj = AMS,AMS 继承自 Binder.java,if 命中
if (env->IsInstanceOf(obj, gBinderOffsets.mClass))
{
// 从 gBinderOffsets.mObject 成员属性获取 JavaBBinderHolder 对象
JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
// 通过 JavaBBinderHolder#get 函数创建 JavaBBinder
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
......
return NULL;
}
JavaBBinderHolder 在 AMS 创建时一同被创建了,保存在 gBinderOffsets.mObject 中
通过调用 JavaBBinderHolder#get
函数可以创建 JavaBBinder 对象
此时创建的 JavaBBinder 对象的 mObject 字段持有了 AMS
ibinderForJavaObject
函数会返回一个 JavaBBinder 对象,其持有了 AMS
Parcel::writeStrongBinder()
// frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, // binder = JavaBBinder
Parcel* out // out = ServiceManagerProxy.addSevice 函数中定义的 data
){
// 用于封装 JavaBBinder
flat_binder_object obj;
......
if (binder != NULL)
{
// 判断 binder 对象是 BpBinder 还是 BBinder,
// JavaBBinder 是 BBinder,local 不为 NULL,执行 else
IBinder *local = binder->localBinder();
if (!local)
{
......
}
else
{
obj.type = BINDER_TYPE_BINDER;
// local->getWeakRefs() = JavaBBinder = AMS
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
}
else
{
......
}
return finish_flatten_binder(binder, obj, out);
}
inline static status_t finish_flatten_binder(
const sp<IBinder>& binder, // binder = JavaBBinder
const flat_binder_object& flat,
Parcel* out // out = ServiceManagerProxy.addSevice 函数中定义的 data
){
// 将 flat_binder_object 对象写入 data
return out->writeObject(flat, false);
}
flat_binder_object 在之后的流程中还会出现,需要对其留个印象;当数据传输到 binder 驱动时,就会转变成 flat_binder_object 结构体进行处理
flat_binder_object 是对于 JavaBBinder 的封装,而 JavaBBinder 又持有了 AMS,可以理解为 flat_binder_object 就是对于 AMS 的封装
同时我们还需要留意此时 flat_binder_object.type = BINDER_TYPE_BINDER
AMS 最终是被封装成 flat_binder_object 写入 data 中的
AMS 是如何将自己发送给 SM 的?
// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
{
// 创建 data
Parcel data = Parcel.obtain();
......
// mRemote = BinderProxy,相当于调用到 BinderProxy.transact
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
......
}
BinderProxy.transact()
// android\frameworks\base\core\java\android\os\Binder.java
public boolean transact(int code, Parcel data, Parcel reply, int flags)
{
......
return transactNative(code, data, reply, flags);
}
public native boolean transactNative(int code, Parcel data, Parcel reply, int flags);
// android\frameworks\base\core\jni\android_util_Binder.cpp
static const JNINativeMethod gBinderProxyMethods[] = {
......
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z",
(void*)android_os_BinderProxy_transact},
......
};
// android\frameworks\base\core\jni\android_util_Binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, // code = ADD_SERVICE_TRANSACTION
jobject dataObj,
jobject replyObj,
jint flags
){
......
// 将 dataObj 的类型转成 Parcel
Parcel* data = parcelForJavaObject(env, dataObj);
......
// 将 replyObj 的类型转成 Parcel
Parcel* reply = parcelForJavaObject(env, replyObj);
......
// 获取 gBinderProxyOffsets.mObject 中保存的 BpBinder 对象
IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
......
// 调用到 BpBinder 对象的 transact 函数
status_t err = target->transact(code, *data, reply, flags);
......
}
// android\frameworks\native\libs\binder\BpBinder.cpp
status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
......
// mHandle = 0
status_t status = IPCThreadState::self()->transact(mHandle, code, data,
reply, flags);
......
}
IPCThreadState::self()
// android\frameworks\native\libs\binder\IPCThreadState.cpp
static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER; // 并发锁对象
static bool gHaveTLS = false; // 标识TLS是否已经创建
static pthread_key_t gTLS = 0; // TLS存储的key
IPCThreadState* IPCThreadState::self()
{
if (gHaveTLS)
{
restart:
const pthread_key_t k = gTLS;
// 调用pthread_getspecific,通过gTLS获取存储的数据
IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
if (st) return st;
return new IPCThreadState;
}
......
pthread_mutex_lock(&gTLSMutex); // 加锁,防止线程并发访问
// gHaveTLS初始值为false,表示TLS未创建
if (!gHaveTLS)
{
// 调用pthread_key_create创建TLS,并对gTLS赋值
// (pthread_key_create创建成功返回0,反之返回错误码)
if (pthread_key_create(&gTLS, threadDestructor) != 0)
{
pthread_mutex_unlock(&gTLSMutex); // 释放锁
return NULL; // 创建TLS错误就返回null
}
gHaveTLS = true;
}
pthread_mutex_unlock(&gTLSMutex); // 释放锁
goto restart;
}
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()), // 调用 ProcessState::self 函数
......
{
// 调用pthread_setspecific,将IPCThreadState对象保存到TLS中
pthread_setspecific(gTLS, this);
......
mIn.setDataCapacity(256); // 设置 mIn 的大小
mOut.setDataCapacity(256); // 设置 mOut 的大小
}
IPCThreadState::self()
函数完成了对于 IPCThreadState 对象的创建
为了做到让 IPCThreadState 对象对应每一个线程独一份,系统使用了 Linux 中的 TLS 技术
TLS 是指 Thread local storage(线程本地储存空间),每个线程都拥有自己的 TLS,并且是私有空间,线程之间不会共享,可以近似理解为 Java 中的 ThreadLocal
可以通过 pthread_getspecific
/ pthread_setspecific
函数获取 / 设置 TLS 空间中的内容
在 IPCThreadState::self()
函数中,将 IPCThreadState 对象使用 TLS 进行存储,使得 IPCThreadState 对象对于每个线程来说是唯一的
IPCThreadState::transact()
// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::transact(int32_t handle, // handle = 0
uint32_t code, // code = ADD_SERVICE_TRANSACTION
const Parcel& data,
Parcel* reply,
uint32_t flags
){
// 数据错误检查
status_t err = data.errorCheck();
// TF_ACCEPT_FDS = 0x10:允许回复中包含文件描述符
// TF_ONE_WAY:当前业务是异步的,不需要等待
// TF_ROOT_OBJECT:所包含的内容是根对象
// TF_STATUS_CODE:所包含的内容是 32-bit 的状态值
flags |= TF_ACCEPT_FDS;
......
// 整理数据,将 flat_binder_object(data)写入 mOut 中
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
......
// 判断当前业务是否为异步操作。
// AIDL 默认是同步操作,除非定义 AIDL 接口时使用了 oneway 关键字。
if ((flags & TF_ONE_WAY) == 0)
{
......
// reply 不为空
if (reply)
{
// 等待 binder 驱动回应事件
err = waitForResponse(reply);
}
else
{
Parcel fakeReply;
// 等待 binder 驱动回应事件
err = waitForResponse(&fakeReply);
}
......
}
else
{
// 不等待 binder 驱动回应事件
err = waitForResponse(NULL, NULL);
}
......
}
mOut 中分为两部分:
-
命令部分(在 mOut 中的地址高位)
-
数据部分,封装好的 flat_binder_object 位于这部分(在 mOut 中的地址低位)
结构如下图所示
IPCThreadState::waitForResponse()
// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::waitForResponse(
Parcel *reply,
status_t *acquireResult
){
uint32_t cmd;
int32_t err;
// 循环等待结果
while (1)
{
// 调用 talkWithDriver 函数发送指令给 binder 驱动
if ((err=talkWithDriver()) < NO_ERROR) break;
......
// 如果 mIn 中没有数据,就 continue
if (mIn.dataAvail() == 0) continue;
......
}
......
}
IPCThreadState::talkWithDriver()
// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
......
// mIn 是宏定义的 Parcel 变量,此时 mIn 未进行赋值
// mIn.dataPosition() = mIn.dataSize() = 0,needRead为true
const bool needRead = mIn.dataPosition() >= mIn.dataSize();
......
const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
bwr.write_size = outAvail;
// 此时 bwr.write_buffer 指向 mOut 的起始地址
bwr.write_buffer = (uintptr_t)mOut.data();
// 如果需要读数据
if (doReceive && needRead)
{
// dataCapacity = 256
bwr.read_size = mIn.dataCapacity();
// 此时的 mIn.data() = 0
bwr.read_buffer = (uintptr_t)mIn.data();
}
else // 不需要读数据就设置 bwr.read_size 为零
// 这样在 binder_ioctl_write_read 函数中就不会执行 binder_thread_read
{
bwr.read_size = 0;
bwr.read_buffer = 0;
}
......
bwr.write_consumed = 0;
bwr.read_consumed = 0;
// 循环发送指令给 binder 驱动直至成功
do {
......
// 通过系统调用到 binder 驱动的 binder_ioctl 方法,进入内核态
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
......
} while (err == -EINTR); // 只有当 ioctl 发生错误后 while 循环条件才会成立,
// 因此如果发送成功就只执行一次
......
return err;
}
binder_ioctl()
// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp,
unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
unsigned long arg // arg 就是我们传入的 bwr
){
// 获取 binder 驱动的设备节点
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
......
// 获取 binder 线程
// (当前 pid 此时没有创建过 binder 线程,则创建一个 binder 线程并返回)
// thread->looper = BINDER_LOOPER_STATE_NEED_RETURN
// thread->return_error = BR_OK
// thread->return_error2 = BR_OK
thread = binder_get_thread(proc);
......
switch (cmd)
{
case BINDER_WRITE_READ:
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
......
break;
......
}
......
return ret;
}
binder_ioctl_write_read()
// kernel\drivers\staging\android\binder.c
static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread)
{
struct binder_proc *proc = filp->private_data;
......
void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;
// 将 mOut 的起始地址从用户空间拷贝到内核空间(bwr)
if (copy_from_user(&bwr, ubuf, sizeof(bwr)))
{
ret = -EFAULT;
goto out;
}
......
// 此时 bwr.write_size > 0,if命中
if (bwr.write_size > 0)
{
// 发送指令给 binder 驱动
ret = binder_thread_write(proc, thread,
bwr.write_buffer,
bwr.write_size,
&bwr.write_consumed);
......
}
// 此时 bwr.read_size > 0,if命中
if (bwr.read_size > 0)
{
// 读取 binder 驱动返回的指令
ret = binder_thread_read(proc, thread, bwr.read_buffer,
bwr.read_size,
&bwr.read_consumed,
filp->f_flags & O_NONBLOCK);
......
}
......
out:
return ret;
}
binder_thread_write()
// kernel\drivers\staging\android\binder.c
static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed)
{
uint32_t cmd;
struct binder_context *context = proc->context;
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
// 指向 mOut 起始地址的指针
void __user *ptr = buffer + *consumed;
// 指向 mOut 结束地址的指针
void __user *end = buffer + size;
// 遍历 mOut 的内存指针,取出指令
while (ptr < end && thread->return_error == BR_OK)
{
// 将 mOut 命令部分中的命令从用户空间拷贝到内核空间(cmd),
// 此时 cmd = BC_TRANSACTION
if (get_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
// 指针后移
ptr += sizeof(uint32_t);
......
switch (cmd)
{
......
case BC_TRANSACTION:
case BC_REPLY:
{
struct binder_transaction_data tr;
// 将 mOut 数据部分中的 binder_transaction_data 从用户空间拷贝到内核空间
if (copy_from_user(&tr, ptr, sizeof(tr)))
return -EFAULT;
// 指针后移
ptr += sizeof(tr);
// 调用 binder_transaction 函数
binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0);
break;
}
......
}
......
}
......
}
这里还不是真正意义上的一次拷贝
binder_transaction()
// kernel\drivers\staging\android\binder.c
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr, // mOut 数据部分
int reply, // 此时 reply = false
binder_size_t extra_buffers_size)
{
......
struct binder_transaction *t;
struct binder_work *tcomplete;
binder_size_t *offp, *off_end, *off_start;
......
struct binder_proc *target_proc;
struct binder_thread *target_thread = NULL;
struct binder_node *target_node = NULL;
struct list_head *target_list;
wait_queue_head_t *target_wait;
......
// 此处 reply 为 false(cmd == BC_TRANSACTION)
if (reply)
{
......
}
else
{
// tr->target.handle = 0,执行 else
if (tr->target.handle)
{
......
}
else
{
// 获取 SM 的 binder_node 节点
target_node = context->binder_context_mgr_node;
......
}
......
// 获取 SM 的 binder_proc
target_proc = target_node->proc;
......
}
// 获取 SM 的 todo 队列和 wait 队列
target_list = &target_proc->todo;
target_wait = &target_proc->wait;
......
// 生成一个 binder_transaction 变量(即变量 t),
// 用于描述本次要进行的 transaction(最后将其加入 target_thread->todo)。
// 这样当目标对象被唤醒时,它就可以从这个队列中取出需要做的工作。
t = kzalloc(sizeof(*t), GFP_KERNEL);
......
// 生成一个 binder_work 变量(即变量 tcomplete),用于说明 AMS 有一个未完成的工作
tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
......
// 此时 if 命中
if (!reply && !(tr->flags & TF_ONE_WAY))
// 非 oneway(同步)的通信方式,把当前 thread 保存到 transaction 的 from 字段
t->from = thread;
else
t->from = NULL;
......
// 记录此次通信的目标进程
t->to_proc = target_proc;
......
// 此次通信 code = ADD_SERVICE_TRANSACTION
t->code = tr->code;
// 此次通信 flags = 0
t->flags = tr->flags;
......
// 从 SM 进程中分配 buffer
// (为完成本条 transaction 申请内存,从 binder_mmap 开辟的空间中申请内存)
t->buffer = binder_alloc_buf(target_proc, tr->data_size,
tr->offsets_size, extra_buffers_size,
!reply && (t->flags & TF_ONE_WAY));
......
// 记录 SM 的 binder_node
t->buffer->target_node = target_node;
......
// 记录 mOut 数据部分的起始地址
off_start = (binder_size_t *)(t->buffer->data +
ALIGN(tr->data_size, sizeof(void *)));
offp = off_start;
......
// 将 mOut 数据部分从用户空间拷贝到内核空间(t->buffer->data)(一次拷贝)
if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
tr->data.ptr.buffer, tr->data_size))
......
// 记录 mOut 数据部分的结束地址
off_end = (void *)off_start + tr->offsets_size;
......
// 遍历 mOut 数据部分的内存指针
for (; offp < off_end; offp++)
{
struct binder_object_header *hdr;
......
// 将 mOut 的数据部分转型成 binder_object_header
hdr = (struct binder_object_header *)(t->buffer->data + *offp);
......
switch (hdr->type) // 此时 hdr->type = flat_binder_object.type = BINDER_TYPE_BINDER
{
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER:
{
struct flat_binder_object *fp;
// 将数据转型成 flat_binder_object 结构体
fp = to_flat_binder_object(hdr);
// 创建 AMS 在 binder 驱动中的实体节点,并创建对该节点的引用(handle)
ret = binder_translate_binder(fp, t, thread);
......
} break;
......
}
}
......
// 此时 cmd = BC_TRANSACTION,cmd != BC_REPLY,reply = false
if (reply)
{
......
}
else if(!(t->flags & TF_ONE_WAY)) // 操作是同步的,命中
{
......
// 记录本次的 transaction,以备后期查询
// (SM 通过这个知道是谁调用的,从而返回数据)
thread->transaction_stack = t;
}
else
{
......
}
// 设置 t 的类型为 BINDER_WORK_TRANSACTION
t->work.type = BINDER_WORK_TRANSACTION;
// 将 t 加入 SM 进程的 todo 队列
list_add_tail(&t->work.entry, target_list);
// 设置 binder_work 的类型为 BINDER_WORK_TRANSACTION_COMPLETE
tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
// 将 tcomplete 加入 AMS 线程的 todo 队列
list_add_tail(&tcomplete->entry, &thread->todo);
// 此时 SM 被挂起,target_wait != NULL,if命中
if (target_wait)
// 唤醒 SM 进程
wake_up_interruptible(target_wait);
return;
......
}
binder_transaction
函数主要做了几件事:
- 获取到 SM 进程的 binder_proc 结构体
- 生成一个 binder_transaction 变量(给 SM 的)和一个 binder_work 变量(给 AMS 的)来保存信息
- 将封装好的 flat_binder_object 拷贝到 binder_mmap 开辟的共享内存中(重点,一次拷贝)
- 创建 AMS 在 binder 驱动中的实体节点,并创建对该节点的引用(handle)
- 将 binder_transaction 变量添加到 SM 进程的 todo 队列,唤醒 SM 进程
- 将 binder_work 变量添加到 AMS 调用线程的 todo 队列,将 AMS 挂起等待
binder_transaction
函数中才真正的做到了 IPC 通信传输
binder_thread_read()
// kernel\drivers\staging\android\binder.c
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block)
{
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
// 指向 mIn 内存起始地址的指针
void __user *ptr = buffer + *consumed;
// 指向 mIn 内存结束地址的指针
void __user *end = buffer + size;
int ret = 0;
int wait_for_proc_work;
......
retry:
// 1. thread->todo 不为空,wait_for_proc_work 为 false
// 2. thread->todo 为空,wait_for_proc_work 为 true
wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
// 1. 执行 else
// 2. 执行 if
if (wait_for_proc_work)
{
......
if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
// 此时 non_block > 0,执行else
{
......
}
else
// 2. thread->todo 为空,binder_has_thread_work 返回 false,将 AMS 线程挂起
ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
}
else
{
if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
// 此时 non_block > 0,执行else
{
......
}
else
// 1. thread->todo 不为空,binder_has_thread_work 返回 true,不会将 AMS 线程挂起
ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
}
......
// 1. 线程没有挂起,继续执行 while 循环
while (1)
{
uint32_t cmd;
struct binder_transaction_data tr;
struct binder_work *w;
struct binder_transaction *t = NULL;
// 1. 在 binder_transaction 函数中添加了一个 binder_work,此时 thread->todo 不为空,if 命中
// 2. 在执行 BINDER_WORK_TRANSACTION_COMPLETE 指令的时候将 binder_work 删除了,
// 此时 thread->todo 为空,执行else
if (!list_empty(&thread->todo))
{
// 1. 取出 binder_work
w = list_first_entry(&thread->todo, struct binder_work, entry);
}
else
{
// 2. 此时 if 命中
if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN))
// 2. 返回 retry 处执行代码
goto retry;
break;
}
......
// 1. 此时 w->type 为 BINDER_WORK_TRANSACTION_COMPLETE
switch (w->type)
{
......
case BINDER_WORK_TRANSACTION_COMPLETE:
{
// 1. 更改指令 BR_TRANSACTION_COMPLETE
cmd = BR_TRANSACTION_COMPLETE;
// 1. 将指令拷贝到 mIn 中
if (put_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
// 1. 指针后移
ptr += sizeof(uint32_t);
......
// 1. 将当前的 binder_work 从 thread->todo 中删除
list_del(&w->entry);
// 1. 释放 binder_work 的内存
kfree(w);
......
} break;
......
}
// 1. 此时 t = null,if 命中
if (!t)
continue;
......
}
*consumed = ptr - buffer;
......
return 0;
}
binder_thread_read
函数中的 while 循环会执行两次,所以代码中的注释写了序号,序号对应着第几次 while 循环
此时 AMS 就被挂起了,等待 SM 进程返回数据后唤醒
当 AMS 被唤醒后就从此处的 binder_thread_read
函数开始继续执行
SM 进程被唤醒后做了什么?
当 binder_transaction
函数执行完成后,SM 线程被唤醒,继续执行未完成的 binder_thread_read
函数
binder_thread_read()
// kernel\drivers\staging\android\binder.c
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block)
{
......
if (wait_for_proc_work)
// 当前进程可用的 binder 线程数 -1
proc->ready_threads--;
thread->looper &= ~BINDER_LOOPER_STATE_WAITING;
......
while (1)
{
uint32_t cmd;
struct binder_transaction_data tr;
struct binder_work *w;
struct binder_transaction *t = NULL;
......
// 在 binder_transaction 函数中添加了一个 binder_transaction,此时 proc->todo 不为空
else if (!list_empty(&proc->todo) && wait_for_proc_work)
{
// 取出 binder_transaction,但类型是 binder_work
w = list_first_entry(&proc->todo, struct binder_work, entry);
}
......
// 此时 w->type 为 BINDER_WORK_TRANSACTION
switch (w->type)
{
......
case BINDER_WORK_TRANSACTION:
{
// 类型转换(binder_work -> binder_transaction)
t = container_of(w, struct binder_transaction, work);
} break;
......
}
// 此时 t != null,if不命中
if (!t)
continue;
......
// 此时 t->buffer->target_node = SM,不为空,if命中
if (t->buffer->target_node)
{
struct binder_node *target_node = t->buffer->target_node;
tr.target.ptr = target_node->ptr;
tr.cookie = target_node->cookie;
......
// 指令更改为 BR_TRANSACTION
cmd = BR_TRANSACTION;
}
else
{
......
}
// t->code = ADD_SERVICE_TRANSACTION
tr.code = t->code;
// t->flags = 0
tr.flags = t->flags;
// 此时 t->from 不为 NULL,if 命中
if (t->from)
{
struct task_struct *sender = t->from->proc->tsk;
// 获取 AMS 线程的 pid 并记录
tr.sender_pid = task_tgid_nr_ns(sender, task_active_pid_ns(current));
}
else
{
......
}
// 记录 mOut 数据部分的内存地址、大小等信息
tr.data_size = t->buffer->data_size;
tr.offsets_size = t->buffer->offsets_size;
tr.data.ptr.buffer = (binder_uintptr_t)((uintptr_t)t->buffer->data +
proc->user_buffer_offset);
tr.data.ptr.offsets = tr.data.ptr.buffer + ALIGN(t->buffer->data_size,
sizeof(void *));
// 将指令 BR_TRANSACTION 拷贝到用户空间(binder_loop 中的 readbuf)
if (put_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
// 指针后移
ptr += sizeof(uint32_t);
// 将 mOut 数据部分的信息拷贝到用户空间(binder_loop 中的 readbuf)
if (copy_to_user(ptr, &tr, sizeof(tr)))
return -EFAULT;
// 指针后移
ptr += sizeof(tr);
......
// 此时 if 命中
if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY))
{
t->to_parent = thread->transaction_stack;
t->to_thread = thread;
// 将 t 保存在 SM 线程的 transaction_stack 中
thread->transaction_stack = t;
}
else
{
......
}
// 跳出循环
break;
......
}
*consumed = ptr - buffer;
// 此时 proc->requested_threads = proc->ready_threads = 0,
// proc->requested_threads_started = 0 < proc->max_threads(默认是15),
// thread->looper = BINDER_LOOPER_STATE_NEED_RETURN + BINDER_LOOPER_STATE_ENTERED,
// 条件满足,if 命中
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))
{
......
// 当前进程需要创建的 binder 线程数 +1
proc->requested_threads++;
// 将指令 BR_SPAWN_LOOPER 拷贝到用户空间(binder_loop 中的 readbuf)
if (put_user(BR_SPAWN_LOOPER, (uint32_t __user *)buffer))
return -EFAULT;
......
}
return 0;
}
当 binder_thread_read
函数执行完成后,binder_ioctl_write_read
函数也执行完成,返回到 binder_loop
函数,继续执行
此时 readbuf 的结构如下
binder_loop()
// frameworks/native/cmds/servicemanager/binder.c
void binder_loop(struct binder_state *bs, binder_handler func)
{
......
for (;;)
{
......
res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
......
}
}
binder_parse()
readbuf 中别的指令处理流程都可以不用管,直接看最重要的 BR_TRANSACTION
// frameworks/native/cmds/servicemanager/binder.c
int binder_parse(struct binder_state *bs,
struct binder_io *bio,
uintptr_t ptr, // ptr 指向 binder_loop 中 readbuf 的起始地址
size_t size, // size = binder_loop 中 readbuf 的长度
binder_handler func
){
int r = 1;
// 指向 binder_loop 中的 bwr.read_buffer 内存结束地址的指针
uintptr_t end = ptr + (uintptr_t) size;
while (ptr < end)
{
// 指令占用的内存大小是 uint32_t,取出 readbuf 中的指令(从头开始)
uint32_t cmd = *(uint32_t *) ptr;
// 指针后移
ptr += sizeof(uint32_t);
......
switch(cmd)
{
......
case BR_TRANSACTION:
{
// 将 mOut 数据部分转型为 binder_transaction_data
struct binder_transaction_data *txn =
(struct binder_transaction_data *) ptr;
......
// 函数指针引用,此时 func = service_manager.svcmgr_handler,if 命中
if (func)
{
unsigned rdata[256/4];
struct binder_io msg;
struct binder_io reply;
int res;
// 初始化 reply
bio_init(&reply, rdata, sizeof(rdata), 4);
// 初始化 msg,将 mOut 数据部分的信息拷贝到 msg 中
bio_init_from_txn(&msg, txn);
// 执行 service_manager.svcmgr_handler 函数
res = func(bs, txn, &msg, &reply);
// 将 reply 发送给 binder 驱动
binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
}
// 指针后移
ptr += sizeof(*txn);
break;
}
......
}
}
return r;
}
func 是一个函数指针,指向 service_manager.svcmgr_handler
函数,所以 res = func(bs, txn, &msg, &reply);
这行代码调用的就是 service_manager.svcmgr_handler
函数
service_manager.svcmgr_handler()
// frameworks/native/cmds/servicemanager/service_manager.c
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn, // mOut 数据部分
struct binder_io *msg, // mOut 数据部分的信息
struct binder_io *reply
){
struct svcinfo *si;
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
......
// 此时 txn->code = ADD_SERVICE_TRANSACTION = 3 = SVC_MGR_ADD_SERVICE
switch(txn->code)
{
......
case SVC_MGR_ADD_SERVICE:
// 从 mOut 数据部分中获取 AMS 的名称
s = bio_get_string16(msg, &len);
......
// 从 mOut 数据部分中获取 AMS 的引用(handle)
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
// 在 SM 中记录 AMS
if (do_add_service(bs, s, len, handle, txn->sender_euid,
allow_isolated, txn->sender_pid))
return -1;
break;
......
}
// 此时 reply 中没有数据
bio_put_uint32(reply, 0);
return 0;
}
do_add_service()
// frameworks/native/cmds/servicemanager/service_manager.c
int do_add_service(struct binder_state *bs,
const uint16_t *s, size_t len,
uint32_t handle, uid_t uid, int allow_isolated,
pid_t spid
){
// 在 SM 中用 svcinfo 结构体保存注册过的 Service 信息
struct svcinfo *si;
......
// 查找 AMS 是否在 SM 注册过
si = find_svc(s, len);
// 如果 AMS 已经注册过了
if (si)
{
if (si->handle)
{
......
// 将当前这个 svcinfo 中记录的引用(handle)清空
svcinfo_death(bs, si);
}
// 对当前这个 svcinfo 中的引用(handle)重新赋值
si->handle = handle;
}
else // 如果 AMS 没注册过
{
// 创建一个新的 svcinfo 结构体
si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
......
// 记录 AMS 的引用(handle)
si->handle = handle;
si->len = len;
// 拷贝 AMS 信息
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;
// 将创建的 svcinfo 结构体添加到 svclist 中
si->next = svclist;
svclist = si;
}
// 以 BC_ACQUIRE 命令,handle 为目标的信息,通过 ioctl 发送给 binder 驱动,
// 使 binder_ref 强引用加1操作
binder_acquire(bs, handle);
// 以 BC_REQUEST_DEATH_NOTIFICATION 命令的信息,通过 ioctl 发送给 binder 驱动,
// 主要进行清理内存等收尾工作
binder_link_to_death(bs, handle, &si->death);
return 0;
}
service_manager.do_add_service
函数将 AMS 记录到了 SM 中,完成了注册
在 SM 中保存是 AMS 的名称 和 对于 AMS 在 binder 驱动中实体节点的引用(handle)
当之后有别的进程通过访问 SM 来请求 AMS 时,SM 就会返回这个引用给请求方
binder_send_reply()
// frameworks/native/cmds/servicemanager/binder.c
void binder_send_reply(
struct binder_state *bs,
struct binder_io *reply, // 此时 reply 中是空的
binder_uintptr_t buffer_to_free, // mOut 数据部分内存起始地址的指针
int status // status = 0
){
// 定义了一个结构体 data,用于封装命令和 reply
struct {
uint32_t cmd_free; // 占高位
binder_uintptr_t buffer;
uint32_t cmd_reply; // 占低位
struct binder_transaction_data txn;
} __attribute__((packed)) data;
data.cmd_free = BC_FREE_BUFFER; // free buffer 命令
data.buffer = buffer_to_free;
data.cmd_reply = BC_REPLY; // reply 命令
data.txn.target.ptr = 0;
data.txn.cookie = 0;
data.txn.code = 0;
// status = 0,执行 else
if (status)
{
......
}
else
{
// 使用 data 中的 binder_transaction_data(txn)记录 reply 的地址信息
data.txn.flags = 0;
data.txn.data_size = reply->data - reply->data0;
data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
}
// 向 binder 驱动通信,执行指令
binder_write(bs, &data, sizeof(data));
}
binder_write()
// frameworks/native/cmds/servicemanager/binder.c
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;
// 通过系统调用到 binder 驱动中的 binder_ioctl 函数,指令为 BINDER_WRITE_READ
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
......
return res;
}
binder_ioctl()
// kernel/drivers/staging/android/binder.c
static long binder_ioctl(struct file *filp,
unsigned int cmd, // cmd 就是我们传入的 BINDER_WRITE_READ
unsigned long arg // arg 就是我们传入的 bwr
){
// 获取 binder 驱动的设备节点
struct binder_proc *proc = filp->private_data;
struct binder_thread *thread;
......
// 获取 binder 线程
// (当前 pid 此时已经创建过 binder 线程,则返回对应的 binder 线程)
// thread->looper = BINDER_LOOPER_STATE_NEED_RETURN + BINDER_LOOPER_STATE_ENTERED
// thread->return_error = BR_OK
// thread->return_error2 = BR_OK
thread = binder_get_thread(proc);
......
switch (cmd)
{
case BINDER_WRITE_READ:
ret = binder_ioctl_write_read(filp, cmd, arg, thread);
......
break;
......
}
......
return ret;
}
binder_ioctl_write_read()
// kernel/drivers/staging/android/binder.c
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;
......
void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;
......
// 将 data 的起始地址从用户空间拷贝到内核空间(bwr)
if (copy_from_user(&bwr, ubuf, sizeof(bwr)))
{
ret = -EFAULT;
goto out;
}
......
if (bwr.write_size > 0)
{
// 发送指令给 binder 驱动
ret = binder_thread_write(proc, thread,
bwr.write_buffer,
bwr.write_size,
&bwr.write_consumed);
......
}
// 此时 bwr.read_size = 0,if 不命中
if (bwr.read_size > 0)
{
......
}
......
out:
return ret;
}
binder_thread_write()
// kernel/drivers/staging/android/binder.c
static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, // binder_buffer = data 的起始地址
size_t size, // data 的大小
binder_size_t *consumed
){
uint32_t cmd;
struct binder_context *context = proc->context;
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
// 指向 data 内存起始地址的指针
void __user *ptr = buffer + *consumed;
// 指向 data 内存结束地址的指针
void __user *end = buffer + size;
while (ptr < end && thread->return_error == BR_OK)
{
// 从 data 中读取指令
if (get_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
// 指针后移
ptr += sizeof(uint32_t);
// cmd 先是 BC_FREE_BUFFER,再是 BC_REPLY
switch (cmd)
{
......
case BC_FREE_BUFFER:
{
// 在这里会将 data.buffer 所指向的内存区域中的数据清空,
// 也就是拷贝到内核空间中的 mOut 数据部分的缓存,
// 在这里就不过多分析了
......
break;
}
......
case BC_TRANSACTION:
case BC_REPLY:
{
struct binder_transaction_data tr;
// 将 data 中记录的 reply 从用户空间拷贝到内核空间(binder_transaction_data)
if (copy_from_user(&tr, ptr, sizeof(tr)))
return -EFAULT;
// 指针后移
ptr += sizeof(tr);
// 调用 binder_transaction 函数
binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0);
break;
}
......
}
......
}
return 0;
}
binder_transaction()
再次调用 binder_transaction
函数与 AMS 进程进行通信,通知 AMS 注册成功
// kernel\drivers\staging\android\binder.c
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr,
int reply, // 此时 reply = true
binder_size_t extra_buffers_size)
{
......
struct binder_transaction *t;
struct binder_work *tcomplete;
......
struct binder_proc *target_proc;
struct binder_thread *target_thread = NULL;
struct binder_node *target_node = NULL;
struct list_head *target_list;
wait_queue_head_t *target_wait;
......
// 此处 reply 为 true(cmd == BC_REPLY)
if (reply)
{
// 获取记录在 thread->transaction_stack 中的 binder_transaction
in_reply_to = thread->transaction_stack;
......
thread->transaction_stack = in_reply_to->to_parent;
// in_reply_to->from = AMS 线程
target_thread = in_reply_to->from;
......
target_proc = target_thread->proc;
}
else
{
......
}
// 此时 target_thread != NULL,if 命中
if (target_thread)
{
// 获取 AMS 线程的 pid 值
e->to_thread = target_thread->pid;
// 获取 AMS 线程的 todo 队列和 wait 队列
target_list = &target_thread->todo;
target_wait = &target_thread->wait;
}
else
{
......
}
......
// 生成一个 binder_transaction 变量(即变量 t),
// 用于描述本次要进行的 transaction(最后将其加入 target_thread->todo)。
// 这样当目标对象被唤醒时,它就可以从这个队列中取出需要做的工作。
t = kzalloc(sizeof(*t), GFP_KERNEL);
......
// 生成一个 binder_work 变量(即变量 tcomplete),用于说明 AMS 有一个未完成的工作
tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
......
// 此时 if 不命中,执行 else
if (!reply && !(tr->flags & TF_ONE_WAY))
......
else
t->from = NULL;
......
// 记录此次通信的目标进程(AMS)
t->to_proc = target_proc;
......
// 此次通信 code = 0
t->code = tr->code;
// 此次通信 flags = 0
t->flags = tr->flags;
......
// 从 AMS 进程中分配 buffer
// (为完成本条 transaction 申请内存,从 binder_mmap 开辟的空间中申请内存)
t->buffer = binder_alloc_buf(target_proc, tr->data_size,
tr->offsets_size, extra_buffers_size,
!reply && (t->flags & TF_ONE_WAY));
......
// 记录 AMS 的 binder_node,此时 target_node = NULL
t->buffer->target_node = target_node;
......
// 将 reply 从用户空间拷贝到内核空间(t->buffer->data)
if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
tr->data.ptr.buffer, tr->data_size))
......
// 此时 cmd = BC_REPLY,reply = true
if (reply)
{
......
// 清空数据,释放缓存
binder_pop_transaction(target_thread, in_reply_to);
}
else if(!(t->flags & TF_ONE_WAY))
{
......
}
else
{
......
}
// 设置 t 的类型为 BINDER_WORK_TRANSACTION
t->work.type = BINDER_WORK_TRANSACTION;
// 将 t 加入 AMS 线程的 todo 队列
list_add_tail(&t->work.entry, target_list);
// 设置 binder_work 的类型为 BINDER_WORK_TRANSACTION_COMPLETE
tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
// 将 tcomplete 加入 SM 进程的 todo 队列
list_add_tail(&tcomplete->entry, &thread->todo);
// 此时 AMS 被挂起,target_wait != NULL,if命中
if (target_wait)
// 唤醒 AMS 进程
wake_up_interruptible(target_wait);
return;
......
}
binder_transaction
函数执行完成后,会一直返回到 binder_loop
函数,经过循环再次调用 ioctl
函数读取 binder 驱动的指令
binder_ioctl_write_read()
// kernel/drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread
){
struct binder_proc *proc = filp->private_data;
......
void __user *ubuf = (void __user *)arg;
struct binder_write_read bwr;
// 将描述数据的 binder_write_read 结构体(ubuf)从用户空间拷贝到内核空间(bwr)中去
if (copy_from_user(&bwr, ubuf, sizeof(bwr))) {
......
// 此时 bwr.write_size = 0,if 不命中
if (bwr.write_size > 0)
{
......
}
// 此时 bwr.read_size > 0,if 命中
if (bwr.read_size > 0)
{
// 读取 binder 驱动返回的指令
ret = binder_thread_read(proc, thread, bwr.read_buffer,
bwr.read_size,
&bwr.read_consumed,
filp->f_flags & O_NONBLOCK);
......
}
......
return ret;
}
binder_thread_read()
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block
){
void __user *buffer = (void __user *)(uintptr_t)binder_buffer;
// 指向 binder_loop 中的 bwr.read_buffer 内存起始地址的指针
void __user *ptr = buffer + *consumed;
// 指向 binder_loop 中的 bwr.read_buffer 内存结束地址的指针
void __user *end = buffer + size;
int ret = 0;
int wait_for_proc_work;
......
retry:
// 1. thread->todo 不为空,wait_for_proc_work 为 false
// 2. thread->todo 为空,wait_for_proc_work 为 true
wait_for_proc_work = thread->transaction_stack == NULL && list_empty(&thread->todo);
......
// 1. 执行 else
// 2. 执行 if
if (wait_for_proc_work)
{
......
if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
// 此时 non_block > 0,执行else
{
......
}
else
// 2. thread->todo 为空,binder_has_thread_work 返回 false,将 SM 线程挂起
ret = wait_event_freezable_exclusive(proc->wait, binder_has_proc_work(proc, thread));
}
else
{
if (non_block) // 入参的时候 filp->f_flags & O_NONBLOCK 已经赋值
// 此时 non_block > 0,执行 else
{
......
}
else
// 1. thread->todo 不为空,binder_has_thread_work 返回 true,不会将 SM 线程挂起
ret = wait_event_freezable(thread->wait, binder_has_thread_work(thread));
}
......
// 1. 线程没有挂起,继续执行 while 循环
while (1)
{
uint32_t cmd;
struct binder_transaction_data tr;
struct binder_work *w;
struct binder_transaction *t = NULL;
// 1. 在 binder_transaction 函数中添加了一个 binder_work,此时 thread->todo 不为空,if 命中
// 2. 在执行 BINDER_WORK_TRANSACTION_COMPLETE 指令的时候将 binder_work 删除了,
// 此时 thread->todo 为空,执行else
if (!list_empty(&thread->todo))
{
// 1. 取出 binder_work
w = list_first_entry(&thread->todo, struct binder_work, entry);
}
else
{
// 2. 此时 if 命中
if (ptr - buffer == 4 && !(thread->looper & BINDER_LOOPER_STATE_NEED_RETURN))
// 2. 返回 retry 处执行代码
goto retry;
break;
}
......
// 1. 此时 w->type 为 BINDER_WORK_TRANSACTION_COMPLETE
switch (w->type)
{
......
case BINDER_WORK_TRANSACTION_COMPLETE:
{
// 1. 更改指令 BR_TRANSACTION_COMPLETE
cmd = BR_TRANSACTION_COMPLETE;
// 1. 将指令拷贝到 binder_loop 中的 bwr.read_buffer
if (put_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
// 1. 指针后移
ptr += sizeof(uint32_t);
......
// 1. 将当前的 binder_work 从 thread->todo 中删除
list_del(&w->entry);
// 1. 释放 binder_work 的内存
kfree(w);
......
} break;
......
}
// 1. 此时 t = null,if 命中
if (!t)
continue;
......
}
*consumed = ptr - buffer;
......
return 0;
}
在 binder_thread_read
函数中 while 循环会执行两次,所以代码中的注释写了序号,序号对应着第几次 while 循环
此时 SM 就再次被挂起了,等待其他进程与之通信后被唤醒
当 SM 被唤醒后就从此处的 binder_thread_read
函数开始继续执行
AMS 进程被唤醒后做了什么?
binder_transaction
函数执行完成后,AMS 进程被唤醒,继续执行未完成的 binder_thread_read
函数
binder_thread_read()
// kernel\drivers\staging\android\binder.c
static int binder_thread_read(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed, int non_block)
{
......
while (1)
{
uint32_t cmd;
struct binder_transaction_data tr;
struct binder_work *w;
struct binder_transaction *t = NULL;
......
// 在 binder_transaction 函数中添加了一个 binder_transaction,此时 proc->todo 不为空
else if (!list_empty(&proc->todo) && wait_for_proc_work)
{
// 取出 binder_transaction,但类型是 binder_work
w = list_first_entry(&proc->todo, struct binder_work, entry);
}
......
// 此时 w->type 为 BINDER_WORK_TRANSACTION
switch (w->type)
{
......
case BINDER_WORK_TRANSACTION:
{
// 类型转换(binder_work -> binder_transaction)
t = container_of(w, struct binder_transaction, work);
} break;
......
}
// 此时 t != null,if不命中
if (!t)
continue;
......
// 此时 t->buffer->target_node 为空,if 不命中
if (t->buffer->target_node)
{
......
}
else
{
tr.target.ptr = 0;
tr.cookie = 0;
// 指令更改为 BR_REPLY
cmd = BR_REPLY;
}
// t->code = 0
tr.code = t->code;
// t->flags = 0
tr.flags = t->flags;
// 此时 t->from 为 NULL,if 不命中
if (t->from)
{
......
}
else
{
tr.sender_pid = 0;
}
// 记录 reply 的内存起始地址、大小等信息
tr.data_size = t->buffer->data_size;
tr.offsets_size = t->buffer->offsets_size;
tr.data.ptr.buffer = (binder_uintptr_t)((uintptr_t)t->buffer->data +
proc->user_buffer_offset);
tr.data.ptr.offsets = tr.data.ptr.buffer +
ALIGN(t->buffer->data_size, sizeof(void *));
// 将指令 BR_REPLY 拷贝到用户空间(mIn)
if (put_user(cmd, (uint32_t __user *)ptr))
return -EFAULT;
// 指针后移
ptr += sizeof(uint32_t);
// 将 reply 的信息拷贝到用户空间(mIn)
if (copy_to_user(ptr, &tr, sizeof(tr)))
return -EFAULT;
// 指针后移
ptr += sizeof(tr);
......
// 此时 if 不命中
if (cmd == BR_TRANSACTION && !(t->flags & TF_ONE_WAY))
{
......
}
else
{
t->buffer->transaction = NULL;
// 释放内存
kfree(t);
}
// 跳出循环
break;
......
}
*consumed = ptr - buffer;
......
return 0;
}
binder_thread_read
函数执行完成后,一直返回到 IPCThreadState::talkWithDriver()
函数,继续执行
IPCThreadState::talkWithDriver()
// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
......
do {
......
// 执行返回处
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
......
} while (err == -EINTR); // 如果 ioctl 没有发生错误,退出循环
......
// 如果 ioctl 没有发生错误,if 命中
if (err >= NO_ERROR)
{
// 如果已经将 mOut 中的数据发送给了 Binder 驱动
if (bwr.write_consumed > 0)
{
if (bwr.write_consumed < mOut.dataSize())
// 将 mOut 中已经发送的数据删除
mOut.remove(0, bwr.write_consumed);
else
mOut.setDataSize(0);
}
// 如果 mIn 中有数据,将 mIn 全部返回
if (bwr.read_consumed > 0)
{
mIn.setDataSize(bwr.read_consumed);
mIn.setDataPosition(0);
}
......
return NO_ERROR;
}
return err;
}
IPCThreadState::waitForResponse()
// android\frameworks\native\libs\binder\IPCThreadState.cpp
status_t IPCThreadState::waitForResponse(
Parcel *reply, // reply = ServiceManagerProxy.addSevice 中的 reply
// 该 reply 位于用户空间
status_t *acquireResult
){
uint32_t cmd;
int32_t err;
// 循环等待结果
while (1)
{
......
// 读取 mIn 中的指令(BR_REPLY)
cmd = (uint32_t)mIn.readInt32();
......
switch(cmd)
{
......
case BR_REPLY:
{
binder_transaction_data tr;
// 读取(位于内核空间的)reply 的信息
err = mIn.read(&tr, sizeof(tr));
......
//(位于用户空间的)reply 不为空,if 命中
if (reply)
{
// 此时 tr.flags = 0,if 命中
if ((tr.flags & TF_STATUS_CODE) == 0)
{
// 将(位于内核空间的)reply 写入(位于用户空间的)reply,
// 也就是写入 ServiceManagerProxy.addSevice 中的 reply
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
{
......
}
}
else
{
......
}
}
// 跳出循环
goto finish;
......
}
}
finish:
if (err != NO_ERROR)
{
if (acquireResult) *acquireResult = err;
if (reply) reply->setError(err);
mLastError = err;
}
return err;
}
当 IPCThreadState::waitForResponse
函数执行完成后,一直返回到 ServiceManagerProxy.addSevice
函数,继续执行
ServiceManagerProxy.addSevice()
// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException
{
......
// 执行返回处
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
// 回收 data 和 reply
reply.recycle();
data.recycle();
}
至此,整个流程结束
总结
按照指令的顺序,AMS 的注册流程大致如下图
按照调用栈的顺序,AMS 的注册流程大致如下图
大家结合流程图再去看代码流程可能会更加清晰一些