Installer启动分析

Installer启动分析

本篇继续解析pms前置installer服务的启动
系统启动之后init进程会解析各种.rc文件最后以service形式拉起zygote,zygote会fork各种系统服务,比如SystemServer,SystemServer会启动多种关键服务。
这里不再赘述init进程启动及zygote、SystemServer是如何启动

  • Installer服务
    • SystemServer是如何启动installer的
      • Installer启动
      • ServiceManager.getService(“installd”)
      • getIServiceManager()
        • BinderInternal.getContextObject()
          • ProcessState::getContextObject
          • javaObjectForIBinder
        • ServiceManagerNative#asInterface
      • ServiceManagerProxy#getService
        • BinderProxy#transact
        • Parcel#readStrongBinder
          • Parcel::readStrongBinder
      • Installer#invalidateMounts
      • InstalldNativeService::invalidateMounts
  • 总结

SystemServer是如何启动installer的

入口是在main函数
/frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {
    ...
    public static void main(String[] args) {
        new SystemServer().run();
    }
    ...
    private void run() {
        ...
        Looper.prepareMainLooper();
        ...
        startBootstrapServices();
        startCoreServices();
        startOtherServices();
        ...
        Looper.loop();
        ...
    }

    private void startBootstrapServices() {
        ...
        Installer installer = mSystemServiceManager.startService(Installer.class);
        ...
    }
    ...

}

略去部分细节,run主要启动各种服务,开启主线程Looper开启消息分发
Installer服务是在startBootstrapServices中启动的

Installer启动

接下来看SystemServiceManager#startService实现
/frameworks/base/services/java/com/android/server/SystemServiceManager.java

public class SystemServiceManager {
    ...
    public SystemService startService(String className) {
        final Class serviceClass;
        try {
            serviceClass = (Class)Class.forName(className);
        } catch (ClassNotFoundException ex) {
            ...
        }
        return startService(serviceClass);
    }
    ...
    public  T startService(Class serviceClass) {
        try {
            final String name = serviceClass.getName();
            ...
            //如果不是SystemService子类说明要启动的不是个系统服务
            if (!SystemService.class.isAssignableFrom(serviceClass)) {
                ...
            }
            final T service;
            try {
                Constructor constructor = serviceClass.getConstructor(Context.class);
                service = constructor.newInstance(mContext);
            } catch (InstantiationException ex) {
                ...
            } catch (IllegalAccessException ex) {
                ..
            } catch (NoSuchMethodException ex) {
                ...
            } catch (InvocationTargetException ex) {
                ...
            }

            startService(service);
            return service;
        } finally {
            ...
        }
    }
    ...
    public void startService(@NonNull final SystemService service) {
        // Register it.
        mServices.add(service);
        ...
        try {
            service.onStart();
        } catch (RuntimeException ex) {
            ...
        }
        ...
    }
    ...
}

  • 看到整个调用流程就是拿到Installer.class然后调用构造函数初始化一个Installer

  • 最后先cache要启动的Installer,然后调用service.onStart()去启动服务,先看Installer的实现
    /frameworks/base/services/java/com/android/server/pm/Installer.java

public class Installer extends SystemService {
    ...
    private final boolean mIsolated;
    ...
    public Installer(Context context) {
        this(context, false);
    }

    public Installer(Context context, boolean isolated) {
        super(context);
        mIsolated = isolated;
    }
    ...
    @Override
    public void onStart() {
        if (mIsolated) {
            ...
        } else {
            connect();
        }
    }

    private void connect() {
        //获取installd的proxy贼复杂
        IBinder binder = ServiceManager.getService("installd");
        if (binder != null) {
            try {
                //死亡通知重连
                binder.linkToDeath(new DeathRecipient() {
                    @Override
                    public void binderDied() {
                        ...
                        connect();
                    }
                }, 0);
            } catch (RemoteException e) {
                binder = null;
            }
        }

        if (binder != null) {
            mInstalld = IInstalld.Stub.asInterface(binder);
            try {
                invalidateMounts();
            } catch (InstallerException ignored) {
                ...
            }
        } else {
            ...
        }
    }
    ...
}

  • 这里三件件事,获取installd守护进程,设置binder的死亡通知,然后去调用invalidateMounts判断sdcard状态

  • 接下来分析调用流程,前方车速较快,乘客请做好

ServiceManager.getService(“installd”)

/frameworks/base/core/java/android/os/ServiceManager.java

