Binder 浅析 —— AMS 获取流程

633 阅读5分钟

Binder 浅析 —— 整体概览

Binder 浅析 —— AMS 注册流程

这篇博客可以说是对于上一篇博客 ——《Binder 浅析 —— AMS 注册流程》的一个补充,其整体流程与 AMS 注册流程没有太多的不同,但还是有一些细节需要我们注意

(以下分析的是 Android 6.0 的源码)

APP 进程是如何获取 AMS 的?

以 bindService 的调用流程为例,获取 AMS 是从 ContextImpl.bindServiceCommon() 函数中开始的

(以下分析的只是获取 AMS 的流程,而不是 bindService 的流程)

调用栈如下:

ContextImpl.bindService()

--> ContextImpl.bindServiceCommon()

--> ActivityManagerNative.getDefault()

--> ServiceManager.getService("activity")

--> ServiceManager.getIServiceManager()

--> ServiceManagerProxy.getService()

ContextImpl.bindService()

// frameworks/base/core/java/android/app/ContextImpl.java
public boolean bindService(Intent service, ServiceConnection conn, int flags)
{
    ......
    return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}

ContextImpl.bindServiceCommon()

// frameworks/base/core/java/android/app/ContextImpl.java
private boolean bindServiceCommon(Intent service, ServiceConnection conn, 
                                  int flags, UserHandle user
){
    ......
    int res = ActivityManagerNative.getDefault().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());
    if (res < 0)
    {
        throw new SecurityException(
                    "Not allowed to bind to service " + service);
    }
    return res != 0;
    ......
}

ActivityManagerNative.getDefault()

// frameworks/base/core/java/android/app/ActivityManagerNative.java
static public IActivityManager getDefault()
{
    return gDefault.get();
}

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>()
{
    protected IActivityManager create()
    {
        IBinder b = ServiceManager.getService("activity");
        ......
        IActivityManager am = asInterface(b);
        ......
        return am;
    }
};

Singleton 是一个单例类,当外部调用了 Singleton.get() 函数时,如果对应的泛型对象没有被创建,就会回调内部的 Singleton.create() 函数来创建单例对象

ServiceManager.getService("activity")
// frameworks/base/core/java/android/os/ServiceManager.java
public static IBinder getService(String name)
{
    ......
    getIServiceManager().getService(name);
    ......
}

ServiceManager.getIServiceManager 函数在上一篇博客中介绍过了,这里就不再重复阐述了

传送门

ServiceManagerProxy.getService()
// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public IBinder getService(String name)
{
    // 创建 data
    Parcel data = Parcel.obtain();
    // 创建 reply
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    // 将 AMS 名称写入 data
    data.writeString(name);
    // mRemote = BinderProxy,相当于调用到 BinderProxy.transact
    mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
    IBinder binder = reply.readStrongBinder();
    reply.recycle();
    data.recycle();
    return binder;
}

APP 进程是如何发送数据给 SM 的?

// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public IBinder getService(String name)
{
    // 创建 data
    Parcel data = Parcel.obtain();
    ......
    // mRemote = BinderProxy,相当于调用到 BinderProxy.transact
    mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
    ......
}

调用栈如下:

BinderProxy.transact()

--> BpBinder::transact()

--> IPCThreadState::transact()

--> IPCThreadState::waitForResponse()

--> IPCThreadState::talkWithDriver()

--> binder_ioctl_write_read()

--> binder_thread_write()

--> binder_transaction()

--> binder_thread_read()

其中的大部分在上一篇博客中就已经介绍了,这里就不再重复阐述了

传送门

除了 mOut 中的数据不同之外,调用流程都是相同的

SM 进程被唤醒后做了什么?

SM 进程被唤醒后,继续执行未完成的 binder_thread_read 函数

调用栈如下:

binder_thread_read()

--> binder_loop()

--> binder_parse()

--> service_manager.svcmgr_handler()

--> binder_send_reply()

--> binder_ioctl_write_read()

--> binder_thread_read()

其中的大部分在上一篇博客中就已经介绍了,这里就不再重复阐述了

传送门

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 = GET_SERVICE_TRANSACTION = 1 = SVC_MGR_GET_SERVICE
    switch(txn->code)
    {
        ......
        case SVC_MGR_GET_SERVICE:
        case SVC_MGR_CHECK_SERVICE:
            // 从 mOut 数据部分中获取 AMS 的名称
            s = bio_get_string16(msg, &len);
            ......
            // 根据 AMS 的名称进行查找,获取 AMS 引用(handle)
            handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
            ......
            // 构建一个 flat_binder_object,将 AMS 引用(handle)写入其中进行封装,
            // 再将 flat_binder_object 写入 reply 中
            bio_put_ref(reply, handle);
            return 0;
        ......
    }
}

