Framwork源码解析(2)_System Server进程启动流程

System Server进程是如何创建的

从上一篇Zygote进程启动过程中,可以看到System Server进程是在Zygote进程中创建出来的。查看ZygoteInit.java类,路径是/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java,找到main方法,可以看到在main方法中启动了System Server。

  public static void main(String argv[]) {
   		 // 代码省略....
         if (startSystemServer) {
             startSystemServer(abiList, socketName, zygoteServer);
         }
          // 代码省略....

    }

ZygoteInit.java类找到startSystemServer方法,如下,通过注释可以看到这个方法主要作用是:准备参数和孵化系统服务进程。

/**
* Prepare the arguments and fork for the system server process.
* 准备参数和孵化系统服务进程
*/
private static boolean startSystemServer(String abiList, String socketName, ZygoteServer zygoteServer)
       throws Zygote.MethodAndArgsCaller, RuntimeException {
   long capabilities = posixCapabilitiesAsBits(
       OsConstants.CAP_IPC_LOCK,
       OsConstants.CAP_KILL,
       OsConstants.CAP_NET_ADMIN,
       OsConstants.CAP_NET_BIND_SERVICE,
       OsConstants.CAP_NET_BROADCAST,
       OsConstants.CAP_NET_RAW,
       OsConstants.CAP_SYS_MODULE,
       OsConstants.CAP_SYS_NICE,
       OsConstants.CAP_SYS_PTRACE,
       OsConstants.CAP_SYS_TIME,
       OsConstants.CAP_SYS_TTY_CONFIG,
       OsConstants.CAP_WAKE_ALARM
   );
   /* Containers run without this capability, so avoid setting it in that case */
   if (!SystemProperties.getBoolean(PROPERTY_RUNNING_IN_CONTAINER, false)) {
       capabilities |= posixCapabilitiesAsBits(OsConstants.CAP_BLOCK_SUSPEND);
   }
   /* Hardcoded command line to start the system server */
   // 1、准备fork系统服务的参数
   String args[] = {
       "--setuid=1000",
       "--setgid=1000",
       "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
       "--capabilities=" + capabilities + "," + capabilities,
       "--nice-name=system_server",
       "--runtime-args",
       "com.android.server.SystemServer",
   };
   ZygoteConnection.Arguments parsedArgs = null;

   int pid;

   try {
       parsedArgs = new ZygoteConnection.Arguments(args);
       ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
       ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

       /* Request to fork the system server process */
        // 2、通过Zygote来fork系统服务的进程
       pid = Zygote.forkSystemServer(
               parsedArgs.uid, parsedArgs.gid,
               parsedArgs.gids,
               parsedArgs.debugFlags,
               null,
               parsedArgs.permittedCapabilities,
               parsedArgs.effectiveCapabilities);
   } catch (IllegalArgumentException ex) {
       throw new RuntimeException(ex);
   }

   /* For child process */
   // 3、如果pid为0,表示在子线程中执行
   if (pid == 0) {
       if (hasSecondZygote(abiList)) {
           waitForSecondaryZygote(socketName);
       }
	   // 4、关闭复制的zygote进程的Socket 
       zygoteServer.closeServerSocket();
       // 5、在子进程中执行操作
       handleSystemServerProcess(parsedArgs);
   }

   return true;
}

通过代码分析,startSystemServer方法中主要做了以下几件事:

  1. 准备fork系统服务的参数
  2. 通过Zygote来fork系统服务的进程
  3. 如果pid为0,表示在子线程中执行,即在fork出的system server进程中执行相关逻辑,执行方法是handleSystemServerProcess。下面就分析这个方法主要做了哪些事情。
  4. SyetemServer进程是复制了Zygote进程的地址空间,因此也会得到Zygote进程创建的Socket,这个Socket对于SyetemServer进程没有用处,所以调用closeServerSocket()关闭它。

System Server创建后做了哪些事

一、ZygoteInit.java类中的方法handleSystemServerProcess
从上一个标题得知,系统服务创建之后,执行了handleSystemServerProcess方法,在该类中找到该方法,如下所示:

/**
 * Finish remaining work for the newly forked system server process.
 */
