Android ActivityManagerService 注册到 Service Manager 的流程(上)

前面两章学习分析了 ServiceManager 的启动流程与获取它代理对象的流程, 本章节开始对 Service 组件启动后注册到 ServiceManager 的流程进行分析.

前言

Service 组件是在 Server 进程中运行的. Server 进程在启动时, 会首先将它里面的 Service 组件注册到 SM 中, 接着再启动一个 Binder 线程池来等待和处理 Client 进程的通信请求.
本章内容以 ActivityManagerService 为例, 一步步分析它是怎么从启动到注册到 SM 中的. 在AMS 服务的的时候不会太详细, 后面会有单独的章节来分析它. 重点在于是如何注册到 SM 中的.

首先是先来到系统服务 SystemServer 中. 看它的 main 方法

一. AMS 的启动

1. SystemServer.main

源码路径 /frameworks/base/services/java/com/android/server/SystemServer.java

 public static void main(String[] args) {
   new SystemServer().run();
 }

在内部看到又调用了 run

2. SystemServer.run

源码路径 /frameworks/base/services/java/com/android/server/SystemServer.java

private void run() {
    ...
    mSystemServiceManager = new SystemServiceManager(mSystemContext);
    ...
    try {
            //启动引导类服务
02        startBootstrapServices();
          //启动核心类服务
          startCoreServices();
          //启动其他服务
          startOtherServices();
    } catch (Throwable ex) {
        ...
    }
    ...
}

这里会先创建 SystemServiceManager 对象, 这个后面会分析到, 直接进入到 2 处 startBootstrapServices(). AMS 属于引导类服务, 很多服务也都依赖 AMS.

3. SystemServer.startBootstrapServices() 在启动引导类服务中创建 AMS.

源码路径 /frameworks/base/services/java/com/android/server/SystemServer.java

private void startBootstrapServices() {
    ...
01   mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
    ...
02  mActivityManagerService.setSystemProcess();
    ...
}

在代码 01 处, 看到调用了 mSystemServiceManager.startService 传入的参数是 Class, 那么猜想应该是用来反射的. 进去看一下 startService 这个函数.

4. SystemServiceManager.startService 传入 ActivityManagerService.Lifecycle.class

源码路径: /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java


    private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();

    public <T extends SystemService> T startService(Class<T> serviceClass) {
        final String name = serviceClass.getName();
        ...
        final T service;
        try {
01          Constructor<T> constructor = serviceClass.getConstructor(Context.class);
02          service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
          ...  
        } 
        ...

03      mServices.add(service);
        try {
04         service.onStart();
        } catch (RuntimeException ex) {
            ...
        }
        return service;
    }

代码 01 处 与 02 处创建了 ActivityManagerService.Lifecycle 对象, 并赋值给变量 service.
代码 03 处将这个创建的 ActivityManagerService.Lifecycle 对象添加到变量 mServices 中. 在最上面看到 mServices 是一个集合. 保存的内容就是 SystemService 类型的.
代码 04 处, 调用 ActivityManagerService.LifecycleonStart 函数.

找到 ActivityManagerService.Lifecycle 看一下它的构造函数和 onStart 函数.

5. ActivityManagerService.Lifecycle() & ActivityManagerService.Lifecycle.onStart()

源码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java


public final class ActivityManagerService extends ActivityManagerNative
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
  ...
  public static final class Lifecycle extends SystemService {
      private final ActivityManagerService mService;

      public Lifecycle(Context context) {
          super(context);
          mService = new ActivityManagerService(context);
      }

      @Override
      public void onStart() {
          mService.start();
      }

      public ActivityManagerService getService() {
          return mService;
      }
  }
  ...

Lifecycle 是 AMS 中的一个静态内部类. 在构造函数内可以看到, 是在这里创建了 ActivityManagerService 并保存到 mService 中.

然后在上面第4步中调用的 service.onStart(); 实际上调用的就是 ActivityManagerService.start() 函数.

接着将 AMS 添加到 SM 中. 回到第 3 步中. getService() 获得了 AMS 对象, 接着在 02 行代码处将 AMS 添加至 SM 中.

private void startBootstrapServices() {
    ...
01   mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
    ...
02  mActivityManagerService.setSystemProcess();
    ...
}

二. 将 ActivityManagerService 添加至 ServiceManager

6. mActivityManagerService.setSystemProcess()

源码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void setSystemProcess() {
     ...
   ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
   ...
}