do_find_service()

// frameworks/native/cmds/servicemanager/service_manager.c
uint32_t do_find_service(struct binder_state *bs, 
                         const uint16_t *s, size_t len, uid_t uid, pid_t spid
){
    // 查找 AMS 是否在 SM 注册过,如果注册过就返回保存的 Service 信息
    struct svcinfo *si = find_svc(s, len);
    ......
    // 返回 AMS 的引用(handle)
    return si->handle;
}

bio_put_ref()

// frameworks/native/cmds/servicemanager/binder.c
void bio_put_ref(
    	struct binder_io *bio, // reply
    	uint32_t handle
){
    struct flat_binder_object *obj;
    // 此时 if 命中
    if (handle)
        // 构建一个 flat_binder_object,再将 flat_binder_object 写入 reply 中
        obj = bio_alloc_obj(bio);
    else
        obj = bio_alloc(bio, sizeof(*obj));

    if (!obj)
        return;

    obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    obj->type = BINDER_TYPE_HANDLE;
    // 将 AMS 引用(handle)写入 flat_binder_object 中
    obj->handle = handle;
    obj->cookie = 0;
}

APP 进程被唤醒后做了什么?

APP 进程被唤醒后,继续执行未完成的 binder_thread_read 函数

返回栈如下:

binder_thread_read()

--> binder_ioctl_write_read()

--> IPCThreadState::talkWithDriver()

--> IPCThreadState::waitForResponse()

--> IPCThreadState::transact()

--> BinderProxy.transact()

--> ServiceManagerProxy.getService()

--> reply.readStrongBinder()

--> ServiceManager.getService("activity")

其中的大部分在上一篇博客中就已经介绍了,这里就不再重复阐述了

传送门

reply.readStrongBinder()

// frameworks/base/core/java/android/os/Parcel.java
public final IBinder readStrongBinder()
{
    return nativeReadStrongBinder(mNativePtr);
}

// frameworks/base/core/jni/android_os_Parcel.cpp
static const JNINativeMethod gParcelMethods[] = {
    ......
    {"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
    ......
}

static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, 
                                                  jclass clazz, 
                                                  jlong nativePtr
){
    // 将 Java 层的 Parcel 类型(Java的Parcel)对象强制类型转换成 Native 层的 Parcel 类型对象(Native的Parcel)
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL)
    {
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}

Parcel::readStrongBinder()

// frameworks/native/libs/binder/Parcel.cpp
sp<IBinder> Parcel::readStrongBinder() const
{
    sp<IBinder> val;
    unflatten_binder(ProcessState::self(), *this, &val);
    return val;
}

status_t unflatten_binder(const sp<ProcessState>& proc,
                          const Parcel& in, // reply
                          sp<IBinder>* out
){
    // 从 reply 中读取出 flat_binder_object
    const flat_binder_object* flat = in.readObject(false);
    // 此时 if 命中
    if (flat)
    {
        // 此时 flat->type = BINDER_TYPE_HANDLE
        switch (flat->type)
        {
            // 当请求 Service 的进程与 Service 同属一个进程
            case BINDER_TYPE_BINDER:
                *out = reinterpret_cast<IBinder*>(flat->cookie);
                return finish_unflatten_binder(NULL, *flat, in);
            // 当请求 Service 的进程与 Service 分属不同进程
            case BINDER_TYPE_HANDLE:
                // 创建 BpBinder 对象
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);
        }
    }
    return BAD_TYPE;
}

ProcessState::getStrongProxyForHandle()

// frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getStrongProxyForHandle(
    	int32_t handle // AMS 的引用(handle)
){
    sp<IBinder> result;
    ......
    // 创建 BpBinder 对象,handle 为 AMS
    b = new BpBinder(handle); 
    ......
    result = b;
    ......
    return result;
}

finish_unflatten_binder()

// frameworks/native/libs/binder/Parcel.cpp
inline static status_t finish_unflatten_binder(
    BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
    const Parcel& /*in*/)
{
    return NO_ERROR;
}

Parcel::readStrongBinder() 函数会创建一个 BpBinder 对象,其 handle 为 AMS

javaObjectForIBinder()

// frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env, 
                            const sp<IBinder>& val // val = BpBinder
){
    ......
    
    // 从 gBinderProxyOffsets 中查找 BinderProxy 对象
    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 对象对应的是 AMS

reply.readStrongBinder() 函数会返回一个 BinderProxy 对象,其在 Native 层绑定了一个 BpBinder 对象(对应 AMS)

总结

按照调用栈的顺序,AMS 的获取流程大致如下图

大家结合流程图再去看代码流程可能会更加清晰一些