private static void handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)throws Zygote.MethodAndArgsCaller {

    // set umask to 0077 so new files and directories will default to owner-only permissions.
    Os.umask(S_IRWXG | S_IRWXO);

	// 1、niceName 其实就是system server的进程名system_server
    if (parsedArgs.niceName != null) {
        Process.setArgV0(parsedArgs.niceName);
    }

    final String systemServerClasspath = Os.getenv("SYSTEMSERVERCLASSPATH");
    if (systemServerClasspath != null) {
        performSystemServerDexOpt(systemServerClasspath);
        // Capturing profiles is only supported for debug or eng builds since selinux normally
        // prevents it.
        boolean profileSystemServer = SystemProperties.getBoolean(
                "dalvik.vm.profilesystemserver", false);
        if (profileSystemServer && (Build.IS_USERDEBUG || Build.IS_ENG)) {
            try {
                File profileDir = Environment.getDataProfilesDePackageDirectory(
                        Process.SYSTEM_UID, "system_server");
                File profile = new File(profileDir, "primary.prof");
                profile.getParentFile().mkdirs();
                profile.createNewFile();
                String[] codePaths = systemServerClasspath.split(":");
                VMRuntime.registerAppInfo(profile.getPath(), codePaths);
            } catch (Exception e) {
                Log.wtf(TAG, "Failed to set up system server profile", e);
            }
        }
    }

    if (parsedArgs.invokeWith != null) {
        String[] args = parsedArgs.remainingArgs;
        // If we have a non-null system server class path, we'll have to duplicate the
        // existing arguments and append the classpath to it. ART will handle the classpath
        // correctly when we exec a new process.
        if (systemServerClasspath != null) {
            String[] amendedArgs = new String[args.length + 2];
            amendedArgs[0] = "-cp";
            amendedArgs[1] = systemServerClasspath;
            System.arraycopy(args, 0, amendedArgs, 2, args.length);
            args = amendedArgs;
        }
		// 2、启动应用进程
        WrapperInit.execApplication(parsedArgs.invokeWith,
                parsedArgs.niceName, parsedArgs.targetSdkVersion,
                VMRuntime.getCurrentInstructionSet(), null, args);
    } else {
        ClassLoader cl = null;
        if (systemServerClasspath != null) {
            cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);

            Thread.currentThread().setContextClassLoader(cl);
        }

        /*
         * Pass the remaining arguments to SystemServer.
         * 3、调用zygoteInit方法,进一步启动SystemServer
         */
        ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
    }
    }
  1. niceName 其实就是system server的进程名system_server
  2. 启动应用进程
  3. 由于parsedArgs.invokeWith属性默认为null,最后调用ZygoteInit.zygoteInit来进一步启动SystemServer。

二、ZygoteInit.java类中的方法zygoteInit

public static final void zygoteInit(int targetSdkVersion, String[] argv,ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
    if (RuntimeInit.DEBUG) {
        Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
    }
	
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
    // 1、重定向Log输出
    RuntimeInit.redirectLogStreams();
    // 2、初始化运行环境
    RuntimeInit.commonInit();
    ///3、调用zygote的native方法启动Binder线程池
    ZygoteInit.nativeZygoteInit();
    // 4、调用应用入口函数
    RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}

zygoteInit主要做了以下几件事:

  1. 重定向Log输出
  2. 初始化运行环境
  3. 调用zygote的native方法启动Binder线程池
  4. 调用RuntimeInit.applicationInit方法启动应用程序

1、先查看zygote的native方法是如何启动Binder线程池的
找到zygote的native方法类AndroidRuntime.cpp,路径是:/frameworks/base/core/jni/AndroidRuntime.cpp
通过注册方法数组找到native方法com_android_internal_os_ZygoteInit_nativeZygoteInit

int register_com_android_internal_os_ZygoteInit(JNIEnv* env)
{
    const JNINativeMethod methods[] = {
        { "nativeZygoteInit", "()V",
            (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
    };
    return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
        methods, NELEM(methods));
}

找到

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
    gCurRuntime->onZygoteInit();
}

这里调用了onZygoteInit()方法,而gCurRuntime是AndroidRuntime类的指针,而上文提到到app_main.cpp(路径是frameworks/base/cmds/app_process/app_main.cpp)中定义了AppRuntime 类,继承于AndroidRuntime类,在AppRuntime类中的onZygoteInit方法中,调用了ProcessState类的启动binder线程池的方法proc->startThreadPool();

 virtual void onZygoteInit()
 {
     sp<ProcessState> proc = ProcessState::self();
     ALOGV("App process: starting thread pool.\n");
     proc->startThreadPool();
 }

找到ProcessState类,路径是/frameworks/native/libs/binder/ProcessState.cpp,找到startThreadPool方法,如下:

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

