在Binder通信建立后,Client端可能需要知道Server端的存活状态。当Server端挂掉时,Client端需要清理与通信相关的数据和行为,这个清理过程就是通过Binder死亡通知机制实现的。

注册死亡通知

应用层通过调用BpBinder::linkToDeath()来注册死亡通知。Native Binder通信可以直接调用这个接口,Java通信需要通过Jni来调用。

frameworks/base/core/jni/android_util_Binder.cppstatic void android_os_BinderProxy_linkToDeath(JNIEnv* env, jobject obj,         jobject recipient, jint flags) // throws RemoteException{    ......    // 获取BpBinder对象    IBinder* target = (IBinder*)        env->GetLongField(obj, gBinderProxyOffsets.mObject);                                                                                                                                                    ......    // 只有远程传输需要注册死亡通知    if (!target->localBinder()) {        // 获取死亡通知队列        DeathRecipientList* list = (DeathRecipientList*)                env->GetLongField(obj, gBinderProxyOffsets.mOrgue);        // 创建JavaDeathRecipient对象,将其加入到死亡回收队列        sp<JavaDeathRecipient> jdr = new JavaDeathRecipient(env, recipient, list);        // 调用BpBinder::linkToDeath()来建立死亡通知        status_t err = target->linkToDeath(jdr, NULL, flags);        ......    }    }

处理死亡通知的是JavaDeathRecipient,它继承IBinder::DeathRecipient,接收到死亡通知时会回调binderDied()。