public final class ServiceManager {
    ...
    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }
        // Find the service manager
        //BinderInternal.getContextObject() 拿到bpBinder(0)
        //之后对bpBinder(0)做一层封装返回BinderProxy
        sServiceManager = ServiceManagerNative
             .asInterface(Binder
             .allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

    ...
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(rawGetService(name));
            }
        } catch (RemoteException e) {
            ...
        }
        return null;
    }
    ...

    private static IBinder rawGetService(String name) throws RemoteException {
        ...
        final IBinder binder = getIServiceManager().getService(name);
        ...
        return binder;
    }
}

  • 首次调用sCache中如果没有缓存的server就通过rawGetService()去查找对应的服务

getIServiceManager()

getIServiceManager()调用比较复杂,我们先来看BinderInternal.getContextObject()实现

BinderInternal.getContextObject()

/frameworks/base/core/java/com/android/internal/os/BinderInternal.java

public class BinderInternal {
    ...
    public static final native IBinder getContextObject();
    ...
}

这个是个native方法,对应jni实现在/frameworks/base/core/jni/android_util_Binder.cpp

...
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    sp b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}
...
static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
    ...
};
...

jni中getContextObject对应的函数是android_os_BinderInternal_getContextObject,其中主要通过ProcessState::getContextObject(NULL)拿到bpBinder(0)也就是service_manager的代理对象,然后经过一层包装,最后返还给java层

ProcessState::getContextObject

/frameworks/native/libs/binder/ProcessState.cpp

...
sp ProcessState::getContextObject(const sp& /*caller*/)
{
    //这里传入的handle为0
    return getStrongProxyForHandle(0);
}
...
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp result;

    ...

    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {
        ...
        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            ...
            b = BpBinder::create(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            ...
        }
    }

    return result;
}
...

  • 可以看到实际上拿到的就是个BpBinder(0),具体流程可以参考笔者Binder分析那篇,这里不再赘述
javaObjectForIBinder

分析javaObjectForIBinder()实现之前,我们先来看一些jni初始化相关的java层引用
/frameworks/base/core/jni/android_util_Binder.cpp

...
static struct binderproxy_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mGetInstance;
    jmethodID mSendDeathNotice;

    // Object state.
    jfieldID mNativeData;  // Field holds native pointer to BinderProxyNativeData.
} gBinderProxyOffsets;
...
int register_android_os_Binder(JNIEnv* env)
{
    ....
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
    ...
}
...
const char* const kBinderProxyPathName = "android/os/BinderProxy";

static int int_register_android_os_BinderProxy(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, "java/lang/Error");
    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

    clazz = FindClassOrDie(env, kBinderProxyPathName);
    //BinderProxy
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    //BinderProxy#getInstance
    gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, 
        clazz, "getInstance", "(JJ)Landroid/os/BinderProxy;");
    ...
    //BinderProxy#mNativeData
    gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz,
         "mNativeData", "J");
    //Class
    clazz = FindClassOrDie(env, "java/lang/Class");
    //Class#getName
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, 
        "getName", "()Ljava/lang/String;");

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

  • jni文件初始化时候会去解析拿到BinderProxy的class、getInstance、mNativeData等信息并存到gBinderProxyOffsets这个struct中
    接下来看javaObjectForIBinder()的实现
    /frameworks/base/core/jni/android_util_Binder.cpp
BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
    return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
}
...

struct BinderProxyNativeData {

    // The native IBinder proxied by this BinderProxy.
    sp mObject;

    sp mOrgue;  // Death recipients for mObject.
};

...

jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
    //一系列校验
    ...

    //封装BinderProxyNativeData
    BinderProxyNativeData* nativeData = new BinderProxyNativeData();
    nativeData->mOrgue = new DeathRecipientList;
    nativeData->mObject = val;

    //调用BinderProxy#getInstance(nativeData,val.get())
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    if (env->ExceptionCheck()) {
        ...
        return NULL;
    }
    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
    ...

    return object;
}

  • 这里val指向的是bpBinder(0),这里构造了BinderProxyNativeData结构体用来存bpBinder(0)与死亡通知队列DeathRecipientList,之后通过调用BinderProxy#getInstance()将nativeData的地址及bpBinder(0)地址传入,最后经过数据初始化然后返回一个BinderProxy对象
    /frameworks/base/core/java/android/os/BinderProxy.java