其中有个判断是变量,由于支持Binder通信的进程中都有一个ProcessState类,它里面有一个mThreadPoolStarted 变量,来表示Binder线程池是否已经被启动过,默认值为false。在每次调用这个函数时都会先去检查这个标记,从而确保Binder线程池只会被启动一次。
如果Binder线程池未被启动则设置mThreadPoolStarted为true,最后调用spawnPooledThread函数来创建线程池中的第一个线程,也就是线程池的main线程。

找到spawnPooledThread方法,如下,,如果线程池启动则创建一个PoolThread,实际上Binder线程为一个PoolThread,然后调用run方法来运行。

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();
        ALOGV("Spawning new pooled thread, name=%s\n", name.string());
        sp<Thread> t = new PoolThread(isMain);
        t->run(name.string());
    }
}

找到类PoolThread,PoolThread类继承了Thread类。threadLoop方法中调用IPCThreadState的joinThreadPool函数,将当前线程注册到Binder驱动程序中,这样我们创建的线程就加入了Binder线程池中,这样新创建的SyetemServer进程就支持Binder进程间通信了。

class PoolThread : public Thread
{
public:
    explicit PoolThread(bool isMain)
        : mIsMain(isMain)
    {
    }
    
protected:
    virtual bool threadLoop()
    {
        IPCThreadState::self()->joinThreadPool(mIsMain);
        return false;
    }
    
    const bool mIsMain;
};

注意:
1、保证同一进程只有一个ProcessState实例,且只有在ProcessState对象建立时才打开Binder设备以及做内存映射

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }

    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

ProcessState::~ProcessState()
{
    if (mDriverFD >= 0) {
        if (mVMStart != MAP_FAILED) {
        	// 内存映射
            munmap(mVMStart, BINDER_VM_SIZE);
        }
        close(mDriverFD);
    }
    mDriverFD = -1;
}
        
};

2、ProcessState是负责打开Binder节点并做mmap映射并向上层提供IPC服务,IPCThreadState是负责与Binder驱动进行具体的命令交互。
open_driver方法实现打开Binder驱动并进行具体的命令交互。

static int open_driver(const char *driver)
{
    int fd = open(driver, O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
        int vers = 0;
        status_t result = ioctl(fd, BINDER_VERSION, &vers);
        if (result == -1) {
            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
            close(fd);
            fd = -1;
        }
        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
            close(fd);
            fd = -1;
        }
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        if (result == -1) {
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
        }
    } else {
        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
    }
    return fd;
}

2、调用RuntimeInit.applicationInit方法启动应用程序
RuntimeInit.java类,路径是/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java,找到applicationInit方法如下:

protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        // If the application calls System.exit(), terminate the process
        // immediately without running any shutdown hooks.  It is not possible to
        // shutdown an Android application gracefully.  Among other things, the
        // Android runtime shutdown hooks close the Binder driver, which can cause
        // leftover running threads to crash before the process actually exits.
        nativeSetExitWithoutCleanup(true);

        // We want to be fairly aggressive about heap utilization, to avoid
        // holding on to a lot of memory that isn't needed.
        // 初始化虚拟机环境
        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);
        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);

        final Arguments args;
        try {
            args = new Arguments(argv);
        } catch (IllegalArgumentException ex) {
            Slog.e(TAG, ex.getMessage());
            // let the process exit
            return;
        }

        // 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
        // 调用main方法
        invokeStaticMain(args.startClass, args.startArgs, classLoader);
   }

从代码可以看到主要做了两件事,一个是初始化虚拟机环境,一个是调用了invokeStaticMain方法,找到该方法如下:

private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
            throws Zygote.MethodAndArgsCaller {
        Class<?> cl;

        try {
            cl = Class.forName(className, true, classLoader);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException(
                    "Missing class when invoking static main " + className,
                    ex);
        }

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

        /*
         * This throw gets caught in ZygoteInit.main(), which responds
         * by invoking the exception's run() method. This arrangement
         * clears up all the stack frames that were required in setting
         * up the process.
         */
        throw new Zygote.MethodAndArgsCaller(m, argv);
    }

这里主要是通过反射的方式获取SystemServer类实例,classsName就是com.android.server.SystemServer(见上面ZygoteInit.java类中startSystemServer方法中配置的启动参数),最后执行创建Zygote.MethodAndArgsCaller(m, argv)类。找到该类如下:

public static class MethodAndArgsCaller extends Exception
            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;
        }

        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.java的main方法,到这,zygote进程就成功fork出system_server进程,并调用了SystemServer.java的main方法。
接着分析SystemServer.java的main方法,类路径是:/frameworks/base/services/java/com/android/server/SystemServer.java,方法实现如下:

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