终于看到了 addService 函数的调用. 进入 ServiceManager.addService 看是如何添加的.
其中 Context.ACTIVITY_SERVICE 的定义为 public static final String ACTIVITY_SERVICE = "activity";
`

7. ServiceManager.addService

源码路径: /frameworks/base/core/java/android/os/ServiceManager.java

public static void addService(String name, IBinder service, boolean allowIsolated) {
    try {
        getIServiceManager().addService(name, service, allowIsolated);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
}

先调用 ServiceManager 类的静态成员函数 getIServiceManager 来获得一个 ServiceManager 的 Java 代理对象 ServiceManagerProxy. 接着再调用这个 Java 代理对象的成员函数 addService 将 AMS 注册到 SM 中. 指定了这个 Service 的注册名称为 activity.

这里通过两步来分析先来看 getIServiceManager

8. getIServiceManager 获得 SM 的代理对象

源码路径: /frameworks/base/core/java/android/os/ServiceManager.java

  private static IServiceManager sServiceManager;

  private static IServiceManager getIServiceManager() {
      if (sServiceManager != null) {
          return sServiceManager;
      }
      ...
      sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
      return sServiceManager;
  }

首先判断 ServiceManager.java 类的静态成员变量 sServiceManager 是否为 NULL, 不为 NULL 说明之前已经获创建过代理对象. 所以直接返回给调用者.
否则就先通过 BinderInternal 类的静态成员函数 getContextObject 创建一个句柄值等等于 0 的 Java 服务代理对象, 接着再通过 ServiceManagerNative.asInterface 函数将这个 Java 服务代理对象封装成一个 ServiceManagerProxy 对象.保存在 sServiceManager 中并返回给调用者.

下面分别分析BinderInternal.getContextObject()ServiceManagerNative.asInterface

9. BinderInternal.getContextObject()

BinderInternal 类的静态成员函数 getContextObject 是一个 JNI 方法, 定义如下
源码路径: /frameworks/base/core/java/com/android/internal/os/BinderInternal.java

public static final native IBinder getContextObject();

它是由 C++ 层中的函数 android_os_BinderInternal_getContextObject() 来实现的.
源码路径: /frameworks/base/core/java/jni/android_util_Binder.cpp

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

看到这里, 终于看到熟悉的了 ProcessState::self()->getContextObject. 如果看过上一章, 对这个肯定不会陌生.
这行代码就是创建一个 BpBinder 对象. 接着调用 javaObjectForIBinder 对这个 Binder 代理对象创建一个 Java 服务代理对象, 即一个 BinderProxy 对象. 返回给调用者.

10. javaObjectForIBinder 创建 Java 服务代理对象

源码路径: /frameworks/base/core/java/com/android/internal/os/BinderInternal.java

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
      if (val == NULL) return NULL;
  
          //检查是 Binder 代理对象还是 本地丢西
      if (val->checkSubclass(&gBinderOffsets)) {
         ...
      }


01    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
      if (object != NULL) {
02        jobject res = jniGetReferent(env, object);
          if (res != NULL) {
                ...
              return res;
          }
          
                    ...
03        val->detachObject(&gBinderProxyOffsets);
          ...
      }

04    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
      if (object != NULL) {
05        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
06          val->incStrong((void*)javaObjectForIBinder);

          jobject refObject = env->NewGlobalRef(
            env->GetObjectField(object, gBinderProxyOffsets.mSelf));
07          val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup);
                ...
      }

      return object;
}

代码 01 处调用 Binder 代理对象(BpBinder) val 的成员函数 findObject 来检查当前进程之前是否已经创建过一个 Java 服务代理对象了(BinderProxy), 如果是接着在代码 02 处接着检查它的有效性, 如果未失效则直接返回给调用者. 如果失效就在代码 03 处调用 Binder 代理对象(BpBinder) val 的成员函数 detachObject 来解除它与一个无效 Java 服务代理对象(BinderProxy) 的对应关系.

如果代码 01 处检查之前没有创建过一个 Java 服务代理对象(BinderProxy), 在代码 04 处就会为它创建一个 Java 服务代理对象(BinderProxy) object. 如果创建成功, 接着来在代码 05 处将 Binder 代理对象(BpBinder) val 的地址值设置到上一步创建的 Java 服务代理对象(BinderProxy) object 的成员变量 mObject 中. 即 BinderProxy.mObject 记录了 BpBinder 对象. 因此在代码 06 处增加 Binder 代理对象(BpBinder) val的强引用计数, 因为它被 Java 服务代理对象(BinderProxy) object 引用了

代码 07 处通过全局变量 gBinderProxyOffsets 将这个全局引用对象与 Binder 代理对象(BpBinder) val 关联起来. 相当于将创建的 Java 服务代理对象(BinderProxy) object 与 Binder 代理对象(BpBinder)的 val 关联起来. 这样以后再以 Binder 代理对象(BpBinder) val 为参数来调用函数 javaObjectForIBinder 时, 就可以直接获得保存在它内部的成员变量 mObjects 中的 Java 服务代理对象(BinderProxy) 了.

Binder 代理对象内部有一个成员变量 mObjects, 类型是 ObjectManager, 用来管理与 Binder 代理对象关联的外部对象. 例如 javaObjectForIBinder函数在为一个 Binder 代理对象创建一个 Java 服务代理对象时, 就会将创建出来的 Java 服务代理对象保存在该 Binder 代理对象的成员变量 mObjects 中, 以便以后需要获取与该 Binder 代理对象对应的 Java 服务代理对象时, 就可以通过它的成员变量 mObjects 来直接获得. 由于一个 Binder 代理对象所关联的外部对象可能不止一个, 因此需要通过额外的一个参数来关联一个 Binder 代理对象和一个 Java 服务代理对象, 这个参数就是全局变量 gBinderProxyOffsets 的地址值.

注: Java 服务代理对象即: BinderProxy.
注: Binder 代理对象级: BpBinder.

最后返回这个 Java 服务代理对象. 接着回到第 8 步. 继续向下分析.
BinderInternal.getContextObject() 已经分析完了, 它返回了一个句柄值等于 0 的Java 服务代理对象. 接下来就可以调用 ServiceManagerNative 类的静态成员函数 asInterface 将它封装成一个 ServiceManager 的 Java 代理对象了

  private static IServiceManager sServiceManager;

  private static IServiceManager getIServiceManager() {
      if (sServiceManager != null) {
          return sServiceManager;
      }
      ...
      sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
      return sServiceManager;
  }

11. ServiceManagerNative.asInterface 创建 ServiceManagerProxy 对象

源码路径: /frameworks/base/core/java/android/os/ServiceManagerNative.java

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

    return new ServiceManagerProxy(obj);
}

参数 obj 指向的是一个 Java 服务代理对象.即一个 BinderProxy 对象. 它的成员函数 queryLocalInterface的返回值为 NULL, 因此最后会创建一个 ServiceManagerProxy 代理对象. 即 SM 的 Java 代理对象. 返回给调用者.

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

ServiceManagerProxy 构造方法中将传入的Java 服务代理对象赋值给 ServiceManagerProxy 中的类成员变量 mRemote.

注: mRemote 指向的是句柄值是 0 的 Java 服务代理对象, 即 BinderProxy, BinderProxy 在第 10 步被创建出来后又与 Binder 代理对象 BpBinder 进行了关联.

现在第8步分析完成了, 最终返回了一个 Java 代理对象 ServiceManagerProxy, 继续向上返回, 返回到第 7 步. 代码如下.

public static void addService(String name, IBinder service, boolean allowIsolated) {
    try {
        getIServiceManager().addService(name, service, allowIsolated);
    } catch (RemoteException e) {
        Log.e(TAG, "error in addService", e);
    }
}

看到又调用了 ServiceManagerProxy 中的函数 addService, 其中参数 name 对应的值为 activity. service 为 AMS 对象.

12. ServiceManagerProxy.addService

源码路径: frameworks/base/core/java/android/os/ServiceManagerNative.java$ServiceManagerProxy.java

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

创建了两个 Parcel 对象 datareply, data 是用来封装进程间通信数据的, reply 是用来封装进程间通信结果数据的.

代码 01 处调用 Parcel 对象 data 的成员函数 writeInterfaceToken 写入一个进程间通信头.
代码 02 处是写入即将要注册的 Java 服务的名称. 这里的名称为 activity.
代码 03 处写入要注册的 Java 服务对象.
代码 04 处调用成员变量 mRemotetransact 函数向 SM 发送一个类型为 ADD_SERVICE_TRANSACTION 的进程间通信请求, 即请求 SM 将一个 Java 服务注册进去.

mRemote 在第 11 步中有强调过. 它指向一个句柄值为 0 的 Java 服务代理对象 BinderProxy.

这里呢先来分析 data.writeStrongBinder 看是如何将 AMS 写入到 data 中的.
接着再来看 mRemote.transact 是如何处理这个进程间通信请求的.

Parcel 是用来封装进程间通信数据的, Java 层中的每一个 Parcel 对象在 C++层中都有一个对应的 Parcel 对象, 后者的地址就保存在前者的成员变量 mObject 中. 当将进程间通信的数据封装在一个 Java 层的 Parcel 对象时, 这个 Java 层中的 Parcel 对象就会通过其成员变量 mObject 找到与它对应的运行在 C++ 层中的 Parcel 对象.并且将这些进程间通信数据封装到 C++ 层中的 Parcel 对象里面去.

13. Parcel.writeStrongBinder

Java 层的 writeStrongBinder 是一个 JNI 方法. 定义如下
源码路径: /frameworks/base/core/java/android/os/Parcel.java

public final void writeStrongBinder(IBinder val) {
    nativeWriteStrongBinder(mNativePtr, val);
}

对应的实现函数为 android_os_Parcel_writeStrongBinder.

14. android_os_Parcel.android_os_Parcel_writeStrongBinder

源码路径: /frameworks/base/core/jni/android_os_Parcel.cpp

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

代码 01 处. 调用函数 reinterpret_cast 得到一个与 Java 层 Parcel 对应的, 运行在 C++ 层的 Parcel 对象 parcel.

代码 02 处先调用函数 ibinderForJavaObject 来获得一个与他对应的 Binder 本地对象, 再将这个 Binder 本地对象写入到上一步得到的 C++层的 Parcel 对象 parcel 中.

这里也分为两步. 先看 ibinderForJavaObject 如何获得一个对应的 Binder 本地对象的.
接着再分析 writeStrongBinder 写入.

15. android_util_Binder.ibinderForJavaObject

源码路径: /frameworks/base/core/jni/android_util_Binder.cpp

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    ...
    //是否是 Java 服务
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
01      JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;
    }
    //是否是 Java 服务代理对象
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }
  ...
  return NULL;
}

这两个 if 意思是 参数 obj 要么指向一个 Java 服务, 要么指向一个 Java 服务代理对象. 否则最后会返回 NULL, 表示它不能将参数 obj 转换成一个 Binder 本地对象或者 Binder 代理对象.

此时我们传入的 obj 是 AMS, 即是一个 Java 服务.所以命中第一个 if. gBinderOffsets.mObject 指向的是一个 Java 服务的成员变量 mObject 中保存的与其对应的一个 JavaBBinderHolder 对象.

代码 01 处就是将参数 obj 即 AMS 服务对象的成员变量 mObject 转换为一个 JavaBBinderHolder 对象 jbh.
接着调用 JavaBBinderHolder 对象的 jbh 的成员函数 get 来获得一个 Binder 本地对象 BBinder.

如果传入的 obj 是一个 Java 服务代理对象, 那么命中第二个 if, 就找到与它对应的一个 Binder 代理对象. 并将这个 Binder 代理对象返回给调用者. 在上面第 10 步中的 05 行代码处创建好 Java 服务代理后将 Binder 代理服务对象的地址保存在 Java 服务代理对象的成员变量 mObject 中. 因此这里可以轻易的根据 Java 服务代理对象 BinderProxy 找到与之对应的 Binder 代理对象 BpBinder.

16. JavaBBinderHolder.get 获得 BBinder

源码路径: /frameworks/base/core/jni/android_util_Binder.cpp$JavaBBinderHolder

class JavaBBinderHolder : public RefBase
{
private:
    ...
    wp<JavaBBinder> mBinder;

public:
    sp<JavaBBinder> get(JNIEnv* env, jobject obj)
    {
        ...
        sp<JavaBBinder> b = mBinder.promote();
        if (b == NULL) {
            b = new JavaBBinder(env, obj);
            mBinder = b;
            ...
        }

        return b;
    }
}

成员变量 mBinder 指向的是一个类型为 JavaBBinder 的 Binder 本地对象.
参数 obj 指向的是一个 Java 服务即 AMS 服务.

成员函数 get 用来将成员变量 mBinder 所指向的一个JavaBBinder 对象返回给调用者. 由于成员变量 mBinder是一个弱指针, 此时可能已经被销毁, 因此在返回给调用者之前, 先要调用 mBinder.promote() 将它升级为一个强指针, 如果升级成功, 直接返回给调用者.

否则就需要先创建一个 JavaBBinder 对象, 将 AMS 服务传入, 同时将结果保存在成员变量 mBinder 中.

17. new JavaBBinder

源码路径: /frameworks/base/core/jni/android_util_Binder.cpp$JavaBBinder

class JavaBBinder : public BBinder
{
private:
    ...
    jobject const   mObject;

public:
    JavaBBinder(JNIEnv* env, jobject object)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {
        ALOGV("Creating JavaBBinder %p\n", this);
        android_atomic_inc(&gNumLocalRefs);
        incRefsCreated(env);
    }
...
}

JavaBBinder 的 Binder 本地对象内部也有一个成员变量 mObject, 指向的是一个 Java 服务. 在构造函数中被初始化. 流程走到这里 mObject 指向的就是 AMS 服务.

好了, 第 14 步中的 ibinderForJavaObject 分析完了, 返回了一个了一个 JavaBBinder 对象. 第 14 步代码如下

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

接着调用 parcel->writeStrongBinder 函数, 传入参数为 JavaBBinder对象.

18. parcel->writeStrongBinder

源码路径: /frameworks/native/libs/binder/Parcel.cpp

status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}

这一步操作是调用全局函数 flatten_binderJavaBBinder 封装成为一个 flat_binder_object 结构体.

19. parcel->flatten_binder

源码路径: /frameworks/native/libs/binder/Parcel.cpp

status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;
        ...
    if (binder != NULL) {
        IBinder *local = binder->localBinder();
        if (!local) {
            ...
        } else {
            obj.type = BINDER_TYPE_BINDER;
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);
        }
    } else {
       ...
    }
    return finish_flatten_binder(binder, obj, out);
}

首先定义了一个 flat_binder_object 结构体 obj. 接着判参数 binder 是否为 NULL, 我们传入的参数是 JavaBBinder 对象不为 NULL, 所以直接命中 if.

通过前面的调用知道参数 binder 指向的是 JavaBBinder, 它继承了 BBinder. 而 BBinder 又是用来描述一个 Binder 本地对象的. 因此 localBinder 函数返回不为 NULL. 所以 if(!local) 不会命中, 而是直接执行 else 中的代码. 将flat_binder_object 结构体 obj 设置为一个 BINDER_TYPE_BINDER 类型的 Binder 对象, 并且将它的成员变量 cookiebinder 的值分别设置为 Binder 本地对象 local 的地址以及其内部的一个弱引用计数对象的地址值.

最后调用全局函数 finish_flatten_binderobj 写入到 Parcel 对象 out 中.

当结构体 flat_binder_object 描述的是一个 Binder 实体对象时, 就使用成员变量 binder 来指向与该 Binder 实体对象对应的一个 Service 组件内部的一个弱引用计数对象的地址, 并且使用成员变量 cookie 来指向该 Service 组件的地址.

当结构体 flat_binder_object 描述的是一个 Binder 引用对象时, 那么就使用成员变量 handle 来描述该 Binder 引用对象的句柄值.

20. parcel->finish_flatten_binder

源码路径: /frameworks/native/libs/binder/Parcel.cpp

inline static status_t finish_flatten_binder(
    const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
{
    return out->writeObject(flat, false);
}

至此, 在第 12 步中的 data.writeStrongBinder(service); 到这里就分析完了. 在第 12 步中传入的 AMS 服务, 到最后写入的实际上是一个 flat_binder_object 结构体. 接下来继续分析第 12 步中的下一个操作. 第 12 步代码如下

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

代码 04 处调用成员变量 mRemote 的 transact 函数向 SM 发送一个类型为 ADD_SERVICE_TRANSACTION 的进程间通信请求, 即请求 SM 将一个 Java 服务注册进去. mRemote 即 BinderProxy. 指向一个句柄值为 0 的 Java 服务代理对象.

21. BinderProxy.transact 开始发送进程间通信请求.

BinderProxy 类的成员函数 transact 是一个 JNI 方法. 定义如下

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
    return transactNative(code, data, reply, flags);
}

public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException;

对应的实现在 android_util_Binder.cpp 中的 android_os_BinderProxy_transact 函数.

22. android_util_Binder.android_os_BinderProxy_transact

源码路径 /frameworks/base/core/jni/android_util_Binder.cpp

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
      ...
01    Parcel* data = parcelForJavaObject(env, dataObj);
      ...
02    Parcel* reply = parcelForJavaObject(env, replyObj);
      ...
03    IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
      ...
04    status_t err = target->transact(code, *data, reply, flags);
      ...
}

代码 01 处与 02 处分别将 Java 层中的两个 Parcel 对象 dataObj, replyObj 转为 C++层中的 Parcel 对象data ,reply . data 中包含了要传递给 SM 的进程间通信数据, reply 用来保存从 SM 返回的数据结果.

参数 obj 指向的是一个 Java 服务代理对象, 即 BinderProxy.
代码 03 处就是获得这个代理对象的 Binder 代理对象. 即 BpBinder. 保存到变量 target 中.

代码 04 处调用 target 的成员函数 transact 想 SM 发送一个类型为 code 的进程间通信请求. code 值为 ADD_SERVICE_TRANSACTION. 当 SM 收到这个进程间通信请求后, 就会将保存在 Parcel对象 data 中的一个 Binder 本地对象的信息取出来后注册到它的内部去. 那现在进入到 BpBinder 的 transact 函数内.

data 中保存的 Binder 本地对象信息即在第 13 - 20 步中写入的 flat_binder_object 结构体, 在 19 步中将这个结构体的成员变量 cookie 设置为 Binder 本地对象. 这个本地对象是在 17 步中创建的 JavaBBinder.

23. BpBinder.transact

源码路径: /frameworks/native/libs/binder/BpBinder.cpp

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

从前面的调用过程可以知道, 第一个参数 code 值为 ADD_SERVICE_TRANSACTION, 第二个参数 data 包含了要传递给 Binder 驱动程序进程间通信数据. 第三个参数 reply 是一个输出参数, 用来保存进程间通信的结果. 第四个参数 flags 用来描述这是一个同步的进程间通信请求还是异步的. 默认值为 0, 表示同步.

成员变量 mAlive 用来描述 Binder 代理对象所引用的 Binder 本地对象是否还活着, 如果还活着,即值为 1. 在 if内才会调用当前线程的 IPCThreadState 对象的成员函数 transact 想 Binder 驱动发送一个 BC_TRANSACTION 命令协议.

Binder 代理对象中的成员变量 mHandle 用来描述该 Binder 代理对象的句柄值. 由于目前正在处理的 Binder 代理对象指向的是 SM 的代理对象. 因此 mHandle 的值就等于 0.

现在进入 IPCThreadStatetransact 函数.

24.IPCThreadState.transact 向 Binder 驱动程序发送 BC_TRANSACTION 命令协议

源码路径: /frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
01    status_t err = data.errorCheck();
02    flags |= TF_ACCEPT_FDS;
          ...
       if (err == NO_ERROR) {
         ...
03       err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
      }
          ...    
04    if ((flags & TF_ONE_WAY) == 0) {
                ...
          if (reply) {
05            err = waitForResponse(reply);
          } else {
              ...
          }
                ...
      } else {
         ...
      }
      
      return err;
}

代码 01 处是检查 Parcel 对象 data 中的进程间通信数据是否正确.

代码 02 处将参数 flagTF_ACCEPT_FDS 位设置为 1, 表示允许 Server 进程在返回结果中携带文件描述.
如果 data 中的数据没有问题, 执行代码 03 处. 调用成员函数 writeTransactionData 将它的内容写到一个 binder_transaction_data 结构体中.

代码 04 处判断是同步请求还是异步请求, 本次为同步请求, 接着判断用来保存通信结果的 reply 是否为 NULL, 不为 NULL 就调用成员函数 waitForResponse 向 Binder 驱动程序发送一个 BC_TRANSACTION 命令协议.

接下来主要是分析两个函数, writeTransactionDatawaitForResponse 的实现

25. IPCThreadState.writeTransactionData

源码路径: /frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
01    binder_transaction_data tr;

      ...
      tr.target.handle = handle;
      tr.code = code;
      tr.flags = binderFlags;
          ...
        
02    const status_t err = data.errorCheck();
      if (err == NO_ERROR) {
          tr.data_size = data.ipcDataSize();
          tr.data.ptr.buffer = data.ipcData();
          tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
          tr.data.ptr.offsets = data.ipcObjects();
      } else if (statusBuffer) {
         ...
      } else {
              ...
      }
03    mOut.writeInt32(cmd);
04    mOut.write(&tr, sizeof(tr));
    return NO_ERROR;
}

在代码 01 处, 先定义了一个 binder_transaction_data 结构体 tr, 接着下面几行代码就对它进行了初始化操作. 经过前面调用已知 handle = 0, code = ADD_SERVICE_TRANSACTION, binderFlags = TF_ACCEPT_FDS.

代码 02 处再次确认 data 中进程间通信数据的正确性. 如果没有问题则命中if.
data 内部的数据缓冲区和偏移数组设置为 binder_transaction_data 结构体 tr 的数据缓冲区与偏移数组.

代码 03 与 04 处将 BC_TRANSACTION 命令协议以及 binder_transaction_data 写入到 IPCThreadState 成员变量 mOut 所描述的一个命令协议缓冲区中. 表示它有一个 BC_TRANSACTION命令协议需要发送给 Binder 驱动程序处理.

BC_TRANSACTION 命令协议写入到 IPCThreadState类内部的命令协议缓冲区后, 回到 第 24 步. 接下来就需要调用成员函数 waitForResponse 向 Binder 驱动程序发送这个命令协议了.

26. IPCThreadState.waitForResponse

源码路径: /frameworks/native/libs/binder/IPCThreadState.cpp

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    uint32_t cmd;
    int32_t err;

    while (1) {
        if ((err=talkWithDriver()) < NO_ERROR) break;
       ...
    }
    return err;
}

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

OK. 其实一路分析到这里, 才算是开始. 现在进入 talkWithDriver

27. IPCThreadState.talkWithDriver

源码路径: /frameworks/native/libs/binder/IPCThreadState.cpp

 //参数 doReceive 用来描述调用者是否希望函数 talkWithDriver  
 //只接受 Binder 驱动程序发送给该进程的返回协议. 该参数默认为 `true`. 
 status_t IPCThreadState::talkWithDriver(bool doReceive)
{
        ...
    //talkWithDriver 函数使用 IO 控制命令 BINDER_WRITE_READ 来与 Binder 驱动程序进行交互
    //因此这里需要先定义一个结构体来指定输入缓冲区和输出缓冲区.
    //其中输出缓冲区是保存的是进程发给 Binder 驱动程序的命令协议, 
    //而输入缓冲区保存的是 Binder 驱动程序发送给进程的返回协议, 
    //它们分别与 `IPCThreadState` 类内部的命令协议缓冲区 `mOut` 和返回协议缓冲区 `mIn` 相对应.
    binder_write_read bwr;
    
 01   const bool needRead = mIn.dataPosition() >= mIn.dataSize();
    
 02   const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
      
      //将变量 write_size 的值设置为 binder_write_read 结构体 bwr 的
      //输出缓冲区的长度 write_size     
      bwr.write_size = outAvail;

      //将 IPCThreadState 类内部的命令协议缓冲区 mOut 
      //设置为 binder_write_read 结构体 bwr 的输出缓冲区.
      bwr.write_buffer = (uintptr_t)mOut.data();

03    if (doReceive && needRead) {
        bwr.read_size = mIn.dataCapacity();
        bwr.read_buffer = (uintptr_t)mIn.data();
      } else {
        bwr.read_size = 0;
        bwr.read_buffer = 0;
      }
    ...
04    do {
        ...
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
                ...
 05   } while (err == -EINTR);
    ...
    if (err >= NO_ERROR) {
06        if (bwr.write_consumed > 0) {
            if (bwr.write_consumed < mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
07        }
        if (bwr.read_consumed > 0) {
             mIn.setDataSize(bwr.read_consumed);
 08          mIn.setDataPosition(0);
        }
        ...
        return NO_ERROR;
    }
    
    return err;
}

从前面的调用可知, mOut 中存在一个 BC_TRANSACTION 命令协议.

IPCThreadState 内部, 除了使用缓冲区 mOut 来保存即将要发送给 Binder 驱动程序的命令协议外, 还用缓冲区 mIn 来保存那些从 Binder 驱动程序接收到的返回协议

一个进程使用 IO 控制命令 BINDER_WRITE_READ 进入到 Binder 驱动程序, 传递的 binder_write_read 结构体的输出缓冲区和输入缓冲区的长度分别等于 0 和大于 0 时, Binder 驱动程序就不会处理进程发送的命令协议, 而只会对该进程发送返回命令协议, 这样进程就达到了接收返回协议的结果.

只接收返回协议还会受到返回协议缓冲区 mIn 的影响. 如果上次 Binder 发送给进程的返回协议已经处理完成, 即返回协议缓冲区 mIn 中的返回协议已经处理完成, 那么即使参数 doReceivetrue, IPCThreadState 的成员函数 talkWithDriver 也会向 Binder 驱动程序发送命令协议.

因此如果返回协议缓冲区 mIn 的返回协议已经处理完成, 即代码 01 处得到的 needRead 变量值为 true. 或者调用者不是只希望接收 Binder 驱动程序发送给进程的返回协议, 及参数 doReceivefalse, 那么代码 02 处就将变量 outAvail 的值设置为 IPCThreadState 类内部的命令协议缓冲区的长度. 否则就设置为 0.

从前面的调用过程可以知道, 参数 doReceive 的值为 true, 假设此时 IPCThreadState 类内部的返回协议缓冲区 mIn 没有包含未处理的返回协议, 那么 needRead 值为 true. 命中代码 03 处 if 判断. 在判断内将 binder_write_read结构体 bwr 的输入缓冲区 read_buffer设置为类内部的返回协议缓冲区 mIn.

代码 04 处到 05 处的 while 循环使用 IO 控制命令 BINDER_WRITE_READ 来与 Binder 驱动程序进行交互. 由于这时候传递给 Binder 驱动程序的 binder_write_read 结构体 bwr 输出缓冲区的长度 write_size 和 输入缓冲区 read_size 的长度均大于 0. 因此 Binder 驱动程序在处理 IO 控制命令 BINDER_WRITE_READ 时, 就会首先调用函数 binder_thread_write 来处理进程发送给它的 BC_TRANSACTION 命令协议. 接着又会调用函数 binder_thread_read 来读取 Binder 驱动程序给进程发送的返回协议.

当从驱动层返回后, 代码 06-07 处将 Binder 驱动程序已经处理的命令协议从 IPCThreadState 类内部的命令协议缓冲区 mOut 中移除, 接着在代码 08 处将从 Binder 驱动程序中读取出来的返回协议保存在类内部的返回协议缓冲区 mIn 中. 这样这个函数执行完再返回到第 26 步的时候. 就可以通过解析返回协议缓冲区 mIn 的内容来执行相对应的操作了.

现在就要进入到 Binder 驱动层了, 来分析是如何处理这个命令协议的.

28. binder_ioctl_write_read

源码路径: kernel 3.18下的 /drivers/staging/android/binder.c

static int binder_ioctl_write_read(struct file *filp,
                unsigned int cmd, unsigned long arg,
                struct binder_thread *thread)
{
    ...
    ...

        ret = binder_thread_write(proc, thread,
                      bwr.write_buffer,
                      bwr.write_size,
                      &bwr.write_consumed);
    ...
}

直接进入到 binder_thread_write 函数

29. binder_thread_write

源码路径: kernel 3.18下的 /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)
{

    while (ptr < end && thread->return_error == BR_OK) {
        switch (cmd) {
        ...
        case BC_TRANSACTION:
        case BC_REPLY: {
            ...
            binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0);
            break;
        }
        ...
        }
        *consumed = ptr - buffer;
    }
    return 0;
}

从代码中可以看出又调用了 binder_transaction 函数. 进入到这个函数. 传入的参数中
cmd == BC_REPLY 值为 false, 因为这个时候 cmd 的值为 BC_TRANSACTION.

30. binder_transaction

源码路径: kernel 3.18下的 /drivers/staging/android/binder.c
这个函数有点长, 将会分为四段来分析.

static void binder_transaction(struct binder_proc *proc,
                   struct binder_thread *thread,
                   struct binder_transaction_data *tr, int reply,
                   binder_size_t extra_buffers_size)
{
        struct binder_proc *target_proc;
        struct binder_node *target_node = NULL;
    ...
    if (reply) {
        ...
    } else {
        if (tr->target.handle) {
            ...
01      } else {
            target_node = context->binder_context_mgr_node;
            ...
        }
        ...
02      target_proc = target_node->proc;
                ...
    }
03  if (target_thread) {
        e->to_thread = target_thread->pid;
        target_list = &target_thread->todo;
        target_wait = &target_thread->wait;
    } else {
        target_list = &target_proc->todo;
        target_wait = &target_proc->wait;
    }

在上一步知道 replyfale , 所以直接进 else. 由于目标 Binder 的引用对象的句柄值为 0, 所以直接执行代码 01 处的 else 逻辑. 将目标 Binder 实体对象 target_node 指向一个引用了 SM 的 Binder 实体对象 binder_context_mgr_node. 如果进的是 if 就需要先获得与句柄值对应的 Binder 引用对象. 再通过这个引用对象的成员变量 node 来找到目标 Binder 实体对象 target_node.

binder_context_mgr_node 的赋值是在 上一章 Android Service Manager 的启动流程中的第6 步忘记的,可以返回去看一下.

找到了目标 Binder 实体对象以后, 代码 02 处就可以根据它的成员变量 proc 来找到目标进程 target_proc.

如果在目标进程 target_proc 中找到了一个最优的目标线程 target_thread 来接收 BR_TRANSACTION 返回协议那么就命中代码 03 处 if, 将变量 target_listtarget_wait 分别指向最优线程的 todowait 队列.. 否则就指向目标进程的 todowait 队列. 有了这两个队列后, 函数接下来就可以将一个 BR_TRANSACTION 返回协议相关的待处理工作项加入到 todo 队列中. 以及通过等待队列将目标进程或线程唤醒来处理这个工作项.

binder_transaction 函数第二部分代码

01  t = kzalloc(sizeof(*t), GFP_KERNEL);
    ...
02  tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
    ...
03  if (!reply && !(tr->flags & TF_ONE_WAY))
        t->from = thread;
    else
        t->from = NULL;
    ...
    ...
04  t->buffer = binder_alloc_buf(target_proc, tr->data_size, tr->offsets_size, extra_buffers_size, !reply && (t->flags & TF_ONE_WAY));
    ...
    if (target_node)
        binder_inc_node(target_node, 1, 0, NULL);
    ...
05  if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
               tr->data.ptr.buffer, tr->data_size)) {
    
    }
06  if (copy_from_user(offp, (const void __user *)(uintptr_t)
               tr->data.ptr.offsets, tr->offsets_size)) {
    }

代码 01 处分配一个 binder_transaction 结构体 t, 后面会将它封装为一个 BINDER_WORKTRANSACTION 类型的工作项加入到目标的 todo 队列中. 以便目标线程可以接收到一个 BR_TRANSACTION 返回协议.

代码 02 处分配了一个 binder_work 结构体 tcomplete. 后面会将它封装成一个 BINDER_WORK_TRANSACTION_COMPLETE 类型的工作项加入到源线程的 todo 队列中, 以便该线程知道可以马上返回用户空间. 并且知道它之前发送给 Binder 驱动程序的 BC_TRANSACTION 命令协议已经被接收了.

代码 03 处判断如果正在处理的是一个 BC_TRANSACTION 命令协议. 并不且它所描述的是一个同步的进程间通信请求, 那么命中 if 就会将 binder_transaction结构体 t的成员变量 from 指向源线程, 以便目标进程 target_proc 或者目标线程 target_thread 处理完该进程间通信请求之后, 能够找到发出改进程通信请求的线程. 最终将通信结果返回给它.

代码 04 处是为 binder_transaction 结构体 t 分配内核缓冲区, 以便可以将进程间通信结果拷贝到它里面, 最后传递给目标进程 target_proc 或者目标线程处理.

当前目标进程为 SM . 源线程/进程为 AMS

代码 05, 06 处是分别将 binder_transaction 结构体 tr 的数据缓冲区以及偏移数组的内容拷贝到在代码 04 处为 binder_transaction 结构体 t 分配的内核缓冲区中.

binder_transaction 函数第三部分代码

    for (; offp < off_end; offp++) {
        struct binder_object_header *hdr;
        ...
        switch (hdr->type) {
        case BINDER_TYPE_BINDER:
        case BINDER_TYPE_WEAK_BINDER: {
01          struct flat_binder_object *fp;
02          struct binder_ref *ref;
03          fp = to_flat_binder_object(hdr);
04          ret = binder_translate_binder(fp, t, thread);
            if (ret < 0) {
                return_error = BR_FAILED_REPLY;
                goto err_translate_failed;
            }
        } break;
        ...
    }

这整个 for 循环就是依次处理进程间通信数据中的 Binder 对象. 如果 Binder 驱动程序是第一次碰到这些 Binder 对象, 那么 Binder 驱动程序就会根据它们的类型分别创建一个 Binder 实体对象或者 Binder 引用对象.
否则, 就会将之前为他们创建的 Binder 实体对象或者 Binder 引用对象获取回来, 增加引用计数, 避免过早销毁.

代码 01 处定义一个 flat_binder_object 结构体 fp.

从第 19 步的调用可以知道, 进程间通信数据中包含一个类型为 BINDER_TYPE_BINDER 的 Binder 对象, 即一个 flat_binder_object 结构体. 用来描述即将要注册到 SM 中的 Service 组件 AMS.

代码 02 处定义一个 binder_ref 结构体 ref. 表示 Binder 的引用对象.

代码 03 处获取获取在 19 步写入的 flat_binder_object 结构体, 保存在 fp 中.

主要分析代码 04 处 binder_translate_binder 函数. 进去看一下

31. binder_translate_binder

源码路径: kernel 3.18下的 /drivers/staging/android/binder.c

static int binder_translate_binder(struct flat_binder_object *fp,
                   struct binder_transaction *t,
                   struct binder_thread *thread)
{
    ...
01  node = binder_get_node(proc, fp->binder);
02  if (!node) {
        ...
    }
    ...
03  ref = binder_get_ref_for_node(target_proc, node);
    ...
    if (fp->hdr.type == BINDER_TYPE_BINDER)
04      fp->hdr.type = BINDER_TYPE_HANDLE;
    else
        fp->hdr.type = BINDER_TYPE_WEAK_HANDLE;
    fp->binder = 0;
    fp->handle = ref->desc;
    fp->cookie = 0;
05  binder_inc_ref(ref, fp->hdr.type == BINDER_TYPE_HANDLE, &thread->todo);
        ...
    return 0;
}

代码 01 处获得 Binder 实体对象 node. 接着在代码 02 处判断是否为 NULL, 此处我们获得的 Binder 实体对象不为 NULL,

binder_get_node 函数是根据 flat_binder_object 结构体中弱引用计数对象的地址 binder 在目标进程 proc 中找到一个对应的 Binder 实体对象. 在第 19 步中被赋值.

在代码 03 处调用 binder_get_ref_for_node 函数, 在目标进程 target_proc 中创建一个 Binder 引用对象来引用该 Service 组件 AMS.

在代码 04 处将 flat_binder_object 结构体 fp 的类型修改为 BINDER_TYPE_HANDLE, 并设置好它的句柄值. 这是因为当 Binder 驱动程序将进程间通信数据传递给目标进程 target_proc 时, 进程间通信数据中的 Binder 实体对象就变量 Binder 引用对象. 所以需要修改它的类型.

在目标进程 target_proc 创建好一个 Binder 引用对象 ref 后, 接着就要将它传递给该目标进程了. 在传递过程中, 必须要保证 Binder 引用对象 ref 不会被销毁, 因此在代码 05 处调用函数 binder_inc_ref 来增加它的引用计数.

继续回到 binder_transaction中, 看第三部分代码

32. binder_transaction 发送进程间通信

第四部分代码

01 if (reply) {
        ...
02  } else if (!(t->flags & TF_ONE_WAY)) {
        t->need_reply = 1;
        t->from_parent = thread->transaction_stack;
        thread->transaction_stack = t;
    } else {
        ...
    }
03  t->work.type = BINDER_WORK_TRANSACTION;
04  list_add_tail(&t->work.entry, target_list);
05  tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
06  list_add_tail(&tcomplete->entry, &thread->todo);
07  if (target_wait)
08      wake_up_interruptible(target_wait);

代码 01 处值为 false 在第 29 步中有说明.
代码 02 处判断正常处理的是否是一个同步的进程间通信请求, 即 binder_transaction 接头体 t的成员变量 flagsTF_ONE_WAY 为等于 0. 那么命中 else if, 设置它的成员变量 need_reply 的值为 1, 表示它需要等待回复. 接着将事务 t 压入到源线程 thread 的事务堆栈 transaction_stack 中.

代码 03 与 04 处将 binder_transaction 结构体 t 封装成一个类型为 BINDER_WORK_TRANSACTION 的工作项添加到目标进程 target_proc 或者目标线程 target_threadtodo 队列中, 并且在 08 行代码处将目标进程唤醒, 以便处理该工作项.

Android Service Manager 的启动流程 一文中的第 12 步分析 3 处调用了 wait_event_freezable_exclusive 函数进行睡眠等待直到其所属的进程有新的未处理工作项. 所以接下来分析SM的时候, 直接从 binder_thread_read 处接着分析 SM 被唤醒后的操作.

如果目标进程 todo 队列 target_list 指向的是一个 Binder 实体对象的异步事务队列 async_todo, 那么目标 wait 等待队列 target_wait 就会等于 NULL, 这时候就不需要唤醒目标进程.

代码 05 与 06 行代码处将 binder_work 结构体 tcomplete 封装成一个类型为 BINDER_WORK_TRANSACTION_COMPLETE 的工作项添加到源线程的 todo 队列中, 以便它从 Binder 驱动程序返回到用户空间之前, 可以处理该工作项.

程序执行到这里, 源线程, 目标进程或者目标线程就会并发的去处理各自 todo 队列中的工作项. 为了方便描述,
假设源线程会首先它的 todo 队列中类型为BINDER_WORK_TRANSACTION_COMPLETE 的工作项.
接着目标进程再处理它队列中的类型为 BINDER_WORK_TRANSACTION 的工作项.

注:
此时源线程为 AMS 进程中请求注册 Service 组件的线程与目标进程 SM 需要处理的工作项类型如下

  • 源线程: ActivityManagerService 要处理的工作项类型为: BINDER_WORK_TRANSACTION_COMPLETE
  • 目标进程 SM. 需要处理的工作项类型为 BINDER_WORK_TRANSACTION.

未完待续......

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章