public final class BinderProxy implements IBinder {
    ...
    private static BinderProxy getInstance(long nativeData, long iBinder) {
        BinderProxy result;
        synchronized (sProxyMap) {
            try {
                result = sProxyMap.get(iBinder);
                if (result != null) {
                    return result;
                }
                result = new BinderProxy(nativeData);
            } catch (Throwable e) {
                ...
            }
            ...
            sProxyMap.set(iBinder, result);
        }
        return result;
    }
    ...
}

BinderProxy#getInstance实际上就是cache了bpBinder(0)与BinderProxy对象的map,方便后续多次使用

ServiceManagerNative#asInterface

回到getIServiceManager(),Binder.allowBlocking只是将BinderProxy的mWarnOnBlocking置位false

public static IBinder allowBlocking(IBinder binder) {
        try {
            if (binder instanceof BinderProxy) {
                ((BinderProxy) binder).mWarnOnBlocking = false;
            }else if(...){
                ...
            }
        } catch (RemoteException ignored) {
        }
        return binder;
    }

最终ServiceManagerNative#asInterface拿到返回一个ServiceManagerProxy并赋值给sServiceManager
/frameworks/base/core/java/android/os/ServiceManagerNative.java

public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
    ...
    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        //obj就是持有BpBinder(0)的BinderProxy对象
        return new ServiceManagerProxy(obj);
    }
    ...
}

ServiceManagerProxy#getService

接下来我们看ServiceManagerProxy#getService
/frameworks/base/core/java/android/os/ServiceManagerNative.java

public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
    ...
    class ServiceManagerProxy implements IServiceManager {
        public ServiceManagerProxy(IBinder remote) {
            mRemote = remote;
        }
        ...
        public IBinder getService(String name) throws RemoteException {
            Parcel data = Parcel.obtain();
            Parcel reply = Parcel.obtain();
            data.writeInterfaceToken(IServiceManager.descriptor);
            data.writeString(name);
            mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
            //service_manager返回的installd对象
            IBinder binder = reply.readStrongBinder();
            reply.recycle();
            data.recycle();
            return binder;
        }
        ...
    }
    ...
}

ServiceManagerProxy是一个内部类,mRemote就是前文中提到的持有BpBinder(0)的BinderProxy对象,最终是一个跨进程通信,这里name是installd

BinderProxy#transact

BinderProxy最终会调用到transactNative,直接来看jni
/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}
    ...
}

-对应的JNI函数为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)
{
    ...
    Parcel* data = parcelForJavaObject(env, dataObj);
    ...
    Parcel* reply = parcelForJavaObject(env, replyObj);
    ...
    //前面存到BinderProxyNativeData中拿到bpBinder
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    ...
    status_t err = target->transact(code, *data, reply, flags);
    ...
}
...

这里实际上就是拿到前面获取过的BpBinder(0),然后调用BpBinder(0)#transact()去发起binder查找通信,service服务的查找清参考老罗的Android的Binder系列
回到ServiceManagerProxy#getService,最终会从ipc通信reply中拿到一个IBinder对象

Parcel#readStrongBinder

/frameworks/base/core/java/android/os/Parcel.java

public final class Parcel {
    ... 
    public final IBinder readStrongBinder() {
        return nativeReadStrongBinder(mNativePtr);
    }
    ...
}

查看jni调用
/frameworks/base/core/jni/android_os_Parcel.cpp

static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast(nativePtr);
    if (parcel != NULL) {
        //封装成BinderProxy返回给java层
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}
...
static const JNINativeMethod gParcelMethods[] = {
    ...
    {"nativeReadStrongBinder",    "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder}
    ...
}

android_os_Parcel_readStrongBinder主要是就是调用parcel->readStrongBinder拿到对应的BpBinder引用对象

Parcel::readStrongBinder

接下来我们来看是怎么解析到servce_manager返回的BpBinder代理对象的
/frameworks/native/libs/binder/Parcel.cpp

status_t Parcel::readStrongBinder(sp* val) const
{
    status_t status = readNullableStrongBinder(val);
    if (status == OK && !val->get()) {
        status = UNEXPECTED_NULL;
    }
    return status;
}

status_t Parcel::readNullableStrongBinder(sp* val) const
{
    return unflatten_binder(ProcessState::self(), *this, val);
}
...
status_t unflatten_binder(const sp& proc,
    const Parcel& in, sp* out)
{
    const flat_binder_object* flat = in.readObject(false);

    if (flat) {
        switch (flat->hdr.type) {
            case BINDER_TYPE_BINDER:
                *out = reinterpret_cast(flat->cookie);
                return finish_unflatten_binder(nullptr, *flat, in);
            case BINDER_TYPE_HANDLE:
                //前文分析过这个就是获取handle持有的BpBinder
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast(out->get()), *flat, in);
        }
    }
    return BAD_TYPE;
}

