系统启动流程分析之Java层的ServiceManager的addService函数流程分析

865 阅读7分钟

「这是我参与2022首次更文挑战的第13天,活动详情查看:2022首次更文挑战」。

在SystemServer启动初始化流程中,会通过ServiceManager类的addService函数将Service添加到service_manager进程中处理,因此,今天来分析一下这个函数具体的作用和特性。 查看其函数,我们以两个参数的函数来启动

public static void addService(String name, IBinder service) {
    addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}

public static void addService(String name, IBinder service, boolean allowIsolated) {
    addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}

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

可以看到,在这边的函数最终会通过getIServiceManager函数获取一个IServiceManager的对象,然后再通过其addService函数来添加服务,因此

获取IServiceManager对象

通过getIServiceManager函数

private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }

    // Find the service manager
    sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

这个函数需要分为三个步骤来分析 1. BinderInternal.getContextObject 2. Binder.allowBlocking 3. ServiceManagerNative.asInterface 因此

BinderInternal.getContextObject

调用BinderInternal.getContextObject函数

@UnsupportedAppUsage
public static final native IBinder getContextObject();

调用了Native的函数,这个Native函数的定义在哪儿呢? 我们知道,在zygote启动SystemServer的过程中,会初始化Java虚拟机,并且通过startReg函数注册一些Native函数

/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    ......
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    ......
    return 0;
}

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    for (size_t i = 0; i < count; i++) {
        if (array[i].mProc(env) < 0) {
            return -1;
        }
    }
    return 0;
}

static const RegJNIRec gRegJNI[] = {
	......
	// 注册JNI函数
	REG_JNI(register_android_os_Binder),
	......
}

而这个register_android_os_Binder函数在android_util_Binder.cpp文件中实现,因此

int register_android_os_Binder(JNIEnv* env) {
	......
	if (int_register_android_os_BinderInternal(env) < 0)
    	return -1;
	......
}

const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";

static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

    gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
    gBinderInternalOffsets.mProxyLimitCallback = GetStaticMethodIDOrDie(env, clazz, "binderProxyLimitCallbackFromNative", "(I)V");

    jclass SparseIntArrayClass = FindClassOrDie(env, "android/util/SparseIntArray");
    gSparseIntArrayOffsets.classObject = MakeGlobalRefOrDie(env, SparseIntArrayClass);
    gSparseIntArrayOffsets.constructor = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject,
                                                           "<init>", "()V");
    gSparseIntArrayOffsets.put = GetMethodIDOrDie(env, gSparseIntArrayOffsets.classObject, "put",
                                                   "(II)V");

    BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);

    return RegisterMethodsOrDie(
        env, kBinderInternalPathName,
        gBinderInternalMethods, NELEM(gBinderInternalMethods));
}

static const JNINativeMethod gBinderInternalMethods[] = {
    /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    ......
};

因此,此处的Java层的BinderInternal.getContextObject函数和这边的android_os_BinderInternal_getContextObject函数建立了索引,因此,

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

首先,调用ProcessState::self()->getContextObject(NULL)函数,在此前分析CPP层的Binder机制的时候,有分析过,最终会返回一个 new BpBinder(0, -1) 然后就是javaObjectForIBinder函数调用

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    // N.B. This function is called from a @FastNative JNI method, so don't take locks around
    // calls to Java code or block the calling thread for a long time for any reason.
	// val为指向BpBinder的指针,不为NULL
    if (val == NULL) return NULL;
	// 分析此处为false
    if (val->checkSubclass(&gBinderOffsets)) {
        // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }
	// 初始化BinderProxyNativeData指针对象,并传递其参数
    BinderProxyNativeData* nativeData = new BinderProxyNativeData();
    nativeData->mOrgue = new DeathRecipientList;
    nativeData->mObject = val;

	// 根据前述的int_register_android_os_BinderProxy函数
	// gBinderProxyOffsets.mClass对应的Java侧的android.os.BinderProxy类
	// gBinderProxyOffsets.mGetInstance对应的是BinderProxy.getInstance函数
	// 且参数为上述初始化的指向BinderProxyNativeData的指针地址
	// 和前述的指向BpBinder的指针地址
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    if (env->ExceptionCheck()) {
        // In the exception case, getInstance still took ownership of nativeData.
        return NULL;
    }
    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
    if (actualNativeData == nativeData) {
        // Created a new Proxy
        uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
        uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
        if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
            // Multiple threads can get here, make sure only one of them gets to
            // update the warn counter.
            if (gProxiesWarned.compare_exchange_strong(numLastWarned,
                        numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
                ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
            }
        }
    } else {
        delete nativeData;
    }

    return object;
}

