framework | SystemServer进程流程分析

2,422 阅读13分钟

前言

前面该系列文章我们分析了用户态第一个进程init进程,和开启Java世界的Zygote进程的流程分析,本篇文章我们来分析一下SystemServer进程,即系统服务进程。

系统服务进程由Zygote进程创建而来,它的作用是用于创建和管理系统服务,比如我们熟知的AMS、WMS和PMS等都是由它来创建的,所以它可以看成是Java Framework的管理者。

正文

话不多说,我们就来看看该进程的启动流程。

Zygote启动SystemServer进程

该部分内容在上一篇Zygote进程分析中有所涉及,主要就是ZygoteInit中的forkSystemServer方法,在该方法中底层通过fork系统调用先创建进程,然后调用handleSystemServerProcess方法来处理系统服务进程。大致代码如下:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    private static Runnable forkSystemServer(String abiList, String socketName,
621            ZygoteServer zygoteServer) {
622        ...
            //各种参数
641        String args[] = {
642            "--setuid=1000",
643            "--setgid=1000",
644            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
645            "--capabilities=" + capabilities + "," + capabilities,
646            "--nice-name=system_server",
647            "--runtime-args",
                //最后调用的Java类
648            "com.android.server.SystemServer",
649        };
650        ZygoteConnection.Arguments parsedArgs = null;
651
652        int pid;
653
654        try {
655            parsedArgs = new ZygoteConnection.Arguments(args);
656            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
657            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
658
               //通过fork创建了新进程,即系统服务进程
660            pid = Zygote.forkSystemServer(
661                    parsedArgs.uid, parsedArgs.gid,
662                    parsedArgs.gids,
663                    parsedArgs.debugFlags,
664                    null,
665                    parsedArgs.permittedCapabilities,
666                    parsedArgs.effectiveCapabilities);
667        } catch (IllegalArgumentException ex) {
668            throw new RuntimeException(ex);
669        }
670
671        //系统服务进程运行分支
672        if (pid == 0) {
673            if (hasSecondZygote(abiList)) {
674                waitForSecondaryZygote(socketName);
675            }
676            //系统服务进程不需要监听socket,所以关闭
677            zygoteServer.closeServerSocket();
                //处理系统服务进程
678            return handleSystemServerProcess(parsedArgs);
679        }
680
681        return null;
682    }

所以这里主要逻辑就来到了handleSystemServerProcess方法,由该方法开启系统服务进程的业务流程。

SystemServer业务流程分析

我们来看看主要逻辑的方法:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {
453       ...
500        } else {
501            ClassLoader cl = null;
502            if (systemServerClasspath != null) {
                    //创建PathClassLoader
503                cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
504
505                Thread.currentThread().setContextClassLoader(cl);
506            }
                //初始化
511            return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
512        }
513
514        /* should never reach here */
515    }

这里首先是创建PathClassLoader,关于类加载,我们后面文章细说,然后调用了ZygoteInit的zygoteInit函数:

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
852        if (RuntimeInit.DEBUG) {
853            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
854        }
855
856        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
857        RuntimeInit.redirectLogStreams();
858
859        RuntimeInit.commonInit();
            //这里启动了Binder线程池
860        ZygoteInit.nativeZygoteInit();
            //初始化业务
861        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
862    }

这个方法中先启动了Binder线程池,然后开始进行系统服务进程的各种服务启动、管理工作。

这里有个很关键的点,就是启动Binder线程池,关于Binder通信我们最熟悉的就是AIDL,而AIDL或者Binder的工作原理中服务端需要有一个线程池来处理客户端的请求,这里给出一张AIDL工作原理图:

image.png

从上图我们可以发现Binder通信是基于C/S架构的,服务端处理数据会放入线程池中处理,所以每个需要使用Binder通信的进程都必须要创建Binder线程池

这也从另一个方面验证了一点,即上面启动进程的zygoteInit函数,都会创建一个用于Binder通信的线程池,而上一篇文章所说的Zygote进程却没有这个,所以和Zygote进程通信方式还是Socket,从SystemServer开始,系统服务进程和其他进程比如APP进程,就是使用Binder了

启动Binder线程池

关于Binder的设计非常复杂,涉及知识点特别多,后续我们仔细说,这里先看看如何启动Binder线程池。