调用链readStrongBinder->readNullableStrongBinder->unflatten_binder,我在Binder那篇中关于binder通信数据传递有一张图

image.png

同样适用于这里,通过service_manager查找服务返回的type是BINDER_TYPE_HANDLE,这里不解释为啥,自己去看/frameworks/native/cmds/servicemanager/service_manager.c中查找服务的实现
回到android_os_Parcel_readStrongBinder,接下来调用javaObjectForIBinder讲查到的installd的BpBinder封装成一个BinderProxy返回给java层,在这之后Java层就可以通过这个BinderProxy与installd通信

Installer#invalidateMounts

回到Installer#connect中,有了installd的代理Binder对象以后,先绑定死亡通知重连,之后讲installd的代理Binder对象再包一层,赋值给mInstalld最后调用invalidateMounts
/frameworks/base/services/core/java/android/server/pm/installer.java

public class Installer extends SystemService {
    ...
    public void invalidateMounts() throws InstallerException {
        ...
        try {
            mInstalld.invalidateMounts();
        } catch (Exception e) {
            throw InstallerException.from(e);
        }
    }
    ...
}

mInstalld怎么去做ipc调用的不再细述,上一篇installd进程启动分析中,installd启动时候注册的Service是InstalldNativeService

InstalldNativeService::invalidateMounts

InstalldNativeService定义在/frameworks/native/cmds/installd/InstalldNativeService.h中,不再贴了读者感兴趣可以看其定义,直接来看invalidateMounts实现
/frameworks/native/cmds/installd/InstalldNativeService.cpp

...
binder::Status InstalldNativeService::invalidateMounts() {
    ENFORCE_UID(AID_SYSTEM);
    std::lock_guard lock(mMountsLock);
    //清理cache
    mStorageMounts.clear();

//BYPASS_QUOTA == 0
#if !BYPASS_QUOTA
    if (!InvalidateQuotaMounts()) {
        ...
    }
#endif
    //检查mounts授权
    std::ifstream in("/proc/mounts");
    if (!in.is_open()) {
        return error("Failed to read mounts");
    }

    std::string source;
    std::string target;
    std::string ignored;
    /**
     * tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,size=1812472k,nr_inodes=453118,mode=755 0 0
    devpts /dev/pts devpts rw,seclabel,relatime,mode=600,ptmxmode=000 0 0

     */
    while (!in.eof()) {
        //获取source devpts
        std::getline(in, source, ' ');
        //获取target路径 /dev/pts
        std::getline(in, target, ' ');
        std::getline(in, ignored);

#if !BYPASS_SDCARDFS
        //SDCARD 检查
        if (target.compare(0, 21, "/mnt/runtime/default/") == 0) {
            ...
            mStorageMounts[source] = target;
        }
#endif
    }
    return ok();
}
...
bool InvalidateQuotaMounts() {
    std::lock_guard lock(mMountsLock);

    mQuotaReverseMounts.clear();

    std::ifstream in("/proc/mounts");
    if (!in.is_open()) {
        return false;
    }

    std::string source;
    std::string target;
    std::string ignored;
    while (!in.eof()) {
        std::getline(in, source, ' ');
        std::getline(in, target, ' ');
        std::getline(in, ignored);

        if (source.compare(0, 11, "/dev/block/") == 0) {
            struct dqblk dq;
            //Get disk quota limits and current usage for user or group id
            if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0,
                    reinterpret_cast(&dq)) == 0) {
                ...
                mQuotaReverseMounts[target] = source;
            }
        }
    }
    return true;
}
...

  • /proc/monuts文件长这样
image.png

解析过程中,例如第一行中
source = proc
target = /proc
ignored = proc rw,relatime,gid=3009,hidepid=2 0 0

  • 首先调用InvalidateQuotaMounts去检查用户磁盘配额quotactl并存到mQuotaReverseMounts中

  • 然后去sdcard是否已经mount授权,并存到mStorageMounts中

总结

至此,整个installer就启动完成,总结下来,installer回去查installd守护进程并将获取到的Binder代理对象cache到mInstalld中便于后续交互通信,启动过程中如果binder不小心跪了,会有重连策略,初始化最终的目的是解析用户磁盘授权+sdcard的授权

你可能感兴趣的:(Installer启动分析)