可以看到,此处会调用到BinderProxy的getInstance函数,并返回其返回值

private static BinderProxy getInstance(long nativeData, long iBinder) {
    BinderProxy result;
    synchronized (sProxyMap) {
        try {
		   // 从sProxyMap中获取iBinder对应的Value
            result = sProxyMap.get(iBinder);
            if (result != null) {
                return result;
            }
		   // 上述显然是没有获取到对应的值,因此此处通过new初始化一个BinderProxy对象
		   // 注意,其参数是一个Native层的指针地址,指向Native层的BinderProxyNativeData结构体
            result = new BinderProxy(nativeData);
        } catch (Throwable e) {
            // We're throwing an exception (probably OOME); don't drop nativeData.
            NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
                    nativeData);
            throw e;
        }
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
        // The registry now owns nativeData, even if registration threw an exception.
	    // 添加iBinder和BinderProxy对象到sProxyMap中
        sProxyMap.set(iBinder, result);
    }
    return result;
}

也就是说,BinderInternal对象的getContextObject函数最终返回的是一个BinderProxy对象, 1.在这个对象中包含一个名称为sProxyMap的ProxyMap对象,将Native层传入的BpBinder对象作为key,BinderProxy对象作为Value,存入该ProxyMap对象中, 2.同时,BinderProxy对象中包含有一个名称为mNativeData的long对象,其对应的是Native层的一个指向BinderProxyNativeData结构体的指针,这个指针对象中有两个参数,如下

nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = new BpBinder(0, -1);

Binder.allowBlocking

public static IBinder allowBlocking(IBinder binder) {
    try {
        if (binder instanceof BinderProxy) {
            ((BinderProxy) binder).mWarnOnBlocking = false;
        } else if (binder != null && binder.getInterfaceDescriptor() != null
                && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
            Log.w(TAG, "Unable to allow blocking on interface " + binder);
        }
    } catch (RemoteException ignored) {
    }
    return binder;
}

由于传入参数为一个BinderProxy对象,因此此处直接设置BinderProxy.mWarnOnBlocking参数的值为false,最终依旧返回BinderProxy对象

ServiceManagerNative.asInterface

最后调用的是ServiceManagerNative的asInterface函数

public static IServiceManager asInterface(IBinder obj) {
    if (obj == null) {
        return null;
    }

    // ServiceManager is never local
    return new ServiceManagerProxy(obj);
}

此处传入参数为BinderProxy对象,然后此处会通过new的方式初始化一个ServiceManagerProxy对象

public ServiceManagerProxy(IBinder remote) {
    mRemote = remote;
    mServiceManager = IServiceManager.Stub.asInterface(remote);
}

在ServiceManagerProxy对象构造函数中,传递BinderProxy对象,并赋值参数mRemote,然后通过IServiceManager.Stub.asInterface函数初始化一个IServiceManager对象,那么此处的IServiceManager.Stub.asInterface函数返回的是什么呢?

IServiceManager.Stub.asInterface函数的本质

如果理解Binder机制的肯定会了解,Binder机制由服务端和客户端组成,那么在IServiceManager.Stub.asInterface返回的是IServiceManager的客户端,而其对应函数传入的参数为服务端 也就是说,在如下这段代码中

mServiceManager = IServiceManager.Stub.asInterface(remote);

mServiceManager参数对应的是此次Binder机制通信的客户端,而传入的参数remote对应的是服务端 也就是说,在Binder机制中,此时调用IServiceManager对象参数名mServiceManager对应的函数时,最终会通过IServiceManager的服务端将消息送出去

总结

getIServiceManager函数,最终返回的是一个ServiceManagerProxy对象,

  1. 这个对象继承自IServiceManager类,它内部有一个IServiceManager对象参数,名称为mServiceManager
  2. ServiceManagerProxy.mServiceManager参数对应的是IServiceManager的Binder机制的一个客户端参数,而IServiceManager对应的Binder机制的服务端为一个BinderProxy对象
  3. 在上述对应关系中的BinderProxy对象中包含一个名称为sProxyMap的ProxyMap对象,将Native层传入的BpBinder对象作为key,BinderProxy对象作为Value,存入该ProxyMap对象中,同时,BinderProxy对象中包含有一个名称为mNativeData的long对象,其对应的是Native层的一个指向BinderProxyNativeData结构体的指针,这个指针对象中有两个参数,如下
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = new BpBinder(0, -1);