nativeZygoteInit方法是一个native方法,因此我们需要找到它的JNI文件,找到对应的C++文件。由Java文件定义的native方法,找到JNI方法是有技巧的,比如这里的方法和类名分别是com.android.internal.os.ZygoteInit和nativeZygoteInit,所以它对应的JNI函数名就是把Java中的.换成_,即com_android_internal_os_ZygoteInit_nativeZygoteInit方法,该方法定义:

/frameworks/base/core/jni/AndroidRuntime.cpp
static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
223  {
224      gCurRuntime->onZygoteInit();
225  }

这里关于JNI类型的细节我们不做讨论,我们可以成功找到该上面本地方法对应的C++代码,当然这种按名字的找法不一定对,因为Java中定义一个Native方法和其C/c++实现方法是通过JNI注册来做的一一对应关系,注册如下:

/frameworks/base/core/jni/AndroidRuntime.cpp
 int register_com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env)
250  {
251      const JNINativeMethod methods[] = {
252          { "nativeZygoteInit", "()V",
253              (void*) com_android_internal_os_ZygoteInit_nativeZygoteInit },
254      };
255      return jniRegisterNativeMethods(env, "com/android/internal/os/ZygoteInit",
256          methods, NELEM(methods));
257  }

关于jni注册的原理我们后面JNI文章再说。

这里我们就只需要知道,在上面Java文件中定义的Native方法对应着com_android_internal_os_ZygoteInit_nativeZygoteInit即可。

在该方法中,gCurRuntime就是AppRuntime(AndroidRuntime子类)的对象,这里是其成员方法:

/frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit()
92      {
93          sp<ProcessState> proc = ProcessState::self();
94          ALOGV("App process: starting thread pool.\n");
95          proc->startThreadPool();
96      }

这里又调用了ProcessState的startThreadPool方法,这个ProcessState是Binder相关的类,这里方法就是创建线程池,我们不继续向下分析了。

分析这里主要就是给大家说一下如何找到JNI方法对应的C/C++方法,关于JNI原理后面文章细说。

SystemServer业务流程

在上面创建完Binder线程池后,会调用RuntimeInit中的applicationInit静态方法:

/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
291              ClassLoader classLoader) {
292         ...
310          return findStaticMain(args.startClass, args.startArgs, classLoader);
311      }

然后调用findStaticMain方法:

/frameworks/base/core/java/com/android/internal/os/RuntimeInit.java
    private static Runnable findStaticMain(String className, String[] argv,
233              ClassLoader classLoader) {
234          Class<?> cl;
            //这里的className为com.android.server.SystemServer
            //通过反射找到SystemServer的Java类
236          try {
237              cl = Class.forName(className, true, classLoader);
238          } catch (ClassNotFoundException ex) {
239              throw new RuntimeException(
240                      "Missing class when invoking static main " + className,
241                      ex);
242          }
243  
244          Method m;
            //找到SystemServer的main方法
245          try {
246              m = cl.getMethod("main", new Class[] { String[].class });
247          } catch (NoSuchMethodException ex) {
248              throw new RuntimeException(
249                      "Missing static main on " + className, ex);
250          } catch (SecurityException ex) {
251              throw new RuntimeException(
252                      "Problem getting static main on " + className, ex);
253          }
254  
255          int modifiers = m.getModifiers();
256          if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
257              throw new RuntimeException(
258                      "Main method is not public and static on " + className);
259          }
260  
261         //调用main方法
267          return new MethodAndArgsCaller(m, argv);
268      }

这里我们的调用流程就转移到了SystemServer.java的main方法:

/frameworks/base/services/java/com/android/server/SystemServer.java
    public static void main(String[] args) {
267          new SystemServer().run();
268      }
/frameworks/base/services/java/com/android/server/SystemServer.java
     private void run() {
278          try {
279             ...
                //创建消息Looper,用于线程间通信
364              Looper.prepareMainLooper();
365  
366              //加载native库
367              System.loadLibrary("android_servers");
368  
371              performPendingShutdown();
372  
373              //创建系统的Context
374              createSystemContext();
375  
376              //创建系统服务管理类
377              mSystemServiceManager = new SystemServiceManager(mSystemContext);
378              mSystemServiceManager.setRuntimeRestarted(mRuntimeRestart);
379              LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
380              // Prepare the thread pool for init tasks that can be parallelized
381              SystemServerInitThreadPool.get();
382          } finally {
383              traceEnd();  // InitBeforeStartServices
384          }
385  
386          //开始开启各种服务
387          try {
388              traceBeginAndSlog("StartServices");
                //开始引导服务
389              startBootstrapServices();
                //开始核心服务
390              startCoreServices();
                //开始其他服务
391              startOtherServices();
392              SystemServerInitThreadPool.shutdown();
393          } catch (Throwable ex) {
394              Slog.e("System", "******************************************");
395              Slog.e("System", "************ Failure starting system services", ex);
396              throw ex;
397          } finally {
398              traceEnd();
399          }
                ...
401          //开始loop
416          Looper.loop();
417          throw new RuntimeException("Main thread loop unexpectedly exited");
418      }

这里就是SystemServer进程所做的事情,主要包括:

  • 创建和循环Looper,这个用于线程间通信,关于Handler知识,后面将会从应用层到底层仔细分析;
  • 加载了动态库libandroid_servers.so,这里是为了找到Native层的C/C++代码;
  • 创建系统Context,关于Context我们后面文章单独分析。
  • 创建了系统服务管理类实例mSystemServiceManager,它的类型是SystemServiceManager,用来创建、启动以及管理系统服务的一些生命周期事件

然后主要工作就是开启各种服务,这里的服务主要分为3类,一共加起来有好几十个,下面列举一些主要的服务:

引导服务作用
Installer系统安装APK时的一个服务类,启动完成Installer服务之后才能其他其他的系统服务
ActivityManagerService负责四大组件的启动、切换和调度
PowerManagerService计算系统中和Power相关的计算,然后决策系统应该如何反应
LightsService管理和显示背光LED
DisplayManagerService用来管理所有显示设备
UserManagerService多用户模式管理
SensorService为消停提供各种感应服务
PackageManagerService用来对APK进行安装、解析、删除、卸载等操作
核心服务作用
DropBoxManagerService用于生成和管理系统允许时的一些日志文件
Battery管理电池的服务
UsageStatsService收集用户使用每一个APP的评率、时长等
其他服务作用
CameraService摄像头相关服务
AlarmManagerService全局定时器管理服务
InputManagerService管理输入事件
WindowManagerService窗口管理服务
BluetoothService蓝牙管理服务

等等

这些系统服务承担了Android系统的各种职责,通过相互合作让我们可以使用和开发上层应用,这些服务特别多,也不用都需要掌握,一般都是了解其中重要的几个。

当然本章内容不是介绍这些服务,而是说服务启动,这里以PowerManagerService和PackageManagerService来举例。

启动服务细节

这里我们先看PowerManagerService的启动流程,首先是SystemService.java中的startBootstrapServices()函数中调用:

/frameworks/base/services/java/com/android/server/SystemServer.java
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);

这里调用SystemServiceManager.java中的startService方法,该方法有好几个重载方法,先调用下面这个:

/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
//创建和启动一个系统服务,该服务必须是SystemService的子类
    public <T extends SystemService> T startService(Class<T> serviceClass) {
83          ...
                //通过反射创建系统服务实例
93              final T service;
94              try {
95                  Constructor<T> constructor = serviceClass.getConstructor(Context.class);
96                  service = constructor.newInstance(mContext);
97              } catch (InstantiationException ex) {
98                  throw new RuntimeException("Failed to create service " + name
99                          + ": service could not be instantiated", ex);
100              } catch (IllegalAccessException ex) {
101                  throw new RuntimeException("Failed to create service " + name
102                          + ": service must have a public constructor with a Context argument", ex);
103              } catch (NoSuchMethodException ex) {
104                  throw new RuntimeException("Failed to create service " + name
105                          + ": service must have a public constructor with a Context argument", ex);
106              } catch (InvocationTargetException ex) {
107                  throw new RuntimeException("Failed to create service " + name
108                          + ": service constructor threw an exception", ex);
109              }
                //启动服务
111              startService(service);
112              return service;
113          } finally {
114              Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
115          }
116      }

这里代码比较简单就是通过反射创建其实例,这里必须注意一点就是所有系统服务都必须是SystemServer.java的子类,然后这里再调用另一个重载函数startService:

/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
     public void startService(@NonNull final SystemService service) {
             //注册该service
120          mServices.add(service);
122          long time = SystemClock.elapsedRealtime();
123          try {
                //开启服务
124              service.onStart();
125          } catch (RuntimeException ex) {
126              throw new RuntimeException("Failed to start service " + service.getClass().getName()
127                      + ": onStart threw an exception", ex);
128          }
129          warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart");
130      }

这里的mServices就是一个ArrayList,保存着需要接收响应事件的系统服务,然后就是调用其onStart()方法:

/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
         @Override
686      public void onStart() {
            //发布到Binder服务中
687          publishBinderService(Context.POWER_SERVICE, new BinderService());
688          publishLocalService(PowerManagerInternal.class, new LocalService());
689  
690          Watchdog.getInstance().addMonitor(this);
691          Watchdog.getInstance().addThread(mHandler);
692      }

这里我们来重点看一下这个发布到Binder服务中的操作,因为这个涉及Binder通信,先看一下这个BinderService是啥:

private final class BinderService extends IPowerManager.Stub 

这里的代码熟悉AIDL的应该知道,这里会定义一个IPowerManager.aidl的远程接口,用于IPC,然后这里的IPowerManager.Stub则是生成的Java类,实现了IBinder接口,是一个Binder对象,所以这里发布到Binder服务中的是一个Binder实例,接着看一下publishBinderService方法:

/frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
198      protected final void publishBinderService(String name, IBinder service) {
199          publishBinderService(name, service, false);
200      }
201  
205      protected final void publishBinderService(String name, IBinder service,
206              boolean allowIsolated) {
207          ServiceManager.addService(name, service, allowIsolated);
208      }

这里最终会通过ServiceManager把刚刚那个Binder给添加进来,更多关于ServiceManager的内容,后面介绍Binder时再细说。

这里给AIDL通信简单画个时序示意图:

sequenceDiagram
SystemServer ->> PowerManagerService:创建、启动服务
PowerManagerService ->> PowerManagerService:new BinderService() 获取Binder对象
PowerManagerService ->> SystemServiceManager:publishBinderService() 传递Binder对象
SystemServiceManager ->> ServiceManager:addService 注册Binder

应用进程X ->> SystemServiceManager:想和PowerManagerService通信
SystemServiceManager ->> 应用进程X:返回Binder引用
Note over 应用进程X,PowerManagerService:应用进程X和PowerManagerService通过Binder进行通信

由上面图我们可知能进行Binder跨进程通信的前提还得需要注册和"中间人"角色

除了通过用mSystemServiceManager的startService启动系统服务外,还可以通过下面方式启动,我们以PMS为例:

/frameworks/base/services/java/com/android/server/SystemServer.java
 mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
586                  mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
/frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
 public static PackageManagerService main(Context context, Installer installer,
2347              boolean factoryTest, boolean onlyCore) {
2348         
2349          PackageManagerServiceCompilerMapping.checkProperties();
2350  
                //通过new创建对象
2351          PackageManagerService m = new PackageManagerService(context, installer,
2352                  factoryTest, onlyCore);
2353          m.enableSystemUserPackages();
2354          ServiceManager.addService("package", m);
2355          final PackageManagerNative pmn = m.new PackageManagerNative();
2356         
                //注册Binder
                ServiceManager.addService("package_native", pmn);
2357          return m;
2358      }

这里可以直接调用系统服务的main函数来创建和启动系统服务,同样也必不可少地需要注册Binder到ServiceManager中。

总结

系统服务进程被创建后,先创建了Context、开启Looper、加载so等常规操作,主要的工作如下:

  • 启动Binder线程池,为Binder服务做基础,因为Binder通信需要线程池来处理请求。
  • 创建SystemServiceManager,用于对系统服务进行创建、启动和生命周期管理。
  • 启动各种服务,在各种服务中都少不了注册Binder,为了通过Binder和其他进程通信。

随着Android系统代码的梳理,一方面逐渐了理解了各种设计的巧妙和新知识,一方面也发现很多技术债,比如前面的Linux、JNI、so库等技术,还有本章涉及的Context、Looper等知识,这些知识很多之前都涉及过,但是没有个系统理解和总结,总是感觉无法完全理解,还需要不断加油突破这些难点。

笔者水平有限,文中有问题,欢迎指正。最后记录一下Flag。# 一个Android开发的学习Flag记录贴