Android 9 (P)系统启动之SystemServer大揭秘下
Android 9 系统启动之SystemServer大揭秘下
前言
在前面的章节Android 9 系统启动之SystemServer大揭秘上中,我们细说了Android的system_server进程的出身及启动流程,在今天的篇章中我们将要看看system_server进程作为Android世界的肱骨大臣究竟有何功劳,能在Android世界享有如此美誉能和zygote同生共死。下面就让我们来看看system_serveer究竟有何丰功伟绩,让我们细品!
注意:本文演示的代码是Android P高通msm8953平台源码。其中涉及的源码路径如下:
frameworks/base/services/java/com/android/server/SystemServer.javaframeworks/base/core/java/android/app/ActivityThread.javaframeworks/base/services/core/java/com/android/server/power/ShutdownThread.javaframeworks/base/core/java/android/app/ContextImpl.javaframeworks/base/core/java/android/app/LoadedApk.javaframeworks/base/services/core/java/com/android/server/SystemServiceManager.javaframeworks/base/services/core/java/com/android/server/SystemServiceManager.java
一. SystemServer彪悍的一生
通过前面章节我们知道最后通过反射调用mMethod.invoke开启了SystemServer的彪悍人生,最终会调用到SystemServer.main()方法,还等什么让我们一探究竟。整个system_server进程启动流程图如下:
SystemServer.main()启动流程图示意如下,这章主要详细分析如下几个流程.
1.1 SystemServer.main
无过多修饰,直接创建new一个SystemServer对象并调用其run方法。
public static void main(String[] args) { new SystemServer().run();//就是这么简单,霸气有总裁范啊,直接创建并运行毫不拖泥带水的 }
1.2 SystemServer.run
前面霸道总裁装逼了一会儿,得开始干正事了,上来就是一堆代码啊!其主要逻辑无外乎前面总结的:
- 初始化一些零碎事务
- createSystemContext初始化system_server进程的context,这个是重点需要分析的
- startBootstrapServices启动第一阶段服务
- startCoreServices启动核心服务
- startOtherServices启动其它服务
private void run() { try { //这个主要是为了调试使用,打日志 traceBeginAndSlog("InitBeforeStartServices"); // If a device's clock is before 1970 (before 0), a lot of // APIs crash dealing with negative numbers, notably // java.io.File#setLastModified, so instead we fake it and // hope that time from cell towers or NTP fixes it shortly. //如果系统时钟早于1970,则系统强制设置从1970年开始 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) { Slog.w(TAG, "System clock is before 1970; setting to 1970."); SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME); } // // Default the timezone property to GMT if not set. // //如果没有设置默认时区,则强制设置默认时区为GMT String timezoneProperty = SystemProperties.get("persist.sys.timezone"); if (timezoneProperty == null || timezoneProperty.isEmpty()) { Slog.w(TAG, "Timezone not set; setting to GMT."); SystemProperties.set("persist.sys.timezone", "GMT"); } // If the system has "persist.sys.language" and friends set, replace them with // "persist.sys.locale". Note that the default locale at this point is calculated // using the "-Duser.locale" command line flag. That flag is usually populated by // AndroidRuntime using the same set of system properties, but only the system_server // and system apps are allowed to set them. // // NOTE: Most changes made here will need an equivalent change to // core/jni/AndroidRuntime.cpp //设置区域,语言等选项 if (!SystemProperties.get("persist.sys.language").isEmpty()) { final String languageTag = Locale.getDefault().toLanguageTag(); SystemProperties.set("persist.sys.locale", languageTag); SystemProperties.set("persist.sys.language", ""); SystemProperties.set("persist.sys.country", ""); SystemProperties.set("persist.sys.localevar", ""); } // The system server should never make non-oneway calls Binder.setWarnOnBlocking(true);//这几个暂时还没有搞清楚是干啥的主要,先忽略 // The system server should always load safe labels PackageItemInfo.setForceSafeLabels(true); // Default to FULL within the system server. SQLiteGlobal.sDefaultSyncMode = SQLiteGlobal.SYNC_MODE_FULL; // Deactivate SQLiteCompatibilityWalFlags until settings provider is initialized SQLiteCompatibilityWalFlags.init(null); // Here we go! Slog.i(TAG, "Entered the Android system server!"); int uptimeMillis = (int) SystemClock.elapsedRealtime(); EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis); if (!mRuntimeRestart) { MetricsLogger.histogram(null, "boot_system_server_init", uptimeMillis); } // In case the runtime switched since last boot (such as when // the old runtime was removed in an OTA), set the system // property so that it is in sync. We can | xq oqi't do this in // libnativehelper's JniInvocation::Init code where we already // had to fallback to a different runtime because it is // running as root and we need to be the system user to set // the property. http://b/11463182 //变更虚拟机的库文件,这里默认使用的是libart.so SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary()); // Mmmmmm... more memory! //由于system_server进程启动过程中消耗较多的虚拟机内存空间,所以先清除vm内存增长上限,供SystemServer正常启动 VMRuntime.getRuntime().clearGrowthLimit(); // The system server has to run all of the time, so it needs to be // as efficient as possible with its memory usage. //设置堆栈利用率为0.8,GC后会重新计算堆栈空间大小 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f); // Some devices rely on runtime fingerprint generation, so make sure // we've defined it before booting further. // 针对部分设备依赖于运行时就产生指纹信息,因此需要在开机完成前已经定义 Build.ensureFingerprintProperty(); // Within the system server, it is an error to access Environment paths without // explicitly specifying a user. //明确指定用户,访问环境变量前 Environment.setUserRequired(true); // Within the system server, any incoming Bundles should be defused // to avoid throwing BadParcelableException. BaseBundle.setShouldDefuse(true);//这个不是很明白,先忽略 // Within the system server, when parceling exceptions, include the stack trace Parcel.setStackTraceParceling(true);//看英文意思是Parceling打包发生异常,会打印堆栈调试信息 // Ensure binder calls into the system always run at foreground priority. //确保当前系统进程的binder调用,总是运行在前台优先级(foreground priority),并且设置binder最大线程数位31 BinderInternal.disableBackgroundScheduling(true); // Increase the number of binder threads in system_server BinderInternal.setMaxThreads(sMaxBinderThreads); // Prepare the main looper thread (this thread). android.os.Process.setThreadPriority( android.os.Process.THREAD_PRIORITY_FOREGROUND); android.os.Process.setCanSelfBackground(false);//开启主线程Looper Looper.prepareMainLooper(); Looper.getMainLooper().setSlowLogThresholdMs( SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS); // Initialize native services. //加载android_servers.so库,该库就是frameworks/base/services/core/jni生成的 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();//重点来了,在system_server进程中创建Context,供后续启动的服务使用,具体将章节1.3 // Create the system service manager. //构建SystemServiceManager对象,注意这个不是Android binder服务的大管家那个 mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); // 将SystemServiceManager对象保存到SystemServer进程中的一个数据结构中 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"); startBootstrapServices();//启动系统Boot级别服务 startCoreServices();//启动系统级别核心服务 startOtherServices();//启动其它类型服务,主要是厂家可以根据实际情况配置的服务 SystemServerInitThreadPool.shutdown(); } catch (Throwable ex) { Slog.e("System", "******************************************"); Slog.e("System", "************ Failure starting system services", ex); throw ex; } finally { traceEnd(); } StrictMode.initVmDefaults(null); if (!mRuntimeRestart && !isFirstBootOrUpgrade()) { int uptimeMillis = (int) SystemClock.elapsedRealtime(); MetricsLogger.histogram(null, "boot_system_server_ready", uptimeMillis); final int MAX_UPTIME_MILLIS = 60 * 1000; if (uptimeMillis > MAX_UPTIME_MILLIS) { Slog.wtf(SYSTEM_SERVER_TIMING_TAG, "SystemServer init took too long. uptimeMillis=" + uptimeMillis); } } // Loop forever. Looper.loop();//启动Looper循环 throw new RuntimeException("Main thread loop unexpectedly exited"); }
1.2.1 performPendingShutdown
这个地方不是很明白为啥要检测sys.shutdown.requested值是否为空,然后为空后需要重启终端。这个各位如果了解,也可以沟通沟通!
private void performPendingShutdown() { final String shutdownAction = SystemProperties.get( ShutdownThread.SHUTDOWN_ACTION_PROPERTY, ""); //如果sys.shutdown.requested的值不为空则会重启终端 if (shutdownAction != null && shutdownAction.length() > 0) { boolean reboot = (shutdownAction.charAt(0) == '1'); final String reason; if (shutdownAction.length() > 1) { reason = shutdownAction.substring(1, shutdownAction.length()); } else { reason = null; } // If it's a pending reboot into recovery to apply an update, // always make sure uncrypt gets executed properly when needed. // If '/cache/recovery/block.map' hasn't been created, stop the // reboot which will fail for sure, and get a chance to capture a // bugreport when that's still feasible. (Bug: 26444951) if (reason != null && reason.startsWith(PowerManager.REBOOT_RECOVERY_UPDATE)) { File packageFile = new File(UNCRYPT_PACKAGE_FILE); if (packageFile.exists()) { String filename = null; try { filename = FileUtils.readTextFile(packageFile, 0, null); } catch (IOException e) { Slog.e(TAG, "Error reading uncrypt package file", e); } if (filename != null && filename.startsWith("/data")) { if (!new File(BLOCK_MAP_FILE).exists()) { Slog.e(TAG, "Can't find block map file, uncrypt failed or " + "unexpected runtime restart?"); return; } } } } Runnable runnable = new Runnable() { @Override public void run() { synchronized (this) { ShutdownThread.rebootOrShutdown(null, reboot, reason); } } }; // ShutdownThread must run on a looper capable of displaying the UI. //这个很常见不多说了 Message msg = Message.obtain(UiThread.getHandler(), runnable); msg.setAsynchronous(true); UiThread.getHandler().sendMessage(msg); } }
1.3 createSystemContext初始化系统上下文
这个知识点比较重要,我们分析分析该方法,其代码逻辑如下:
- 创建system_server进程的上下文环境
- 设置主题样式
private void createSystemContext() { //创建system_server进程上下文环境 ActivityThread activityThread = ActivityThread.systemMain(); mSystemContext = activityThread.getSystemContext(); mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);//设置主题 final Context systemUiContext = activityThread.getSystemUiContext(); systemUiContext.setTheme(DEFAULT_SYSTEM_THEME); }
1.3.1 ActivityThread.systemMain
该类定义在frameworks/base/core/java/android/app/ActivityThread.java中,这个类大伙因该比较熟悉或者耳闻过其大名。
ActivityThread() { mResourcesManager = ResourcesManager.getInstance();//单例模式 } public static ActivityThread systemMain() { // The system process on low-memory devices do not get to use hardware // accelerated drawing, since this can add too much overhead to the // process. if (!ActivityManager.isHighEndGfx()) {//判断是否是低内存设备,如果是低内存设备禁用硬件加速 ThreadedRenderer.disable(true); } else { ThreadedRenderer.enableForegroundTrimming(); } ActivityThread thread = new ActivityThread(); thread.attach(true, 0);//这个在android app的启动过程中也会看到,也是这里需要重点分析的,注意这里传入的参数 return thread; }
1.3.2 ActivityThread.attach
让我们接着继续分析attach函数,揭开其面纱看看其到底干了些啥!
private void attach(boolean system, long startSeq) { sCurrentActivityThread = this; mSystemThread = system; if (!system) {//这是Android app启动的分支,暂时不管 ...... } else {//分析Android app启动的时候,我还在想谁会走这条分支呢,原来是system_server进程启动会走 // Don't set application object here -- if the system crashes, // we can't display an alert, we just want to die die die. android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId());//设置system_server进程在DDMS中的名称为system_process,system_server和system_process都是同一个进程只是套了不同的马甲,各位不要被蒙骗了 try { mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); // 先通过getSystemContext()创建系统上下文,然后通过createAppContext创建应用上下文 ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); //创建Application mInitialApplication = context.mPackageInfo.makeApplication(true, null); // 调用Application的onCreate() mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } } // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> { synchronized (mResourcesManager) { // We need to apply this change to the resources immediately, because upon returning // the view hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, null /* compat */)) { updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), mResourcesManager.getConfiguration().getLocales()); // This actually changed the resources! Tell everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { mPendingConfiguration = globalConfig; sendMessage(H.CONFIGURATION_CHANGED, globalConfig); } } } };//设置ViewrOotImpl回调,譬如语言,横竖变化时回调 ViewRootImpl.addConfigCallback(configChangedCallback); }
通过上述的代码分析,我们可以归纳此时的attach主要干了如下几个事情:
- 创建系统上下文:getSystemContext() -> createSystemContext() -> new ContextImpl()
- 创建应用上下文:ContextImpl.createAppContext() -> new ContextImpl()
- 添加回调configChangedCallback到ViewRootImpl
1.3.3 ActivityThread.getSystemContext
让我们继续跟进getSystemContext,该函数比较简单直接调用ContextImpl.createSystemContext创建系统上下文。
public ContextImpl getSystemContext() { synchronized (this) { if (mSystemContext == null) { mSystemContext = ContextImpl.createSystemContext(this); } return mSystemContext; } }
1.3.4 ContextImpl.createSystemContext
该方法定义在frameworks/base/core/java/android/app/ContextImpl.java中,代码如下:
static ContextImpl createSystemContext(ActivityThread mainThread) { // 这边new出来的LoadedApk将作为创建应用上下文的参数packageInfo LoadedApk packageInfo = new LoadedApk(mainThread); //通过ContextImpl创建系统上下文 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null); context.setResources(packageInfo.getResources()); context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(), context.mResourcesManager.getDisplayMetrics()); return context; }
1.3.5 ContextImpl.createAppContext()创建应用上下文
static ContextImpl createAppContext(ActivityThread mainThread, LoadedApk packageInfo) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); //通过ContextImpl创建应用上下文 ContextImpl context = new ContextImpl(null, mainThread, packageInfo, null, null, null, 0, null); context.setResources(packageInfo.getResources()); return context; }
不用怀疑你的眼睛,这里的new ContextImpl的参数创建系统上下文和应用上下文是一样的,这是不是多此一举呢?createAppContext()中的参数packageInfo,就是createSystemContext()中new的LoadedApk。创建完成之后,系统上下文赋值给了ActivityThread的成员变量mSystemContext,而应用上下文只是作为函数中的局部变量临时使用。这是我的理解,不知道谷歌的工程师是不是这么认为的,或者童靴们你们有另外的理解!
1.3.6 LoadedApk.makeApplication
让我们回头看下ActivityThread.attach中创建上下文的内容:
try { mInstrumentation = new Instrumentation(); mInstrumentation.basicInit(this); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); //创建Application mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); }
接下来让我们继续分析makeApplication,该方法定义在frameworks/base/core/java/android/app/LoadedApk.java中,源码如下:
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "makeApplication"); Application app = null; String appClass = mApplicationInfo.className; //这里传入的参数forceDefaultAppClass为true if (forceDefaultAppClass || (appClass == null)) { appClass = "android.app.Application"; } try { java.lang.ClassLoader cl = getClassLoader(); // 此LoadedApk对象是createSystemContext时new的,mPackageName="android",大伙可以回看下 if (!mPackageName.equals("android")) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "initializeJavaContextClassLoader"); initializeJavaContextClassLoader(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } //有创建了一个局部应用上下文 ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); //创建application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { if (!mActivityThread.mInstrumentation.onException(app, e)) { Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); throw new RuntimeException( "Unable to instantiate application " + appClass + ": " + e.toString(), e); } } // 将前面创建的app添加到应用列表 mActivityThread.mAllApplications.add(app); mApplication = app; ...... return app;}
1.3.6 createSystemContext总结
createSystemContext这一章节涉及的知识面比较多,且比较重要,我们分析总结一番。在这一章节里面我们主要是创建了一个ActivityThread对象,这个对象大伙应该都不会感到陌生,然后然后执行了该对象的attach()方法,attach()方法中创建了系统上下文mSystemContext(类型为ContextImpl),并创建Application对象。系统上下文中,new了一个LoadedApk的成员变量,并将ActivityThread对象传给LoadedApk成员,后面的Application对象就是LoadedApk使用ActivityThread创建的,LoadedApk创建了Application对象后,将Application添加到ActivityThread的应用列表中。关于这个章节的内容这里限于主题和篇幅就不过多解释了,如果想更加详细的了解可以参见gityuan的博客理解Application创建过程。
1.4 初始化SystemServiceManager系统服务管理类
让我们收回思路,回到SystemServer中的run方法中看看创建系统服务管理类的代码。
// Create the system service manager. //通过前面章节创建的系统上下文创建mSystemServiceManager mSystemServiceManager = new SystemServiceManager(mSystemContext); //设置mSystemServiceManager 的启动相关信息 mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); //将创建的mSystemServiceManager 添加到LocalServices中 LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
这一流程比较简单,主要逻辑有如下几点:
- 以前面章节创建的系统上下文mSystemContext初始化SystemServiceManager对象
- 设置mSystemServiceManager 对象启动信息,主要是时间和是否是重启等
- 将构建的mSystemServiceManager 其添加到本地服务列表中,本地服务列表是以类为key保存的一个列表,即列表中某种类型的对象最多只能有一个
1.4.1 SystemServiceManager简单分析
该类定义在frameworks/base/services/core/java/com/android/server/SystemServiceManager.java中,主要代码逻辑如下:
public class SystemServiceManager {......//系统服务列表,可以看到必须系统服务必须继承SystemService private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();//当前处于开机过程的哪个阶段,这个定义在SystemService中不是SystemServer中,后续会讲解 private int mCurrentPhase = -1; ......//启动系统服务第一种方式,通过类名 public SystemService startService(String className) { final Class<SystemService> serviceClass; try { serviceClass = (Class<SystemService>)Class.forName(className); } catch (ClassNotFoundException ex) { Slog.i(TAG, "Starting " + className); throw new RuntimeException("Failed to create service " + className + ": service class not found, usually indicates that the caller should " + "have called PackageManager.hasSystemFeature() to check whether the " + "feature is available on this device before trying to start the " + "services that implement it", ex); } return startService(serviceClass); } //第二种启动系统服务方式,创建并启动系统服务,系统服务类必须继承SystemService public <T extends SystemService> T startService(Class<T> serviceClass) { try { final String name = serviceClass.getName(); Slog.i(TAG, "Starting " + name); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name); // Create the service. if (!SystemService.class.isAssignableFrom(serviceClass)) { throw new RuntimeException("Failed to create " + name + ": service must extend " + SystemService.class.getName()); } final T service; try { Constructor<T> constructor = serviceClass.getConstructor(Context.class); service = constructor.newInstance(mContext); } catch (InstantiationException ex) { throw new RuntimeException("Failed to create service " + name + ": service could not be instantiated", ex); } catch (IllegalAccessException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (NoSuchMethodException ex) { throw new RuntimeException("Failed to create service " + name + ": service must have a public constructor with a Context argument", ex); } catch (InvocationTargetException ex) { throw new RuntimeException("Failed to create service " + name + ": service constructor threw an exception", ex); } startService(service); return service; } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } //前面两种启动系统服务的方式,最后都会调用这个方法 public void startService(@NonNull final SystemService service) { // Register it. mServices.add(service); // Start it. long time = SystemClock.elapsedRealtime(); try { service.onStart(); } catch (RuntimeException ex) { throw new RuntimeException("Failed to start service " + service.getClass().getName() + ": onStart threw an exception", ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onStart"); } // 通知系统服务到了开机的哪个阶段,会遍历调用所有系统服务的onBootPhase()函数 public void startBootPhase(final int phase) { if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase; Slog.i(TAG, "Starting phase " + mCurrentPhase); try { Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase); final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); long time = SystemClock.elapsedRealtime(); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, service.getClass().getName()); try { service.onBootPhase(mCurrentPhase); } catch (Exception ex) { throw new RuntimeException("Failed to boot service " + service.getClass().getName() + ": onBootPhase threw an exception during phase " + mCurrentPhase, ex); } warnIfTooLong(SystemClock.elapsedRealtime() - time, service, "onBootPhase"); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } } finally { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } }}
我们这里说mCurrentPhase表示当前处于开机过程的那个阶段,有如下几个阶段,定义在frameworks/base/services/core/java/com/android/server/SystemService.java中,如下所示:
public abstract class SystemService { /* * Boot Phases */ public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency? /** * After receiving this boot phase, services can obtain lock settings data. */ public static final int PHASE_LOCK_SETTINGS_READY = 480; /** * After receiving this boot phase, services can safely call into core system services * such as the PowerManager or PackageManager. */ public static final int PHASE_SYSTEM_SERVICES_READY = 500; /** * After receiving this boot phase, services can safely call into device specific services. */ public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; /** * After receiving this boot phase, services can broadcast Intents. */ public static final int PHASE_ACTIVITY_MANAGER_READY = 550; /** * After receiving this boot phase, services can start/bind to third party apps. * Apps will be able to make Binder calls into services at this point. */ public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; /** * After receiving this boot phase, services can allow user interaction with the device. * This phase occurs when boot has completed and the home application has started. * System services may prefer to listen to this phase rather than registering a * broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency. */ public static final int PHASE_BOOT_COMPLETED = 1000;......}
1.4.2 LocalServices
该类定义在frameworks/base/core/java/com/android/server/LocalServices.java中,逻辑so easy就是将SystemService 存放在hash表中,供后续使用。
public final class LocalServices { private LocalServices() {} private static final ArrayMap<Class<?>, Object> sLocalServiceObjects = new ArrayMap<Class<?>, Object>(); /** * Returns a local service instance that implements the specified interface. * * @param type The type of service. * @return The service object. */ @SuppressWarnings("unchecked") public static <T> T getService(Class<T> type) { synchronized (sLocalServiceObjects) { return (T) sLocalServiceObjects.get(type); } } /** * Adds a service instance of the specified interface to the global registry of local services. */ public static <T> void addService(Class<T> type, T service) { synchronized (sLocalServiceObjects) { if (sLocalServiceObjects.containsKey(type)) { throw new IllegalStateException("Overriding service registration"); } sLocalServiceObjects.put(type, service); } }}
1.5 startBootstrapServices启动引导服务
能被称为引导的东西个人感觉都是牛逼的东西,譬如windows下的BIOS引导程序,当然这里的引导服务也不例外,基本都是Android界的实干家,牛逼的很。
//代码量有点多,所以把默认注释和无关紧要的代码给删掉了 private void startBootstrapServices() { ...... //通过mSystemServiceManager启动Installer,并且是阻塞等待与installd建立socket通道 Installer installer = mSystemServiceManager.startService(Installer.class); //这个服务暂时不清楚是干啥的 mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class); //好吗,这个服务无需多言了,我是AMS重要你懂的 mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService(); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); //PowerManagerService服务,牵涉到电源管理等等方面 mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class); //mPowerManagerService 已经准备就绪,AMS mActivityManagerService.initPowerManagement(); //启动RecoverySystemService mSystemServiceManager.startService(RecoverySystemService.class); //不知是啥,那就只能忽略了 RescueParty.noteBoot(mSystemContext); //启动LightsService服务 mSystemServiceManager.startService(LightsService.class);//这个服务不知是啥,暂时不管了 if (SystemProperties.getBoolean("config.enable_sidekick_graphics", false)) { mSystemServiceManager.startService(WEAR_SIDEKICK_SERVICE_CLASS); } // 启动DisplayManagerService(必须咋PMS服务启动之前) mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);//划重点,初始化package manager之前,需要默认显示。阻塞,10s超时,see DisplayManagerService.onBootPhase() mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); traceEnd(); //当设备正在加密时,仅运行核心 String cryptState = SystemProperties.get("vold.decrypt"); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; } else if (ENCRYPTED_STATE.equals(cryptState)) { Slog.w(TAG, "Device encrypted - only parsing core apps"); mOnlyCore = true; } // Start Carrier regionalization service //开启运营商区域化服务,先放着 if (RegionalizationEnvironment.isSupported()) { Slog.i(TAG, "Regionalization Service"); RegionalizationService regionalizationService = new RegionalizationService(); ServiceManager.addService("regionalization", regionalizationService); }//启动PMS服务 mPackageManagerService = PackageManagerService.main(mSystemContext, installer, mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore); mFirstBoot = mPackageManagerService.isFirstBoot(); mPackageManager = mSystemContext.getPackageManager(); if (!mOnlyCore) { boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt", false); if (!disableOtaDexopt) { traceBeginAndSlog("StartOtaDexOptService"); try { OtaDexoptService.main(mSystemContext, mPackageManagerService); } catch (Throwable e) { reportWtf("starting OtaDexOptService", e); } finally { traceEnd(); } } } //启动多用户服务,新建目录/data/user/ mSystemServiceManager.startService(UserManagerService.LifeCycle.class); // 初始化用来缓存包资源的属性缓存,不要问我怎么知道的,按照注释翻译的 AttributeCache.init(mSystemContext); //设置AMS mActivityManagerService.setSystemProcess(); //直接过 mDisplayManagerService.setupSchedulerPolicies(); //直接过 OverlayManagerService overlayManagerService = new OverlayManagerService( mSystemContext, installer); mSystemServiceManager.startService(overlayManagerService); if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) { // DisplayManager needs the overlay immediately. overlayManagerService.updateSystemUiContext(); LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged(); }//启动sensor服务 mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> { TimingsTraceLog traceLog = new TimingsTraceLog( SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER); traceLog.traceBegin(START_SENSOR_SERVICE); startSensorService(); traceLog.traceEnd(); }, START_SENSOR_SERVICE); }
这里可以看到startBootstrapServices会首先等待installd启动完成,然后阻塞等待和建立连接。接着会启动一系列相关联的重要服务,其中比较常见的和经常会用到的如下表格所示:
引导服务 | 功能 |
---|---|
Installer | 注意和installd的关联,这个是在系统安装apk时的一个服务类, 启动完成installer服务之后才能启动其它的系统服务,是installd的客户端和installd是C-S端架构 |
ActivityManagerService | 牛逼的AMS服务,负责四大组件的启动,切换,调度等相关工作 |
PowerManagerService | 负责Android系统中和Power相关的计算,决策系统的电源策略 |
LightsService | 管理和显示Android相关指示灯服务 |
DisplayManagerService | 用来管理Android所有显示设备服务 |
PackageManagerService | 牛逼的PKMS服务,主要用来管理apk的安装,解析,验签,删除,升级等功能 |
UserManagerService | 多用户模式管理服务 |
SensorService | Android各种感应器管理服务! |
1.6 startCoreServices启动核心服务
无需多言,主要是启动Android系统各种核心服务,核心是啥各位应该都懂!
private void startCoreServices() {// 启动BatteryService,用于管理电池各种状态情况 mSystemServiceManager.startService(BatteryService.class); //启动UsageStatsService服务,该服务主要用于统计应用使用情况 mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); //启动WebViewUpdateService if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_WEBVIEW)) { mWebViewUpdateService = mSystemServiceManager.startService(WebViewUpdateService.class); } // Tracks cpu time spent in binder calls BinderCallsStatsService.start(); }
其中核心服务中常见的和其作用如下表格所示:
核心服务 | 功能 |
---|---|
BatteryService | 电源管理服务,管理电池的各种状态 |
UsageStatsService | 主要用于统计应用的使用情况,如时长,使用频率等 |
WebViewUpdateService | 用于管理webview的更新 |
1.7 startOtherServices启动其它服务
好吗其它,你懂的!就好像各种排名,通常是以其它结束的。这里的代码比较多,没有什么难点,就是启动各种服务。
private void startOtherServices() {......mSystemServiceManager.startService(KeyChainSystemService.class);//启动调度策略服务ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());mSystemServiceManager.startService(TelecomLoaderService.class);telephonyRegistry = new TelephonyRegistry(context);// 提供电话注册、管理服务,可以获取电话的链接状态、信号强度等 ServiceManager.addService("telephony.registry", telephonyRegistry); mSystemServiceManager.startService(ACCOUNT_SERVICE_CLASS);//启动账号管理,密码,认证等相关的服务mSystemServiceManager.startService(CONTENT_SERVICE_CLASS);mActivityManagerService.installSystemProviders();//启动provider服务mSystemServiceManager.startService(DropBoxManagerService.class);vibrator = new VibratorService(context); ServiceManager.addService("vibrator", vibrator); mSystemServiceManager.startService(AlarmManagerService.class);//Alarm服务watchdog.init(context, mActivityManagerService);//启动看门狗服务inputManager = new InputManagerService(context);//启动input输入管理服务wm = WindowManagerService.main(context, inputManager, mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL, !mFirstBoot, mOnlyCore, new PhoneWindowManager());//WMS服务,这个也很重要 ServiceManager.addService(Context.WINDOW_SERVICE, wm, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PROTO); ServiceManager.addService(Context.INPUT_SERVICE, inputManager, /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); mActivityManagerService.setWindowManager(wm); startHidlServices();//启动HIDL服务mSystemServiceManager.startService(VrManagerService.class);//启动vr服务inputManager.setWindowManagerCallbacks(wm.getInputMonitor());//启动inputManager inputManager.start();mDisplayManagerService.windowManagerAndInputReady();//SystemServer启动的480阶段mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);//SystemServer启动的500阶段mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);//SystemServer启动的520阶段mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY);mActivityManagerService.systemReady(() -> {mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); try { startSystemUi(context, windowManagerF); } catch (Throwable e) { reportWtf("starting System UI", e); }} mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);}
在这一阶段启动的服务太多了,就不一一列举出来,在该阶段的最后调用AMS.systemReady()启动默认Lancher进而完成了整个的开机流程。到此, System_server主线程的启动工作总算完成, 进入Looper.loop()状态,等待其他线程通过handler发送消息到主线再处理.。最后附上该阶段启动的相关服务常见列表!
其它服务 | 功能 |
---|---|
CameraServiceProxy | 顾名思义摄像相关服务 |
AlarmManagerService | 定时器管理服务 |
InputManagerservice | 输入事件管理服务 |
WindowManagerService | WMS窗口管理服务 |
VrManagerService | VR管理服务 |
BluetoothService | 蓝牙管理服务 |
NotificationManagerService | 通知栏管理服务 |
DeviceStorageMonitorService | 存储管理相关服务 |
LocationManagerService | 定位管理服务 |
AudioService | 音频相关管理服务 |
LockSettingsService | 屏幕锁定服务,管理每个用户的相关锁屏信息 |
DeviceIdleController | Doze模式的主要驱动,参考“深入Android ‘M’ Doze” |
DevicePolicyManagerService | 提供一些系统级别的设置及属性 |
StatusBarManagerService | 状态栏管理服务 |
ClipboardService | 系统剪切板服务 |
NetworkManagementService | 网络管理服务 |
TextServicesManagerService | 文本服务,例如文本检查等 |
NetworkScoreService | 网络评分服务 |
NetworkStatsService | 网络状态服务 |
NetworkPolicyManagerService | 网络策略服务 |
WifiP2pService | Wifi Direct服务 |
WifiService | Wifi服务 |
WifiScanningService | Wifi扫描服务 |
RttService | Wifi相关 |
EthernetService | 以太网服务 |
ConnectivityService | 网络连接管理服务 |
NsdService | 网络发现服务 |
NotificationManagerService | 通知栏管理服务 |
DeviceStorageMonitorService | 磁盘空间状态检测服务 |
LocationManagerService | 位置服务,GPS、定位等 |
CountryDetectorService | 检测用户国家 |
SearchManagerService | 搜索管理服务 |
DropBoxManagerService | 用于系统运行时日志的存储于管理 |
WallpaperManagerService | 壁纸管理服务 |
AudioService | AudioFlinger的上层管理封装,主要是音量、音效、声道及铃声等的管理 |
DockObserver | 如果系统有个座子,当手机装上或拔出这个座子的话,就得靠他来管理了 |
WiredAccessoryManager | 监视手机和底座上的耳机 |
UsbService | USB服务 |
SerialService | 串口服务 |
TwilightService | 指出用户当前所在位置是否为晚上,被UiModeManager等用来调整夜间模式。 |
BackupManagerService | 备份服务 |
AppWidgetService | 提供Widget的管理和相关服务 |
VoiceInteractionManagerService | 语音交互管理服务 |
DiskStatsService | 磁盘统计服务,供dumpsys使用 |
SamplingProfilerService | 用于耗时统计等 |
NetworkTimeUpdateService | 监视网络时间,当网络时间变化时更新本地时间。 |
CommonTimeManagementService | 管理本地常见的时间服务的配置,在网络配置变化时重新配置本地服务。 |
CertBlacklister | 提供一种机制更新SSL certificate blacklist |
DreamManagerService | 屏幕保护 |
AssetAtlasService | 负责将预加载的bitmap组装成纹理贴图,生成的纹理贴图可以被用来跨进程使用,以减少内存。 |
PrintManagerService | 打印服务 |
HdmiControlService | HDMI控制服务 |
FingerprintService | 指纹服务 |
二. SystemServer服务启动阶段概括
通过前面的章节我们发现在SystemServer启动服务的三个阶段过程中,SystemServiceManager的startBootPhase()贯穿system_server进程以及服务的整个启动过程,基本示意图如下所示:
其中最后的PHASE_BOOT_COMPLETED=1000,该阶段是发生在Boot完成和home应用启动完毕,从而完成了真正意义上的Android终端开机启动流程。系统服务更倾向于监听该阶段,而不是注册广播ACTION_BOOT_COMPLETED,从而降低系统延迟。
其中各个启动阶段在system_server进程启动中的源码位置如下所示:
public final class SystemServer { private void startBootstrapServices() { ... //phase100 mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY); ... }//重点注意,在该阶段是没有设置启动阶段标志的相关设置 private void startCoreServices() { ... } private void startOtherServices() { ... //phase480 && 500 mSystemServiceManager.startBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); mSystemServiceManager.startBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); //520 mSystemServiceManager.startBootPhase(SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY); ...mActivityManagerService.systemReady(() -> {......//550mSystemServiceManager.startBootPhase(SystemService.PHASE_ACTIVITY_MANAGER_READY);//600 mSystemServiceManager.startBootPhase(SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);......}, BOOT_TIMINGS_TRACE_LOG);}public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... final void finishBooting() { ...... // Let system services know.10000 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); ...... } ......}
如上就是Systemserver启动服务的各个阶段相关标志的设置,那么下面我们简单分析分析各个阶段主要完成的相关工作。
2.1 PHASE_START(0)
在源码中是没有这个阶阶段的,这个是我们让更好的理解,本人强行加上去的,可以理解为system_server进程启动之后并启动SystemSever的开始阶段,在这一阶段主要创建了如下几个引导服务:
- installer服务,主要是提供给其它服务使用
- ActivityManagerService
- PowerManagerService
- RecoverySystemService
- DisplayManagerService
2.2 PHASE_WAIT_FOR_DEFAULT_DISPLAY(100)
进入该阶段后,将会回调2.1阶段创建的相关服务的onBootPhase(100)方法,然后继续创建下列相关的服务:
- PackageManagerService
- UserManagerService
- OverlayManagerService
- BatteryService
- UsageStatsService
- InputManagerService
- WindowManagerService
- NetworkWatchlistService
2.3 PHASE_LOCK_SETTINGS_READY(480)
进入该阶段后会回调前面阶段创建服务的onBootPhase(480)方法,该阶段非常短调用完上述方法后会直接进入PHASE_SYSTEM_SERVICES_READY(500)阶段。
2.4 PHASE_SYSTEM_SERVICES_READY(500)
进入该阶段后会回调前面阶段创建服务的onBootPhase(500)方法,并依次执行如下服务的systemReady方法:
- WindowManagerService.systemReady():
- PowerManagerService.systemReady():
- PackageManagerService.systemReady():
- DisplayManagerService.systemReady():
接下来就绪AMS.systemReady方法,这个方法非常重要!
2.5 PHASE_ACTIVITY_MANAGER_READY(550)
该阶段中将设置AMS的mSystemReady为true表明AMS已准备就绪,进入该阶段服务能广播Intent;但是system_server主线程并没有就绪,然后继续会调用前面创建服务的onBootPhase(550)方法!接下来执行: (AMS启动native crash监控, 加载WebView,启动SystemUi等),如下:
-
mActivityManagerService.startObservingNativeCrashes()
-
mWebViewUpdateService.prepareWebViewInSystemServer
-
startSystemUi(context)
-
networkManagementF.systemReady
-
pSecServiceF.systemReady
-
networkStatsF.systemRead
-
connectivityF.systemReady
-
networkPolicyF.systemReady
-
Watchdog.getInstance().start()
2.6 PHASE_THIRD_PARTY_APPS_CAN_START(600)
该阶段依次会调用前面阶段创建服务的onBootPhase(600),接着调用如下服务的systemRunning方法:
- locationF.systemRunning
- countryDetectorF.systemRunning
- networkTimeUpdaterF.systemRunning
- commonTimeMgmtServiceF.systemRunning
- inputManagerF.systemRunning
- telephonyRegistryF.systemRunning
- mediaRouterF.systemRunning
- mmsServiceF.systemRunning
- incident.systemRunning
2.7 PHASE_BOOT_COMPLETED(1000)
在经过如上一系列流程,最终调用AMS.finishBooting()时,则进入阶段PHASE_BOOT_COMPLETED(1000)。
到此,系统服务启动阶段完成就绪,system_server进程启动完成则进入Looper.loop()状态,随时待命,等待消息队列MessageQueue中的消息到来,则马上进入执行状态。
结语
经过层层的拨山涉水,我们终于system_server进程的启动以及其启动过程中的丰功伟绩介绍完成了,到这里大伙应该明白了为啥system_server进程可以做到和zygote进程生死与共了,这个哥们是有实力的人不是靠吹牛皮来的。
写在最后
system_server进程启动篇章终于告一段落了,在后续篇章中我们将要讲述zygote进程怎么否孵化普通App进程的,这个也是后续篇章的重点。好了,如果今天的文章对大伙有帮助,希望能点个赞,求个关注!各位江湖见!
更多相关文章
- Android系统架构概况
- Android核心分析(14)------ Android GWES之输入系统
- [Android] 图片裁剪总结——调用系统裁剪
- Android绘制优化----系统显示原理
- Android系统启动过程分析