IServiceManager的addService对象

通过如上的描述,此时

IServiceManager.Stub.asInterface(remote)

返回的是一个ServiceManagerProxy对象,且这个对象中包含一个类型为IServiceManager的mServiceManager参数 因此,当getIServiceManager()的函数addService被调用的时候,就会调用ServiceManagerProxy对象的addService函数

public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
        throws RemoteException {
    mServiceManager.addService(name, service, allowIsolated, dumpPriority);
}

mServiceManager对应的是Binder机制的客户端,其调用addService的时候,会调用到服务端的transact函数

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
    Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
    // 在getIServiceManager函数中有分析过,在Binder.allowBlocking函数中,会将mWarnOnBlocking的值设置为false
    if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)
            && Binder.sWarnOnBlockingOnCurrentThread.get()) {

        // ...... 无法进入的分支,代码省略
    }
    // ...... 功能无关代码,省略
    final AppOpsManager.PausedNotedAppOpsCollection prevCollection =
            AppOpsManager.pauseNotedAppOpsCollection();
    // ...... 功能无关代码,省略
    try {
        // 最终会调用到Native层的transactNative函数
        return transactNative(code, data, reply, flags);
    } finally {
        // ...... 功能无关代码,省略
    }
}

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

而transactNative函数实现在android_utils_Binder.cpp文件中

const char* const kBinderProxyPathName = "android/os/BinderProxy";

static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    // ...... 功能无关代码,此处省略
    jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
            "(JJ)Landroid/os/BinderProxy;");
    gBinderProxyOffsets.mSendDeathNotice =
            GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
                                   "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
    gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");

    clazz = FindClassOrDie(env, "java/lang/Class");
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

    return RegisterMethodsOrDie(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}

static const JNINativeMethod gBinderProxyMethods[] = {
     // ......
    {"transactNative",      "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
    // ......
};

也就是说,Java层的BinderProxy.transactNative函数索引和这边的android_os_BinderProxy_transact函数索引绑定,最后

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
    // ...... 

    Parcel* data = parcelForJavaObject(env, dataObj);
    // ...... 判空操作代码省略
    Parcel* reply = parcelForJavaObject(env, replyObj);
    // ...... 判空操作代码省略
    // 还记得这边的getBPNativeData(env, obj)获取到的BinderProxyNativeData指针对象是什么么?
    // 在BinderProxy函数初始化的时候设定的
    // nativeData->mOrgue = new DeathRecipientList;
    // nativeData->mObject = new BpBinder(0, -1);
    // 可以看到,此处的target参数指针指向的是new BpBinder(0, -1)
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    // ...... 判空操作代码省略

    // ...... 功能无关代码省略
    // 此处会调用new BpBinder(0, -1)对象的transact函数,这样就跟Native层的service_manager建立了联系
    status_t err = target->transact(code, *data, reply, flags);
    // ...... 功能无关代码省略
    if (err == NO_ERROR) {
        return JNI_TRUE;
    } else if (err == UNKNOWN_TRANSACTION) {
        return JNI_FALSE;
    }

    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
    return JNI_FALSE;
}

可以看到,最终调用的是Native层new BpBinder(0, -1)对象的transact函数,跟Native层的添加Service服务流程一致,在Native层的分析,在网上有很多实例,此处不再详细分析

更新一张上述分析的对应类图

classDiagram
ServiceManager <|-- ServiceManagerProxy
IServiceManager <|-- ServiceManagerProxy
ServiceManagerProxy o-- BinderProxy : mRemote
ServiceManagerProxy -- ServiceManagerNative
BinderProxy -- android_utils_Binder
android_utils_Binder o-- BinderProxyNativeData
<<struct>> BinderProxyNativeData
<<interface>> IServiceManager
class ServiceManager {
    -sServiceManager : IServiceManager
    -getIServiceManager()
    +getService()
    +addService()
    +checkService
}
class ServiceManagerProxy {
    -mRemote : IBinder
    -mServiceManager : IServiceManager
    +asBinder()
    +getService()
    +checkService()
    +addService()
}
class BinderProxy {
    +mNativeData : long
    +transact()
}
class BinderProxyNativeData {
    +mObject: sp<IBinder>
    +mOrgue : sp<DeathRecipientList>
}
class ServiceManagerNative {
    +asInterface()
    -ServiceManagerNative()
}

更新一张上述分析的流程图 图片.png