Android源码分析挖掘(二) fork大师zygote进程

序言

上一篇Android源码分析挖掘(一) 开天辟地init进程分析了Android系统从按下开机键到init进程启动服务的过程,init进程启动了很多服务,如Zygote,ServiceManager,SurfaceFlinger等,本片分析一下Zygote进程被启动后都干了些啥。

上篇介绍了init进程通过init.rc文件启动了服务,那么Zygote服务是在init.rc哪一条指令被定义的呢,回到源码init.rc文件,路径:system/core/rootdir/init.rc

复制代码
# Copyright (C) 2012 The Android Open Source Project
#
# IMPORTANT: Do not create world writable files or directories.
# This is a common source of Android security bugs.
#

import /init.environ.rc
import /system/etc/init/hw/init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /system/etc/init/hw/init.usb.configfs.rc
import /system/etc/init/hw/init.${ro.zygote}.rc

...

可以看到,import /system/etc/init/hw/init.${ro.zygote}.rc,这一行的import的意思就是读取这个路径文件的所有内容,在init进程启动服务时,会一并启动。

在init.rc同目录下就能找到几个对应的文件:init.zygote32_64.rc、``init.zygote32.rc、``init.zygote64_32.rc、``init.zygote64.rc,具体import哪个文件与具体设备硬件有关,这里就以init.zygote64.rc分析,代码内容如下:

复制代码
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
    class main
    priority -20
    user root
    group root readproc reserved_disk
    socket zygote stream 660 root system
    socket usap_pool_primary stream 660 root system
    onrestart exec_background - system system -- /system/bin/vdc volume abort_fuse
    onrestart write /sys/power/state on
    onrestart restart audioserver
    onrestart restart cameraserver
    onrestart restart media
    onrestart restart netd
    onrestart restart wificond
    writepid /dev/cpuset/foreground/tasks
    critical window=${zygote.critical_window.minute:-off} target=zygote-fatal

暂时可以只关注第一行,简单点认为,可以认为启动了/system/bin/app_process64这个程序,后面携带了一系列参数,这些参数需要重点关注,因为关系到后续是启动SystemServer还是app:

复制代码
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server

那么这个zygote程序源码在哪里呢?可以通过以上启动systemserver参数的字符串全局查找一下,命令如下:

复制代码
grep "start-system-server" ./ -rn


//搜索结果
./base/cmds/app_process/app_main.cpp:200:    // --start-system-server : Start the system server.
./base/cmds/app_process/app_main.cpp:269:        } else if (strcmp(arg, "--start-system-server") == 0) {
./base/cmds/app_process/app_main.cpp:310:            args.add(String8("start-system-server"));
./base/core/java/com/android/internal/os/ZygoteInit.java:920:                if ("start-system-server".equals(argv[i])) {
./base/core/jni/AndroidRuntime.cpp:1195:    static const String8 startSystemServer("start-system-server");

可以看到有c++代码,也有java代码,但是由于此时虚拟机环境还没有建立,不可能进入到java代码中,所以源码一定是./base/cmds/app_process/app_main.cpp,查看源码:

复制代码
#if defined(__LP64__)
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist64";
static const char ZYGOTE_NICE_NAME[] = "zygote64";
#else
static const char ABI_LIST_PROPERTY[] = "ro.product.cpu.abilist32";
static const char ZYGOTE_NICE_NAME[] = "zygote";
#endif

int main(int argc, char* const argv[])
{
    //打印传入的参数日志
    if (!LOG_NDEBUG) {
      String8 argv_String;
      for (int i = 0; i < argc; ++i) {
        argv_String.append("\"");
        argv_String.append(argv[i]);
        argv_String.append("\" ");
      }
      ALOGV("app_process main with argv: %s", argv_String.string());
    }

    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
    ...
    int i;
    ...
    // Parse runtime arguments.  Stop at first unrecognized option.
    bool zygote = false;
    bool startSystemServer = false;
    String8 niceName;
    ...
    while (i < argc) {
        const char* arg = argv[i++];
        //如果参数中携带有--zygote,就把zygote置为true,并将nicName赋值为zygoteXX
        if (strcmp(arg, "--zygote") == 0) {
            zygote = true;
            niceName = ZYGOTE_NICE_NAME;
        //如果参数中携带有--start-system-server,就把startSystemServer置为true
        } else if (strcmp(arg, "--start-system-server") == 0) {
            startSystemServer = true;
        } else

        ...
    }

    Vector<String8> args;
    if (!className.isEmpty()) {
        ...
    } else {
        // We're in zygote mode.
        maybeCreateDalvikCache();
        //上面startSystemServer为true,args中加入start-system-server
        if (startSystemServer) {
            args.add(String8("start-system-server"));
        }
        ...

        //系统架构
        String8 abiFlag("--abi-list=");
        abiFlag.append(prop);
        args.add(abiFlag);

        // In zygote mode, pass all remaining arguments to the zygote
        // main() method.
        //把剩余参数都添加到Vector容器中
        for (; i < argc; ++i) {
            args.add(String8(argv[i]));
        }
    }

    //修改进程的名称为zygoteXX
    if (!niceName.isEmpty()) {
        runtime.setArgv0(niceName.string(), true /* setProcName */);
    }

    if (zygote) {
        //执行AndroidRuntime的start函数,并传入参数com.android.internal.os.ZygoteInit, args,true
        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
    } 
    ...
}

整体流程还是很简单的,基本可以概括为:

1.解析参数,检查参数中是否存在--zygote、--start-system-server

2.根据解析出来的内容,重新装填参数

2.将进程名称修改为zygoteXX

3.调用AndroidRuntime.start函数,并传入"com.android.internal.os.ZygoteInit",重新装填的参数和true

通过文件内搜索可知,AppRuntime继承自AndroidRuntime:

复制代码
class AppRuntime : public AndroidRuntime
{
    ...
}

故而分析AndroidRuntime代码,通过如下命令搜索:

复制代码
find -name AndroidRuntime.cpp

//搜索结果
./base/core/jni/AndroidRuntime.cpp

源码如下:

复制代码
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
    ALOGD(">>>>>> START %s uid %d <<<<<<\n",
            className != NULL ? className : "(unknown)", getuid());

    //配置环境变量
    ...
    /* start the virtual machine */
    JniInvocation jni_invocation;
    //加载libart.so
    jni_invocation.Init(NULL);
    JNIEnv* env;
    //启动VM
    if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
        return;
    }
    //回调AppRuntime重写的方法
    onVmCreated(env);

    /*
     * Register android functions.
     */
    //注册jni函数
    if (startReg(env) < 0) {
        ALOGE("Unable to register all android natives\n");
        return;
    }

    //将Vector转换为String数组
    /*
     * We want to call main() with a String array with arguments in it.
     * At present we have two arguments, the class name and an option string.
     * Create an array to hold them.
     */
    jclass stringClass;
    jobjectArray strArray;
    jstring classNameStr;

    stringClass = env->FindClass("java/lang/String");
    assert(stringClass != NULL);
    strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
    assert(strArray != NULL);
    classNameStr = env->NewStringUTF(className);
    assert(classNameStr != NULL);
    env->SetObjectArrayElement(strArray, 0, classNameStr);

    for (size_t i = 0; i < options.size(); ++i) {
        jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
        assert(optionsStr != NULL);
        env->SetObjectArrayElement(strArray, i + 1, optionsStr);
    }

    /*
     * Start VM.  This thread becomes the main thread of the VM, and will
     * not return until the VM exits.
     */
    char* slashClassName = toSlashClassName(className != NULL ? className : "");
    //查找com.android.internal.os.ZygoteInit的class对象
    jclass startClass = env->FindClass(slashClassName);
    if (startClass == NULL) {
        ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
        /* keep going */
    } else {
        //查找main方法,参数为String数组
        jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
            "([Ljava/lang/String;)V");
        if (startMeth == NULL) {
            ALOGE("JavaVM unable to find main() in '%s'\n", className);
            /* keep going */
        } else {
            //执行com.android.internal.os.ZygoteInit的main方法
            env->CallStaticVoidMethod(startClass, startMeth, strArray);
            ...
        }
    }
    ...
}