找到run方法如下:

private void run() {
        try {
           // ......
           // 1、启动looper循环
            Looper.prepareMainLooper();

            // Initialize native services.
            // 2、初始化libandroid_servers.so库
            System.loadLibrary("android_servers");

            // Check whether we failed to shut down last time we tried.
            // This call may not return.
            performPendingShutdown();

            // Initialize the system context.
            createSystemContext();

            // Create the system service manager.
            ///3、创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。启动系统的各种服务。
            mSystemServiceManager = new SystemServiceManager(mSystemContext);
            mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
            LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
            // Prepare the thread pool for init tasks that can be parallelized
            SystemServerInitThreadPool.get();
        } finally {
            traceEnd();  // InitBeforeStartServices
        }

        // Start services.
        try {
            traceBeginAndSlog("StartServices");
            // 4、启动引导服务
            startBootstrapServices();
            ///5、启动核心服务
            startCoreServices();
            // 6、启动其他服务
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {
            Slog.e("System", "******************************************");
            Slog.e("System", "************ Failure starting system services", ex);
            throw ex;
        } finally {
            traceEnd();
        }
		// ......

        // Loop forever.
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

从run方法中可以看到主要做了以下几件事:

  1. 启动服务都是在Looper循环中执行。system_server进程中的主线程是不能退出的,一旦退出子线程也会退出,所以进入loop循环。
  2. 初始化libandroid_servers.so库,system_server进程中启动的服务器的native代码都在这个共享库中。
  3. 创建SystemServiceManager,它会对系统的服务进行创建、启动和生命周期管理。启动系统的各种服务。
  4. 启动引导服务
  5. 启动核心服务
  6. 启动其他服务

这里把系统服务分为了三种类型,分别是引导服务、核心服务和其他服务,其中其他服务为一些非紧要和一些不需要立即启动的服务。系统服务大约有80多个,这里列出部分系统服务以及它们的作用:

引导服务作用
Installer系统安装apk时的一个服务类,启动完成Installer服务之后才能启动其他的系统服务
ActivityManagerService负责四大组件的启动、切换、调度
PowerManagerService计算系统中与Power相关的计算,然后决策系统应该如何反应
LightsService管理和显示背光LED
DisplayManagerService管理和显示背光LED
UserManagerService多用户模式管理
PackageManagerService用来对apk进行安装、解析、删除、卸载等操作
OverlayManagerServiceOverlayManagerService(OMS)可以在运行时动态替换res等资源
SensorService为系统提供各种感应器服务,调用的是native方法
核心服务作用
DropBoxManagerServiceDropBoxManagerService(简称DBMS) 记录着系统关键log信息,主要功能用于Debug调试。
BatteryService管理电池相关的服务
UsageStatsService收集用户使用每一个APP的频率、使用时间
WebViewUpdateServicewebview更新服务
其他服务作用
CameraService摄像头相关服务
AlarmManagerService全局定时器管理服务
InputManagerService管理输入事件服务
WindowManagerService窗口管理服务
VrManagerServiceVR模式管理服务
BluetoothService蓝牙管理服务
NotificationManagerService通知栏管理服务,Android中的通知栏和状态栏在一起,只是界面上前者在左边,后者在右边
DeviceStorageMonitorService存储相关管理服务
LocationManagerService地理位置管理服务
AudioService音频相关管理服务
AccessibilityManagerService辅助管理服务
ContentServiceContentProvider服务,提供跨进程数据交换
NetworkManagementService网络管理服务

问题与思考

1、System Server是什么?

System Server是Android系统的核心,是 Android JAVA 层的系统服务模块,这个模块主要功能就是管理供 Android 应用开发的各种系统服务,比如AMS、PMS、WMS等服务. 在Dalvik虚拟机启动后立即开始初始化和运行。其它的系统服务在System Server进程的环境中运行。

2、System Server主要做了哪些事情?

  • 启动binder线程池
  • 启动各种服务

3、System Server中启动binder线程池作用?

因为system_server进程中许多服务要与其他进程进行通信,比如要与应用进程进行通信,所以要启动binder机制进行跨进程通信。

4、系统服务都运行在哪些线程中?
主线程:负责Message通信。
工作线程:

  • 独有线程,AMS、PMS、WMS
  • 公用线程DisplayThread、FgThread、IoThread、UiThread
  • 跨进程通信都在binder线程,所以系统服务们也在binder线程中

5、系统服务们如何解决相互依赖?
分批启动和分阶段启动,启动之后再去调用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ruiurrui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值