frameworks/base/core/jni/android_util_Binder.cppclass JavaDeathRecipient : public IBinder::DeathRecipient{public:    JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),          mObjectWeak(NULL), mList(list)    {        ......            // 加入到回收队列        list->add(this);        android_atomic_inc(&gNumDeathRefs);        // 增加对象引用计数,当创建对象个数达到200时强行出发GC        incRefsCreated(env);    }        void binderDied(const wp<IBinder>& who)     {            if (mObject != NULL) {            JNIEnv* env = javavm_to_jnienv(mVM);                                                                                                                                                                        // 调用Java的sendDeathNotice方法            env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,                    gBinderProxyOffsets.mSendDeathNotice, mObject);            ......            // 释放全局引用,增加弱引用,以便GC回收            mObjectWeak = env->NewWeakGlobalRef(mObject);            env->DeleteGlobalRef(mObject);            mObject = NULL;        }        }

Java的注册过程最终也是指向到BpBinder中。死亡通知的注销也同样在这里,一起看一下。

frameworks/native/libs/binder/BpBinder.cppstatus_t BpBinder::linkToDeath(    const sp<DeathRecipient>& recipient, void* cookie, uint32_t flags){    Obituary ob;     ob.recipient = recipient;    ob.cookie = cookie;    ob.flags = flags;    ......        // 如果死亡通知已经发出,mObitsSent将被设置        if (!mObitsSent) {            // 第一个死亡通知将创建mObituaries,并向驱动注册死亡通知                                                                                                                                                                                              if (!mObituaries) {                mObituaries = new Vector<Obituary>;                ......                getWeakRefs()->incWeak(this);                // 向驱动注册死亡通知                IPCThreadState* self = IPCThreadState::self();                self->requestDeathNotification(mHandle, this);                self->flushCommands();            }            // 加入到mObituaries中            ssize_t res = mObituaries->add(ob);            return res >= (ssize_t)NO_ERROR ? (status_t)NO_ERROR : res;        }    ......}status_t BpBinder::unlinkToDeath(    const wp<DeathRecipient>& recipient, void* cookie, uint32_t flags,    wp<DeathRecipient>* outRecipient){    ......    const size_t N = mObituaries ? mObituaries->size() : 0;    // 在mObituaries中查找相应的recipient    for (size_t i=0; i<N; i++) {        const Obituary& obit = mObituaries->itemAt(i);        if ((obit.recipient == recipient                    || (recipient == NULL && obit.cookie == cookie))                && obit.flags == flags) {            const uint32_t allFlags = obit.flags|flags;            if (outRecipient != NULL) {                *outRecipient = mObituaries->itemAt(i).recipient;            }            // 将死亡通知从mObituaries移除            mObituaries->removeAt(i);            // 如果是mObituaries中最后一个死亡通知,则像驱动注销死亡通知            if (mObituaries->size() == 0) {                ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);                // 与驱动交互                IPCThreadState* self = IPCThreadState::self();                self->clearDeathNotification(mHandle, this);                self->flushCommands();                delete mObituaries;                mObituaries = NULL;            }            return NO_ERROR;        }    }    ......}

Obituary翻译过来是讣告的意思,也就是死亡通知,这里用中文解释就有些混乱。一个Binder代理在驱动上只注册一次死亡通知,但是多个应用可以同时注册Obituary到Binder代理上。就是说一个Binder代理接收到死亡通知后可以告诉多个感兴趣的应用,但其都来源于一个死亡通知。真正注册和注销死亡通知是通过IPCThreadState实现的。

frameworks/native/libs/binder/IPCThreadState.cppvoid IPCThreadState::flushCommands()                                                                                                                                                                        {    if (mProcess->mDriverFD <= 0)        return;    // 向驱动发送命令,不需要回复    talkWithDriver(false);}......status_t IPCThreadState::requestDeathNotification(int32_t handle, BpBinder* proxy)                                                                                                                          {    // 注册死亡通知命令    mOut.writeInt32(BC_REQUEST_DEATH_NOTIFICATION);    mOut.writeInt32((int32_t)handle);    mOut.writePointer((uintptr_t)proxy);    return NO_ERROR;}status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy){    // 注销死亡通知命令    mOut.writeInt32(BC_CLEAR_DEATH_NOTIFICATION);    mOut.writeInt32((int32_t)handle);    mOut.writePointer((uintptr_t)proxy);    return NO_ERROR;}

接下来进入到驱动中,看看死亡通知命令的处理过程。

drivers/staging/android/binder.cstatic int binder_thread_write(struct binder_proc *proc,            struct binder_thread *thread,            binder_uintptr_t binder_buffer, size_t size,            binder_size_t *consumed){    ......        case BC_REQUEST_DEATH_NOTIFICATION:        case BC_CLEAR_DEATH_NOTIFICATION: {            uint32_t target;            binder_uintptr_t cookie;            struct binder_ref *ref;            struct binder_ref_death *death;            // 获取用户空间数据            if (get_user(target, (uint32_t __user *)ptr))                return -EFAULT;            ptr += sizeof(uint32_t);            if (get_user(cookie, (binder_uintptr_t __user *)ptr))                return -EFAULT;            ptr += sizeof(binder_uintptr_t);            // 根据handle获取binder引用            ref = binder_get_ref(proc, target, false);            ......            if (cmd == BC_REQUEST_DEATH_NOTIFICATION)                 ......                // 分配binder_ref_death结构                death = kzalloc(sizeof(*death), GFP_KERNEL);                ......                binder_stats_created(BINDER_STAT_DEATH);                // 初始化death工作队列                INIT_LIST_HEAD(&death->work.entry);                death->cookie = cookie;                ref->death = death;                // 如果proc死掉,发送死亡通知                if (ref->node->proc == NULL) {                    ref->death->work.type = BINDER_WORK_DEAD_BINDER;                    if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {                        list_add_tail(&ref->death->work.entry, &thread->todo);                    } else {                        list_add_tail(&ref->death->work.entry, &proc->todo);                        wake_up_interruptible(&proc->wait);                    }                }            } else {                ......                death = ref->death;                ......                // 清除binder引用的death                ref->death = NULL;                if (list_empty(&death->work.entry)) {                    // 加入清理死亡通知work到队列                    death->work.type = BINDER_WORK_CLEAR_DEATH_NOTIFICATION;                    if (thread->looper & (BINDER_LOOPER_STATE_REGISTERED | BINDER_LOOPER_STATE_ENTERED)) {                        list_add_tail(&death->work.entry, &thread->todo);                    } else {                        list_add_tail(&death->work.entry, &proc->todo);                        wake_up_interruptible(&proc->wait);                    }                } else {                    // 死亡通知已经发生,修改work的类型                    BUG_ON(death->work.type != BINDER_WORK_DEAD_BINDER);                    death->work.type = BINDER_WORK_DEAD_BINDER_AND_CLEAR;                }            }        } break;    ......}

死亡通知的注册过程就是创建一个binder_ref_death结构,赋值给Binder引用的death上,Binder实体死亡时会根据death发送死亡通知。注销死亡通知的过程就是清理Binder引用的death,并创建一个清理的work。

drivers/staging/android/binder.cstatic 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){    ......        case BINDER_WORK_DEAD_BINDER:        case BINDER_WORK_DEAD_BINDER_AND_CLEAR:        case BINDER_WORK_CLEAR_DEATH_NOTIFICATION: {            struct binder_ref_death *death;            uint32_t cmd;            death = container_of(w, struct binder_ref_death, work);            if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION)                // 注销时回复这个命令                cmd = BR_CLEAR_DEATH_NOTIFICATION_DONE;            Else                // Binder死亡时回复这个命令                cmd = BR_DEAD_BINDER;            ......            if (w->type == BINDER_WORK_CLEAR_DEATH_NOTIFICATION) {                // 注销时释放death                list_del(&w->entry);                kfree(death);                binder_stats_deleted(BINDER_STAT_DEATH);            } else                list_move(&w->entry, &proc->delivered_death);            if (cmd == BR_DEAD_BINDER)                goto done; /* DEAD_BINDER notifications can cause transactions */        } break;    ......}

发送死亡通知

Binder进程退出或异常终止时都会调用exit流程,在Binder驱动中会调用到binder_release。Release中会启动一个BINDER_DEFERRED_RELEASE内核workqueue,这里进行具体的清理工作。

drivers/staging/android/binder.cstatic int binder_release(struct inode *nodp, struct file *filp){    struct binder_proc *proc = filp->private_data;    debugfs_remove(proc->debugfs_entry);    // 启动workqueue    binder_defer_work(proc, BINDER_DEFERRED_RELEASE);                                                                                                                                                           return 0;}static int binder_node_release(struct binder_node *node, int refs){    ......    list_del_init(&node->work.entry);    binder_release_work(&node->async_todo);    ......    // 循环处理binder实体中的每一个引用    hlist_for_each_entry(ref, &node->refs, node_entry) {        ......        if (list_empty(&ref->death->work.entry)) {            // 将Binder死亡work加入到进程的todo队列            ref->death->work.type = BINDER_WORK_DEAD_BINDER;            list_add_tail(&ref->death->work.entry,                      &ref->proc->todo);            wake_up_interruptible(&ref->proc->wait);        } else            BUG();    }    ......}static void binder_deferred_release(struct binder_proc *proc){    ......    while ((n = rb_first(&proc->nodes))) {        struct binder_node *node;        node = rb_entry(n, struct binder_node, rb_node);        nodes++;        rb_erase(&node->rb_node, &proc->nodes);        // 释放Binder实体        incoming_refs = binder_node_release(node, incoming_refs);    }    ......}

Binder驱动处理完release后会将BR_DEAD_BINDER命令发送给应用层。

frameworks/native/libs/binder/IPCThreadState.cppstatus_t IPCThreadState::executeCommand(int32_t cmd){    ......    case BR_DEAD_BINDER:                                                                                                                                                                                            {            BpBinder *proxy = (BpBinder*)mIn.readPointer();            // 调用Binder代理的sendObituary            proxy->sendObituary();            // 告诉驱动死亡通知已经处理            mOut.writeInt32(BC_DEAD_BINDER_DONE);            mOut.writePointer((uintptr_t)proxy);        } break;    ......}

Binder代理处理死亡回收工作,最终回调到binderDied()上。

frameworks/native/libs/binder/BpBinder.cppvoid BpBinder::sendObituary(){    ......    mLock.lock();    Vector<Obituary>* obits = mObituaries;    // 向驱动发送注销死亡通知命令    if(obits != NULL) {        ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);        IPCThreadState* self = IPCThreadState::self();        self->clearDeathNotification(mHandle, this);        self->flushCommands();        mObituaries = NULL;    }    // 设置flag,表明收到死亡通知       mObitsSent = 1;    mLock.unlock();    ......                                                                                                                                                                                   if (obits != NULL) {        const size_t N = obits->size();        // 循环给mObituaries中每一个向量发送死亡通知        for (size_t i=0; i<N; i++) {            reportOneDeath(obits->itemAt(i));        }        delete obits;    }   }void BpBinder::reportOneDeath(const Obituary& obit){    sp<DeathRecipient> recipient = obit.recipient.promote();    ALOGV("Reporting death to recipient: %p\n", recipient.get());    if (recipient == NULL) return;    // 调用上层应用死亡通知的binderDied    recipient->binderDied(this);}