start主要做了一下几件事:

1.配置系统环境变量

2.加载libart.so库

3.启动虚拟机,注册jni函数

4.启动java类com.android.internal.os.ZygoteInit的main方法,并传入之前的参数

加载libart.so

下面简要分析一下以上流程,环境变量就不说了,看一下jni_invocation.Init(NULL)加载libart.so的流程,由于我通过JniInvocation.cpp没有搜索到内容,所以先通过AndroidRuntime.cpp中导入的头文件来搜索,搜索JniInvocation.h,搜索到源码路径:libnativehelper/include_platform/nativehelper/JniInvocation.h,源码如下:

复制代码
struct JniInvocationImpl* JniInvocationCreate();

bool JniInvocationInit(struct JniInvocationImpl* instance, const char* library);

class JniInvocation final {

//构造函数
 public:
  JniInvocation() {
    impl_ = JniInvocationCreate();
  }

  ~JniInvocation() {
    JniInvocationDestroy(impl_);
  }

  //这个就是调用的init方法
  bool Init(const char* library) {
    //调用JniInvocationInit函数,library传入NULL
    return JniInvocationInit(impl_, library) != 0;
  }

  static const char* GetLibrary(const char* library, char* buffer) {
    return JniInvocationGetLibrary(library, buffer);
  }

 private:
  JniInvocation(const JniInvocation&) = delete;
  JniInvocation& operator=(const JniInvocation&) = delete;

  //原来最终是这个cpp文件
  JniInvocationImpl* impl_;
};

原来JniInvocation只是一个代理包装类,业务是交给JniInvocationImpl实现的,搜索JniInvocationImpl.cpp文件,结果也没有搜到,嘿,奇了怪了,总不能没有吧,后来使用 grep JniInvocationImpl ./ -rn 来搜索,果然就搜索到了,原来一直在关注.cpp,忽略了linux也可以运行.c的,搜索结果如下:

复制代码
./JniInvocation.c:35:struct JniInvocationImpl {
./JniInvocation.c:48:static struct JniInvocationImpl g_impl;
./JniInvocation.c:138:struct JniInvocationImpl* JniInvocationCreate() {
./JniInvocation.c:146:bool JniInvocationInit(struct JniInvocationImpl* instance, const char* library_name) {
./JniInvocation.c:199:void JniInvocationDestroy(struct JniInvocationImpl* instance) {
./include_platform/nativehelper/JniInvocation.h:33:struct JniInvocationImpl;
./include_platform/nativehelper/JniInvocation.h:36: * Creates an instance of a JniInvocationImpl.
./include_platform/nativehelper/JniInvocation.h:38:struct JniInvocationImpl* JniInvocationCreate();
./include_platform/nativehelper/JniInvocation.h:41: * Associates a library with a JniInvocationImpl instance. The library should export C symbols for
./include_platform/nativehelper/JniInvocation.h:56:bool JniInvocationInit(struct JniInvocationImpl* instance, const char* library);
./include_platform/nativehelper/JniInvocation.h:59: * Release resources associated with JniInvocationImpl instance.
./include_platform/nativehelper/JniInvocation.h:61:void JniInvocationDestroy(struct JniInvocationImpl* instance);
./include_platform/nativehelper/JniInvocation.h:122:  JniInvocationImpl* impl_;
./libnativehelper_lazy.c:257:struct JniInvocationImpl* JniInvocationCreate() {
./libnativehelper_lazy.c:258:    typedef struct JniInvocationImpl* (*M)();
./libnativehelper_lazy.c:262:void JniInvocationDestroy(struct JniInvocationImpl* instance) {
./libnativehelper_lazy.c:263:    typedef void (*M)(struct JniInvocationImpl*);
./libnativehelper_lazy.c:267:bool JniInvocationInit(struct JniInvocationImpl* instance, const char* library) {
./libnativehelper_lazy.c:268:    typedef bool (*M)(struct JniInvocationImpl*, const char*);

可以很确定说,源码肯定在./JniInvocation.c中,打开源码文件,查看:

复制代码
static const char* kDefaultJniInvocationLibrary = "libart.so";

bool JniInvocationInit(struct JniInvocationImpl* instance, const char* library_name) {
  //传入的library_name为NULL
  library_name = JniInvocationGetLibrary(library_name, buffer);
  //看函数名字应该是调用linux的dlopen函数,用于打开library为命名的so
  DlLibrary library = DlOpenLibrary(library_name);
  if (library == NULL) {
    //如果library为空,library_name不是libart.so
    if (strcmp(library_name, kDefaultJniInvocationLibrary) == 0) {
    ALOGW("Falling back from %s to %s after dlopen error: %s",
          library_name, kDefaultJniInvocationLibrary, DlGetError());
    //就加载libart.so
    library_name = kDefaultJniInvocationLibrary;
    library = DlOpenLibrary(library_name);
    //如果加载libart.so失败,就返回
    if (library == NULL) {
      ALOGE("Failed to dlopen %s: %s", library_name, DlGetError());
      return false;
    }
  }

  //查找函数JNI_GetDefaultJavaVMInitArgs
  DlSymbol JNI_GetDefaultJavaVMInitArgs_ = FindSymbol(library, "JNI_GetDefaultJavaVMInitArgs");
  if (JNI_GetDefaultJavaVMInitArgs_ == NULL) {
    return false;
  }

  //查找函数JNI_CreateJavaVM
  DlSymbol JNI_CreateJavaVM_ = FindSymbol(library, "JNI_CreateJavaVM");
  if (JNI_CreateJavaVM_ == NULL) {
    return false;
  }

  //查找函数JNI_GetCreatedJavaVMs
  DlSymbol JNI_GetCreatedJavaVMs_ = FindSymbol(library, "JNI_GetCreatedJavaVMs");
  if (JNI_GetCreatedJavaVMs_ == NULL) {
    return false;
  }

  instance->jni_provider_library_name = library_name;
  instance->jni_provider_library = library;
  instance->JNI_GetDefaultJavaVMInitArgs = (jint (*)(void *)) JNI_GetDefaultJavaVMInitArgs_;
  instance->JNI_CreateJavaVM = (jint (*)(JavaVM**, JNIEnv**, void*)) JNI_CreateJavaVM_;
  instance->JNI_GetCreatedJavaVMs = (jint (*)(JavaVM**, jsize, jsize*)) JNI_GetCreatedJavaVMs_;
  return true;
}

先看一下JniInvocationGetLibrary函数:

复制代码
const char* JniInvocationGetLibrary(const char* library, char* buffer) {
  bool debuggable = IsDebuggable();
  const char* system_preferred_library = NULL;
  if (buffer != NULL && (GetLibrarySystemProperty(buffer) > 0)) {
    system_preferred_library = buffer;
  }
  //调用到JniInvocationGetLibraryWith函数中
  return JniInvocationGetLibraryWith(library, debuggable, system_preferred_library);
}

const char* JniInvocationGetLibraryWith(const char* library,
                                        bool is_debuggable,
                                        const char* system_preferred_library) {
  //是否debug
  if (is_debuggable) {
    // Debuggable property is set. Allow library providing JNI Invocation API to be overridden.

    // Choose the library parameter (if provided).
    if (library != NULL) {
      return library;
    }
    // Choose the system_preferred_library (if provided).
    if (system_preferred_library != NULL) {
      return system_preferred_library;
    }
  }
  //返回libart.so字段
  return kDefaultJniInvocationLibrary;
}

再看一下DlOpenLibrary函数,源码位置在:./DlHelp.c:28行

复制代码
DlLibrary DlOpenLibrary(const char* filename) {
#ifdef _WIN32
  return LoadLibrary(filename);
#else
  // Load with RTLD_NODELETE in order to ensure that libart.so is not unmapped when it is closed.
  // This is due to the fact that it is possible that some threads might have yet to finish
  // exiting even after JNI_DeleteJavaVM returns, which can lead to segfaults if the library is
  // unloaded.
  //加载的linux的dlopen函数
  return dlopen(filename, RTLD_NOW | RTLD_NODELETE);
#endif
}

接着往下看,看一下FindSymbol函数的调用:

复制代码
static DlSymbol FindSymbol(DlLibrary library, const char* symbol) {
  //又调用了DlGetSymbol函数
  DlSymbol s = DlGetSymbol(library, symbol);
  if (s == NULL) {
    ALOGE("Failed to find symbol: %s", symbol);
  }
  return s;
}

DlGetSymbol函数也在./DlHelp.c中第48行:

复制代码
DlSymbol DlGetSymbol(DlLibrary handle, const char* symbol) {
#ifdef _WIN32
  return (DlSymbol) GetProcAddress(handle, symbol);
#else
  //调用的是linux的dlsym函数
  return dlsym(handle, symbol);
#endif
}

通过以上分析,可以明确第2点,加载libart.so库,这个so库的源码位置再art/runtime/jni/java_vm_ext.cc中,这里就不做分析了。

启动虚拟机

顺着主线继续,然后再来分析第3步,启动虚拟机startVm的流程, 回到源码:/frameworks/base/core/jni/AndroidRuntime.cpp中:

复制代码
int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv, bool zygote, bool primary_zygote)
{
    JavaVMInitArgs initArgs;
    //配置了很多虚拟机参数
    ...

    initArgs.version = JNI_VERSION_1_4;
    initArgs.options = mOptions.editArray();
    initArgs.nOptions = mOptions.size();
    initArgs.ignoreUnrecognized = JNI_FALSE;

    /*
     * Initialize the VM.
     *
     * The JavaVM* is essentially per-process, and the JNIEnv* is per-thread.
     * If this call succeeds, the VM is ready, and we can start issuing
     * JNI calls.
     */
    //创建java虚拟机
    if (JNI_CreateJavaVM(pJavaVM, pEnv, &initArgs) < 0) {
        ALOGE("JNI_CreateJavaVM failed\n");
        return -1;
    }
    return 0;
}

注册JNI函数

startReg方法调用主要是注册jni函数,下面看一下是如何注册的:

复制代码
static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
    ...
    env->PushLocalFrame(200);

    //注册jni函数的方法,跟一下register_jni_procs函数
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}

static int register_jni_procs(const RegJNIRec array[], size_t count, JNIEnv* env)
{
    //通过for循环,注册全部jni函数
    for (size_t i = 0; i < count; i++) {
        if (array[i].mProc(env) < 0) {
            ...
            return -1;
        }
    }
    return 0;
}

//将这些jni函数全部注册
static const RegJNIRec gRegJNI[] = {
        REG_JNI(register_com_android_internal_os_RuntimeInit),
        REG_JNI(register_com_android_internal_os_ZygoteInit_nativeZygoteInit),
        REG_JNI(register_android_os_SystemClock),
        REG_JNI(register_android_util_CharsetUtils),
        REG_JNI(register_android_util_EventLog),
        REG_JNI(register_android_util_Log),
        REG_JNI(register_android_util_MemoryIntArray),
        REG_JNI(register_android_app_admin_SecurityLog),
        REG_JNI(register_android_content_AssetManager),
        REG_JNI(register_android_content_StringBlock),
        REG_JNI(register_android_content_XmlBlock),
        REG_JNI(register_android_content_res_ApkAssets),
        REG_JNI(register_android_text_AndroidCharacter),
        REG_JNI(register_android_text_Hyphenator),
        REG_JNI(register_android_view_InputDevice),
        REG_JNI(register_android_view_KeyCharacterMap),
        REG_JNI(register_android_os_Process),
        REG_JNI(register_android_os_SystemProperties),
        REG_JNI(register_android_os_Binder),
        ...
};

register_com_android_internal_os_RuntimeInit这些函数还可以继续往下分析,其实就是调用了jniEnv的RegisterNatives函数,这个函数在app动态注册函数时使用的是同一个方法,这里就不再继续深入了。

启动ZygoteInit

经过以上的加载虚拟机,注册jni函数完成后,终于通过反射启动了ZygoteInit.java的静态main方法入口,ZygoteInit源码位置:/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

复制代码
public class ZygoteInit {
    public static void main(String[] argv) {
        //申明zygoteServer
        ZygoteServer zygoteServer = null;

        // Mark zygote start. This ensures that thread creation will throw
        // an error.
        //抑制线程启动,保证zygote单线程启动
        ZygoteHooks.startZygoteNoThreadCreation();

        // Zygote goes into its own process group.
        //设置进程组的id
        try {
            Os.setpgid(0, 0);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to setpgid(0,0)", ex);
        }

        Runnable caller;
        try {
            ...

            boolean startSystemServer = false;
            String zygoteSocketName = "zygote";
            String abiList = null;
            boolean enableLazyPreload = false;
            for (int i = 1; i < argv.length; i++) {
                //包含start-system-server,将startSystemServer置为true
                if ("start-system-server".equals(argv[i])) {
                    startSystemServer = true;
                } else if ("--enable-lazy-preload".equals(argv[i])) {
                    enableLazyPreload = true;
                //从AndroidRuntime.cpp中带过来的也有这个信息
                } else if (argv[i].startsWith(ABI_LIST_ARG)) {
                    abiList = argv[i].substring(ABI_LIST_ARG.length());
                } else ...
            }

            ...

            if (abiList == null) {
                throw new RuntimeException("No ABI list supplied.");
            }

            //enableLazyPreload是false
            if (!enableLazyPreload) {
                ...
                //加载android资源
                preload(bootTimingsTraceLog);
                ...
            }

            // Do an initial gc to clean up after startup
            //调用gc进行初始清理回收
            gcAndFinalize();
            //调用AppRuntime的onZygoteInit函数
            Zygote.initNativeState(isPrimaryZygote);

            //中止抑制子线程启动,即将fork,要保证线程可以创建线程
            ZygoteHooks.stopZygoteNoThreadCreation();

            //初始化ZygoteServer创建socket
            zygoteServer = new ZygoteServer(isPrimaryZygote);

            //此时startSystemServer为true,会启动systemServer
            if (startSystemServer) {
                Runnable r = forkSystemServer(abiList, zygoteSocketName, zygoteServer);

                // {@code r == null} in the parent (zygote) process, and {@code r != null} in the child (system_server) process.
                //r==null时为zygote进程,r!=null时为子进程
                if (r != null) {
                    r.run();
                    return;
                }
            }

            Log.i(TAG, "Accepting command socket connections");

            // The select loop returns early in the child process after a fork and
            // loops forever in the zygote.
            //在子进程中会有返回值,在zygote进程中永远循环
            caller = zygoteServer.runSelectLoop(abiList);
        } catch (Throwable ex) {
            Log.e(TAG, "System zygote died with fatal exception", ex);
            throw ex;
        } finally {
            //出现异常或子进程返回,需要关闭socket
            if (zygoteServer != null) {
                zygoteServer.closeServerSocket();
            }
        }

        // We're in the child process and have exited the select loop. Proceed to execute the command.
        //子进程返回后,会执行
        if (caller != null) {
            caller.run();
        }
    }
}

以上流程备注的比较详细了,下面针对其中的步骤做详细分析。

首先看一下ZygoteHooks.startZygoteNoThreadCreation(),禁止创建线程,之所以要禁止创建线程,是因为Zygote必须保证线程单一,这和fork机制有关,fork函数只会将当前线程复制到子进程,同时,fork会将锁也复制到子进程中,如果在fork之前,有一个线程持有了锁,但是fork的时候没把这个线程复制到子进程中,这把锁就被永久持有了,会造成死锁。

preload

接下来重点看一下加载android资源,进入到preload方法中看一下:

复制代码
static void preload(TimingsTraceLog bootTimingsTraceLog) {
    ...
    //预加载android中的java类
    preloadClasses();

    //加载三个jar
    /* /system/framework/android.hidl.base-V1.0-java.jar */
    /* /system/framework/android.hidl.manager-V1.0-java.jar */
    /* /system/framework/android.test.base.jar */
    cacheNonBootClasspathClassLoaders();
    //预加载资源
    preloadResources();
    //加载硬件抽象层
    nativePreloadAppProcessHALs();
    //加载渲染相关opengl等
    maybePreloadGraphicsDriver();
    //加载动态库
    preloadSharedLibraries();
    //加载front库
    preloadTextResources();
    // Ask the WebViewFactory to do any initialization that must run in the zygote process,
    // for memory sharing purposes.
    //预加载webviewchromium
    WebViewFactory.prepareWebViewInZygote();
    ...
}

先看一下源码:

复制代码
private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";    

private static void preloadClasses() {
    final VMRuntime runtime = VMRuntime.getRuntime();

    InputStream is;
    try {
        is = new FileInputStream(PRELOADED_CLASSES);
    } catch (FileNotFoundException e) {
        Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
        return;
    }
    ...
    try {
        BufferedReader br =
                new BufferedReader(new InputStreamReader(is), Zygote.SOCKET_BUFFER_SIZE);

        int count = 0;
        int missingLambdaCount = 0;
        String line;
        while ((line = br.readLine()) != null) {
            // Skip comments and blank lines.
            line = line.trim();
            //如果被注释或者是空的,直接continue
            if (line.startsWith("#") || line.equals("")) {
                continue;
            }
            try {
                //加载类
                Class.forName(line, true, null);
                count++;
            } catch (ClassNotFoundException e) {
                ...
            } catch (UnsatisfiedLinkError e) {
                Log.w(TAG, "Problem preloading " + line + ": " + e);
            } catch (Throwable t) {
                ...
            }
        }
    } catch (IOException e) {
        Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
    } finally {
        IoUtils.closeQuietly(is);

        //用预加载带来的类、字段和方法填充dex缓存
        runtime.preloadDexCaches();

        ...
    }
}

可以看到主要就是通过类加载器从/system/etc/preloaded-classes这个路径文件中预加载类,这个路径文件在源码的路径为:frameworks/base/config/preloaded-classes,可以进去看一下:

复制代码
android.R$styleable
android.accessibilityservice.AccessibilityServiceInfo$1
android.accessibilityservice.AccessibilityServiceInfo
android.accessibilityservice.IAccessibilityServiceClient$Stub$Proxy
android.accessibilityservice.IAccessibilityServiceClient$Stub
android.accessibilityservice.IAccessibilityServiceClient
android.accounts.AbstractAccountAuthenticator$Transport
android.accounts.AbstractAccountAuthenticator
android.accounts.Account$1
android.accounts.Account
android.accounts.AccountAndUser
android.accounts.AccountAuthenticatorResponse$1
android.accounts.AccountAuthenticatorResponse
android.accounts.AccountManager$10
android.accounts.AccountManager$11
android.accounts.AccountManager$15
android.accounts.AccountManager$16
android.accounts.AccountManager$17
android.accounts.AccountManager$18
android.accounts.AccountManager$1
android.accounts.AccountManager$20
android.accounts.AccountManager$2
android.accounts.AccountManager$3
android.accounts.AccountManager$8
android.accounts.AccountManager$AmsTask$1
android.accounts.AccountManager$AmsTask$Response
android.accounts.AccountManager$AmsTask
android.accounts.AccountManager$BaseFutureTask$1
android.accounts.AccountManager$BaseFutureTask$Response
android.accounts.AccountManager$BaseFutureTask
android.accounts.AccountManager$Future2Task$1
android.accounts.AccountManager$Future2Task
android.accounts.AccountManager
android.accounts.AccountManagerCallback
...

为什么需要在zygote中预加载类呢?

这是由于父子进程的资源是共享的,每启动一个app,都需要使用虚拟机、加载类等,直接在父进程中预加载这些,fork后子进程就可以直接使用它们,就不需要每个app都要去加载一次,降低系统效率,浪费资源。

cacheNonBootClasspathClassLoaders

再看一下cacheNonBootClasspathClassLoaders加载了三个jar

复制代码
    private static void cacheNonBootClasspathClassLoaders() {
        // These libraries used to be part of the bootclasspath, but had to be removed.
        // Old system applications still get them for backwards compatibility reasons,
        // so they are cached here in order to preserve performance characteristics.

        //这些库曾经是bootclasspath的一部分,但必须删除,由于向后兼容性的原因,旧的系统应用程序仍然得到它们,所以缓存再这里
        SharedLibraryInfo hidlBase = new SharedLibraryInfo(
                "/system/framework/android.hidl.base-V1.0-java.jar", null /*packageName*/,
                null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
                null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
                false /*isNative*/);
        SharedLibraryInfo hidlManager = new SharedLibraryInfo(
                "/system/framework/android.hidl.manager-V1.0-java.jar", null /*packageName*/,
                null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
                null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
                false /*isNative*/);

        SharedLibraryInfo androidTestBase = new SharedLibraryInfo(
                "/system/framework/android.test.base.jar", null /*packageName*/,
                null /*codePaths*/, null /*name*/, 0 /*version*/, SharedLibraryInfo.TYPE_BUILTIN,
                null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
                false /*isNative*/);

        ApplicationLoaders.getDefault().createAndCacheNonBootclasspathSystemClassLoaders(
                new SharedLibraryInfo[]{
                    // ordered dependencies first
                    hidlBase,
                    hidlManager,
                    androidTestBase,
                });
    }

preloadResources

preloadResources主要预加载资源和检查资源

复制代码
private static final boolean PRELOAD_RESOURCES = true;

private static void preloadResources() {
    try {
        mResources = Resources.getSystem();
        mResources.startPreloading();
        if (PRELOAD_RESOURCES) {
            //加载所有drawable
            TypedArray ar = mResources.obtainTypedArray(
                    com.android.internal.R.array.preloaded_drawables);
            int N = preloadDrawables(ar);
            ar.recycle();
            //加载color属性
            ar = mResources.obtainTypedArray(
                    com.android.internal.R.array.preloaded_color_state_lists);
            N = preloadColorStateLists(ar);
            ar.recycle();

            ...
        }
        mResources.finishPreloading();
    } catch (RuntimeException e) {
        Log.w(TAG, "Failure preloading resources", e);
    }
}

private static int preloadDrawables(TypedArray ar) {
    int N = ar.length();
    for (int i = 0; i < N; i++) {
        int id = ar.getResourceId(i, 0);

        if (id != 0) {
            //
            if (mResources.getDrawable(id, null) == null) {
                throw new IllegalArgumentException(
                        "Unable to find preloaded drawable resource #0x"
                                + Integer.toHexString(id)
                                + " (" + ar.getString(i) + ")");
            }
        }
    }
    return N;
}

private static int preloadColorStateLists(TypedArray ar) {
    int N = ar.length();
    for (int i = 0; i < N; i++) {
        int id = ar.getResourceId(i, 0);

        if (id != 0) {
            if (mResources.getColorStateList(id, null) == null) {
                throw new IllegalArgumentException(
                        "Unable to find preloaded color resource #0x"
                                + Integer.toHexString(id)
                                + " (" + ar.getString(i) + ")");
            }
        }
    }
    return N;
}

直接上面分析了几种,其他项基本都是预加载各种资源,就不再一个一个的看了,接着主线流程,往preload下面看:

ZygoteServer

可以看到调用两次创建socket的方法,传入不同的参数,分别创建了一个socket

java 复制代码
//ZygoteServer的构造方法,此时isPrimaryZygote为true
ZygoteServer(boolean isPrimaryZygote) {
        mUsapPoolEventFD = Zygote.getUsapPoolEventFD();

        if (isPrimaryZygote) {
            //创建本地socket,传入zygote
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.PRIMARY_SOCKET_NAME);
            //创建本地socket,传入usap_pool_primary
            mUsapPoolSocket =
                    Zygote.createManagedSocketFromInitSocket(
                            Zygote.USAP_POOL_PRIMARY_SOCKET_NAME);
        } else {
            //创建本地socket,传入zygote_secondary
            mZygoteSocket = Zygote.createManagedSocketFromInitSocket(Zygote.SECONDARY_SOCKET_NAME);
            //创建本地socket,传入usap_pool_secondary
            mUsapPoolSocket =
                    Zygote.createManagedSocketFromInitSocket(
                            Zygote.USAP_POOL_SECONDARY_SOCKET_NAME);
        }

        mUsapPoolSupported = true;
        fetchUsapPoolPolicyProps();
}

调用了Zygote.java中的静态方法,接着往下追代码:

java 复制代码
/** Prefix prepended to socket names created by init */
private static final String ANDROID_SOCKET_PREFIX = "ANDROID_SOCKET_";

/**
 * @hide for internal use only.
 */
public static final String PRIMARY_SOCKET_NAME = "zygote";

/**
 * @hide for internal use only.
 */
public static final String SECONDARY_SOCKET_NAME = "zygote_secondary";

/**
 * @hide for internal use only
 */
public static final String USAP_POOL_PRIMARY_SOCKET_NAME = "usap_pool_primary";

/**
 * @hide for internal use only
 */
public static final String USAP_POOL_SECONDARY_SOCKET_NAME = "usap_pool_secondary";

static LocalServerSocket createManagedSocketFromInitSocket(String socketName) {
    int fileDesc;
    final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;

    try {
        //获取指定环境变量fullSocketName的值
        String env = System.getenv(fullSocketName);
        fileDesc = Integer.parseInt(env);
    } catch (RuntimeException ex) {
        throw new RuntimeException("Socket unset or invalid: " + fullSocketName, ex);
    }

    try {
        //创建fd并绑定节点
        FileDescriptor fd = new FileDescriptor();
        fd.setInt$(fileDesc);
        //创建LocalServerSocket对象,并传入fd
        return new LocalServerSocket(fd);
    } catch (IOException ex) {
        throw new RuntimeException(
            "Error building socket from file descriptor: " + fileDesc, ex);
    }
}

进入到LocalServerSocket类中,其中又创建了LocalSocketImpl对象,然后设置了fd和BACKLOG为50的监听:

java 复制代码
private static final int LISTEN_BACKLOG = 50;

public LocalServerSocket(FileDescriptor fd) throws IOException
{
    //创建LocalSocketImpl对象
    impl = new LocalSocketImpl(fd);
    //添加监听,监听BACKLOG为50
    impl.listen(LISTEN_BACKLOG);
    //获取本地地址
    localAddress = impl.getSockAddress();
}

LocalSocketImpl构造方法什么都没干,listene方法内部就是调用的Os.listen(FileDescriptor fd, int backlog),就不再往下分析了。

forkSystemServer

java 复制代码
//传入的参数:架构, zygote, zygoteServer对象
private static Runnable forkSystemServer(String abiList, String socketName,
        ZygoteServer zygoteServer) {
    ...
    /* Hardcoded command line to start the system server */
    //fork内容要传入的参数
    String[] args = {
            "--setuid=1000",
            "--setgid=1000",
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,"
                    + "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010,3011,3012",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
    };
    ZygoteArguments parsedArgs;

    int pid;

    try {
        ZygoteCommandBuffer commandBuffer = new ZygoteCommandBuffer(args);
        try {
            parsedArgs = ZygoteArguments.getInstance(commandBuffer);
        } catch (EOFException e) {
            throw new AssertionError("Unexpected argument error for forking system server", e);
        }
        commandBuffer.close();
        ...
        /* Enable gwp-asan on the system server with a small probability. This is the same
         * policy as applied to native processes and system apps. */
        parsedArgs.mRuntimeFlags |= Zygote.GWP_ASAN_LEVEL_LOTTERY;

        if (shouldProfileSystemServer()) {
            parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
        }

        /* Request to fork the system server process */
        //进入到zygote的静态方法中
        pid = Zygote.forkSystemServer(
                parsedArgs.mUid, parsedArgs.mGid,
                parsedArgs.mGids,
                parsedArgs.mRuntimeFlags,
                null,
                parsedArgs.mPermittedCapabilities,
                parsedArgs.mEffectiveCapabilities);
    } catch (IllegalArgumentException ex) {
        throw new RuntimeException(ex);
    }

    /* For child process */
    //子进程创建成功,进入子进程
    if (pid == 0) {
        if (hasSecondZygote(abiList)) {
            //等待secondZygote
            waitForSecondaryZygote(socketName);
        }
        //停止自己的serverSocket
        zygoteServer.closeServerSocket();
        //调用了handleSystemServerProcess
        return handleSystemServerProcess(parsedArgs);
    }

    return null;
}

//Zygote.forkSystemServer
static int forkSystemServer(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
    ZygoteHooks.preFork();
    //调用了nativeForkSystemServer,这是一个native方法,可以通过命令搜索源码
    int pid = nativeForkSystemServer(
            uid, gid, gids, runtimeFlags, rlimits,
            permittedCapabilities, effectiveCapabilities);

    // Set the Java Language thread priority to the default value for new apps.
    //设置新进程的线程优先级
    Thread.currentThread().setPriority(Thread.NORM_PRIORITY);

    ZygoteHooks.postForkCommon();
    return pid;
}

通过如下命令搜索:

java 复制代码
grep nativeForkSystemServer ./ -rn

进入到nativeForkSystemServer源码中:

java 复制代码
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
        JNIEnv* env, jclass, uid_t uid, gid_t gid, jintArray gids,
        jint runtime_flags, jobjectArray rlimits, jlong permitted_capabilities,
        jlong effective_capabilities) {
  ...
  //调用了zygote的ForkCommon方法,再跟一下
  pid_t pid = zygote::ForkCommon(env, true,
                                 fds_to_close,
                                 fds_to_ignore,
                                 true);
  if (pid == 0) {
      // System server prcoess does not need data isolation so no need to
      // know pkg_data_info_list.
      SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits, permitted_capabilities,
                       effective_capabilities, MOUNT_EXTERNAL_DEFAULT, nullptr, nullptr, true,
                       false, nullptr, nullptr, /* is_top_app= */ false,
                       /* pkg_data_info_list */ nullptr,
                       /* allowlisted_data_info_list */ nullptr, false, false);
  }
  return pid;
}

//ForkCommon
pid_t zygote::ForkCommon(JNIEnv* env, bool is_system_server,
                         const std::vector<int>& fds_to_close,
                         const std::vector<int>& fds_to_ignore,
                         bool is_priority_fork,
                         bool purge) {
  //设置子进程信号处理函数
  SetSignalHandlers();
  ...
  //fork前先阻塞SIGCHLD信号
  BlockSignal(SIGCHLD, fail_fn);
  ...
  //最终是调用了fork方法
  pid_t pid = fork();
  ...
  // We blocked SIGCHLD prior to a fork, we unblock it here.
  //恢复SIGCHLD信号
  UnblockSignal(SIGCHLD, fail_fn);
  return pid;
}

这里佐证了forkSystemServer是通过fork来实现的进程启动,forSystemServer返回值是一个Runnable,看一下这个Runnable怎么被创建出来的,可以看到再pid==0子进程创建成功后,调用了handleSystemServerProcess,看一下源码:

java 复制代码
private static Runnable handleSystemServerProcess(ZygoteArguments parsedArgs) {
    // set umask to 0077 so new files and directories will default to owner-only permissions.
    //设置权限掩码
    Os.umask(S_IRWXG | S_IRWXO);
    //设置进程名称为system_server
    if (parsedArgs.mNiceName != null) {
        Process.setArgV0(parsedArgs.mNiceName);
    }
    ...
    if (parsedArgs.mInvokeWith != null) {
        ...
    } else {
        //创建classloader
        ClassLoader cl = getOrCreateSystemServerClassLoader();
        if (cl != null) {
            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         */
        //调用了ZygoteInit.zygoteInit方法
        return ZygoteInit.zygoteInit(parsedArgs.mTargetSdkVersion,
                parsedArgs.mDisabledCompatChanges,
                parsedArgs.mRemainingArgs, cl);
    }
}

进入到zygoteInit方法中:

java 复制代码
public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ...
    RuntimeInit.redirectLogStreams();
    RuntimeInit.commonInit();
    ZygoteInit.nativeZygoteInit();
    //调用到了RuntimeInit.applicationInit
    return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

调用到了RuntimeInit.applicationInit,继续追踪

java 复制代码
protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
        ClassLoader classLoader) {
    ....
    VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
    VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);
    final Arguments args = new Arguments(argv);
    // The end of of the RuntimeInit event (see #zygoteInit).
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    // Remaining arguments are passed to the start class's static main
    //调用findStaticMain, 查找main方法,在追踪一下
    return findStaticMain(args.startClass, args.startArgs, classLoader);
}

//findStaticMain
protected static Runnable findStaticMain(String className, String[] argv,
        ClassLoader classLoader) {
    //反射获取类对象
    Class<?> cl;
    try {
        cl = Class.forName(className, true, classLoader);
    } catch (ClassNotFoundException ex) {
        throw new RuntimeException(
                "Missing class when invoking static main " + className,
                ex);
    }
    //反射获取main方法对象
    Method m;
    try {
        m = cl.getMethod("main", new Class[] { String[].class });
    } catch (NoSuchMethodException ex) {
        throw new RuntimeException(
                "Missing static main on " + className, ex);
    } catch (SecurityException ex) {
        throw new RuntimeException(
                "Problem getting static main on " + className, ex);
    }
    int modifiers = m.getModifiers();
    if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
        throw new RuntimeException(
                "Main method is not public and static on " + className);
    }
    //new MethodAndArgsCaller其实就是一个Runnable,其中的run方法就是invoke这个main方法,可以通过源码印证
    return new MethodAndArgsCaller(m, argv);
}

//MethodAndArgsCaller
static class MethodAndArgsCaller implements Runnable {
        /** method to call */
    private final Method mMethod;
    /** argument array */
    private final String[] mArgs;
    public MethodAndArgsCaller(Method method, String[] args) {
        mMethod = method;
        mArgs = args;
    }
    //run方法,调用后会调用main方法
    public void run() {
        try {
            mMethod.invoke(null, new Object[] { mArgs });
        } catch (IllegalAccessException ex) {
            throw new RuntimeException(ex);
        } catch (InvocationTargetException ex) {
            Throwable cause = ex.getCause();
            if (cause instanceof RuntimeException) {
                throw (RuntimeException) cause;
            } else if (cause instanceof Error) {
                throw (Error) cause;
            }
            throw new RuntimeException(ex);
        }
    }
}

整个过程就是调用到了SystemServer的main方法中启动了SystemServer,SystemServer启动后做了什么留在后面章节分析,这里继续将剩余的流程分析完。

runSelectLoop

ZygoteInit类中如果startSystemServer为false,则会调用zygoteServer.runSelectLoop方法,看一下这个方法做了什么:

java 复制代码
Runnable runSelectLoop(String abiList) {
        ArrayList<FileDescriptor> socketFDs = new ArrayList<FileDescriptor>();
        ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
        //将server socket fd加到列表头(后面需要判断是否为server socket)
        socketFDs.add(mZygoteSocket.getFileDescriptor());
        peers.add(null);

        while (true) {
            ...
            //等待fd的事件
            try {
                Os.poll(pollFDs, -1);
            } catch (ErrnoException ex) {
                throw new RuntimeException("poll failed", ex);
            }

            boolean usapPoolFDRead = false;

            while (--pollIndex >= 0) {
                if ((pollFDs[pollIndex].revents & POLLIN) == 0) {
                    continue;
                }
                //pollIndex == 0说明fd是ZygoteServer socket的fd
                if (pollIndex == 0) {
                    // Zygote server socket
                    //接受并建立一个socket连接
                    ZygoteConnection newPeer = acceptCommandPeer(abiList);
                    peers.add(newPeer);
                    socketFDs.add(newPeer.getFileDescriptor());

                } else if (pollIndex < usapPoolEventFDIndex) {
                    // Session socket accepted from the Zygote server socket

                    try {
                        ZygoteConnection connection = peers.get(pollIndex);
                        final Runnable command = connection.processOneCommand(this);

                        // TODO (chriswailes): Is this extra check necessary?
                        if (mIsForkChild) {
                            // We're in the child. We should always have a command to run at this
                            // stage if processOneCommand hasn't called "exec".
                            if (command == null) {
                                throw new IllegalStateException("command == null");
                            }

                            return command;
                        } else {
                            // We're in the server - we should never have any commands to run.
                            if (command != null) {
                                throw new IllegalStateException("command != null");
                            }

                            // We don't know whether the remote side of the socket was closed or
                            // not until we attempt to read from it from processOneCommand. This
                            // shows up as a regular POLLIN event in our regular processing loop.
                            if (connection.isClosedByPeer()) {
                                connection.closeSocket();
                                peers.remove(pollIndex);
                                socketFDs.remove(pollIndex);
                            }
                        }
                    } catch (Exception e) {
                        if (!mIsForkChild) {
                            // We're in the server so any exception here is one that has taken place
                            // pre-fork while processing commands or reading / writing from the
                            // control socket. Make a loud noise about any such exceptions so that
                            // we know exactly what failed and why.

                            Slog.e(TAG, "Exception executing zygote command: ", e);

                            // Make sure the socket is closed so that the other end knows
                            // immediately that something has gone wrong and doesn't time out
                            // waiting for a response.
                            ZygoteConnection conn = peers.remove(pollIndex);
                            conn.closeSocket();

                            socketFDs.remove(pollIndex);
                        } else {
                            // We're in the child so any exception caught here has happened post
                            // fork and before we execute ActivityThread.main (or any other main()
                            // method). Log the details of the exception and bring down the process.
                            Log.e(TAG, "Caught post-fork exception in child process.", e);
                            throw e;
                        }
                    } finally {
                        // Reset the child flag, in the event that the child process is a child-
                        // zygote. The flag will not be consulted this loop pass after the Runnable
                        // is returned.
                        mIsForkChild = false;
                    }
                } else {
                    // Either the USAP pool event FD or a USAP reporting pipe.

                    // If this is the event FD the payload will be the number of USAPs removed.
                    // If this is a reporting pipe FD the payload will be the PID of the USAP
                    // that was just specialized.
                    long messagePayload = -1;

                    try {
                        byte[] buffer = new byte[Zygote.USAP_MANAGEMENT_MESSAGE_BYTES];
                        int readBytes = Os.read(pollFDs[pollIndex].fd, buffer, 0, buffer.length);

                        if (readBytes == Zygote.USAP_MANAGEMENT_MESSAGE_BYTES) {
                            DataInputStream inputStream =
                                    new DataInputStream(new ByteArrayInputStream(buffer));

                            messagePayload = inputStream.readLong();
                        } else {
                            Log.e(TAG, "Incomplete read from USAP management FD of size "
                                    + readBytes);
                            continue;
                        }
                    } catch (Exception ex) {
                        if (pollIndex == usapPoolEventFDIndex) {
                            Log.e(TAG, "Failed to read from USAP pool event FD: "
                                    + ex.getMessage());
                        } else {
                            Log.e(TAG, "Failed to read from USAP reporting pipe: "
                                    + ex.getMessage());
                        }

                        continue;
                    }

                    if (pollIndex > usapPoolEventFDIndex) {
                        Zygote.removeUsapTableEntry((int) messagePayload);
                    }

                    usapPoolFDRead = true;
                }
            }

            // Check to see if the USAP pool needs to be refilled.
            if (usapPoolFDRead) {
                int[] sessionSocketRawFDs =
                        socketFDs.subList(1, socketFDs.size())
                                .stream()
                                .mapToInt(fd -> fd.getInt$())
                                .toArray();

                final Runnable command = fillUsapPool(sessionSocketRawFDs);

                if (command != null) {
                    return command;
                }
            }
        }
    }

未完待续...

相关推荐
帅次2 小时前
Android 16(API Level 36)Activity 启动流程源码级解析
android·framework·源码解析·activity启动流程·android 16
chian-ocean2 小时前
Microi吾码:从零到服装ERP:低代码打造企业级系统的实战之旅
android·低代码·rxjava
故渊at4 小时前
第十五板块:Android 系统调试与逆向工程 | 第三十五篇:ART 虚拟机内部机制与 OAT 文件格式
android·虚拟机·art·机器码·oat文件格式
alexhilton10 小时前
Android的Agent优先时代:构建时vs运行时
android·kotlin·android jetpack
Cutecat_11 小时前
视频字幕处理工具横向:提取模式 vs 编辑模式,该如何选择
android·前端·ios·语音识别
2601_9617652912 小时前
【分享】PlayerPro媒体音乐播放器 完整专业版
android·媒体
JohnnyDeng9414 小时前
【Android】Android 包体积优化:R8/ProGuard 深度配置全攻略
android·性能优化·kotlin·jetpack
故渊at14 小时前
第九板块:Android 多媒体体系 | 第二十四篇:Camera Service 与 HAL3 成像流水线
android·camera·多媒体体系·hal3
Jinkxs18 小时前
Python基础 - 初识内置函数 Python自带的便捷工具
android·java·python