一、系统启动与服务初始化全链路
1. Zygote进程到SystemServer的跃迁
frameworks/base/cmds/app_process/app_main.cpp
`// app_main.cpp (Zygote进程)
int main(int argc, char** argv) {
// 创建Binder线程池
sp<ProcessState> proc(ProcessState::self());
// 启动SystemServer进程
if (startSystemServer) {
pid_t pid = fork();
if (pid == 0) {
// 设置实时优先级(关键参数)
setpriority(PRIO_PROCESS, 0, -20);
// 跳转到SystemServer主函数
SystemMain();
}
}
}`
值得注意的是:
Binder线程池初始化:ProcessState::self()->startThreadPool()创建Binder线程池
如上代码将流程直接推到了ZygoInit.java
//frameworks/base/core/java/com/android/internal/os/ZygoteInit.java
` /**
* Performs Zygote process initialization. Loads and initializes commonly used classes.
*
* Most classes only cause a few hundred bytes to be allocated, but a few will allocate a dozen
* Kbytes (in one case, 500+K).
*/
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;
}
Log.i(TAG, "Preloading classes...");
long startTime = SystemClock.uptimeMillis();
// Drop root perms while running static initializers.
final int reuid = Os.getuid();
final int regid = Os.getgid();
// We need to drop root perms only if we're already root. In the case of "wrapped"
// processes (see WrapperInit), this function is called from an unprivileged uid
// and gid.
boolean droppedPriviliges = false;
if (reuid == ROOT_UID && regid == ROOT_GID) {
try {
Os.setregid(ROOT_GID, UNPRIVILEGED_GID);
Os.setreuid(ROOT_UID, UNPRIVILEGED_UID);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to drop root", ex);
}
droppedPriviliges = true;
}
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();
if (line.startsWith("#") || line.equals("")) {
continue;
}
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, line);
try {
// Load and explicitly initialize the given class. Use
// Class.forName(String, boolean, ClassLoader) to avoid repeated stack lookups
// (to derive the caller's class-loader). Use true to force initialization, and
// null for the boot classpath class-loader (could as well cache the
// class-loader of this class in a variable).
Class.forName(line, true, null);
count++;
} catch (ClassNotFoundException e) {
if (line.contains("$$Lambda$")) {
if (LOGGING_DEBUG) {
missingLambdaCount++;
}
} else {
Log.w(TAG, "Class not found for preloading: " + line);
}
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Problem preloading " + line + ": " + e);
} catch (Throwable t) {
Log.e(TAG, "Error preloading " + line + ".", t);
if (t instanceof Error) {
throw (Error) t;
} else if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new RuntimeException(t);
}
}
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
}
Log.i(TAG, "...preloaded " + count + " classes in "
+ (SystemClock.uptimeMillis() - startTime) + "ms.");
if (LOGGING_DEBUG && missingLambdaCount != 0) {
Log.i(TAG, "Unresolved lambda preloads: " + missingLambdaCount);
}
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
IoUtils.closeQuietly(is);
// Fill in dex caches with classes, fields, and methods brought in by preloading.
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "PreloadDexCaches");
runtime.preloadDexCaches();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
// If we are profiling the boot image, reset the Jit counters after preloading the
// classes. We want to preload for performance, and we can use method counters to
// infer what clases are used after calling resetJitCounters, for profile purposes.
if (shouldProfileBootClasspath()) {
Trace.traceBegin(Trace.TRACE_TAG_DALVIK, "ResetJitCounters");
VMRuntime.resetJitCounters();
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
}
// Bring back root. We'll need it later if we're in the zygote.
if (droppedPriviliges) {
try {
Os.setreuid(ROOT_UID, ROOT_UID);
Os.setregid(ROOT_GID, ROOT_GID);
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to restore root", ex);
}
}
}
}`
2. SystemServer服务启动时序
进入SystemServer之后,执行run方法
private void run() {
TimingsTraceAndSlog t = new TimingsTraceAndSlog();
try {
t.traceBegin("InitBeforeStartServices");
// Record the process start information in sys props.
SystemProperties.set(SYSPROP_START_COUNT, String.valueOf(mStartCount));
SystemProperties.set(SYSPROP_START_ELAPSED, String.valueOf(mRuntimeStartElapsedTime));
SystemProperties.set(SYSPROP_START_UPTIME, String.valueOf(mRuntimeStartUptime));
EventLog.writeEvent(EventLogTags.SYSTEM_SERVER_START,
mStartCount, mRuntimeStartUptime, mRuntimeStartElapsedTime);
// Set the device's time zone (a system property) if it is not set or is invalid.
SystemTimeZone.initializeTimeZoneSettingsIfRequired();
// 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.forceSafeLabels();
// 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!");
final long uptimeMillis = SystemClock.elapsedRealtime();
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, uptimeMillis);
if (!mRuntimeRestart) {
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
FrameworkStatsLog
.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_INIT_START,
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'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
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// Mmmmmm... more memory!
VMRuntime.getRuntime().clearGrowthLimit();
// 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);
// Ensure binder calls into the system always run at foreground priority.
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.prepareMainLooper();
Looper.getMainLooper().setSlowLogThresholdMs(
SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);
SystemServiceRegistry.sEnableServiceNotFoundWtf = true;
// Initialize native services.
System.loadLibrary("android_servers");
// Allow heap / perf profiling.
initZygoteChildHeapProfiling();
// Debug builds - spawn a thread to monitor for fd leaks.
if (Build.IS_DEBUGGABLE) {
spawnFdLeakCheckThread();
}
// Check whether we failed to shut down last time we tried.
// This call may not return.
performPendingShutdown();
// Initialize the system context.
createSystemContext();
// Call per-process mainline module initialization.
ActivityThread.initializeMainlineModules();
// Sets the dumper service
ServiceManager.addService("system_server_dumper", mDumper);
mDumper.addDumpable(this);
// Create the system service manager.
mSystemServiceManager = new SystemServiceManager(mSystemContext);
mSystemServiceManager.setStartInfo(mRuntimeRestart,
mRuntimeStartElapsedTime, mRuntimeStartUptime);
mDumper.addDumpable(mSystemServiceManager);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
// Prepare the thread pool for init tasks that can be parallelized
SystemServerInitThreadPool tp = SystemServerInitThreadPool.start();
mDumper.addDumpable(tp);
// Lazily load the pre-installed system font map in SystemServer only if we're not doing
// the optimized font loading in the FontManagerService.
if (!com.android.text.flags.Flags.useOptimizedBoottimeFontLoading()
&& Typeface.ENABLE_LAZY_TYPEFACE_INITIALIZATION) {
Slog.i(TAG, "Loading pre-installed system font map.");
Typeface.loadPreinstalledSystemFontMap();
}
// Attach JVMTI agent if this is a debuggable build and the system property is set.
if (Build.IS_DEBUGGABLE) {
// Property is of the form "library_path=parameters".
String jvmtiAgent = SystemProperties.get("persist.sys.dalvik.jvmtiagent");
if (!jvmtiAgent.isEmpty()) {
int equalIndex = jvmtiAgent.indexOf('=');
String libraryPath = jvmtiAgent.substring(0, equalIndex);
String parameterList =
jvmtiAgent.substring(equalIndex + 1, jvmtiAgent.length());
// Attach the agent.
try {
Debug.attachJvmtiAgent(libraryPath, parameterList, null);
} catch (Exception e) {
Slog.e("System", "*************************************************");
Slog.e("System", "********** Failed to load jvmti plugin: " + jvmtiAgent);
}
}
}
} finally {
t.traceEnd(); // InitBeforeStartServices
}
// Setup the default WTF handler
RuntimeInit.setDefaultApplicationWtfHandler(SystemServer::handleEarlySystemWtf);
// Start services.
try {
t.traceBegin("StartServices");
startBootstrapServices(t);
startCoreServices(t);
startOtherServices(t);
startApexServices(t);
// Only update the timeout after starting all the services so that we use
// the default timeout to start system server.
updateWatchdogTimeout(t);
CriticalEventLog.getInstance().logSystemServerStarted();
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
t.traceEnd(); // StartServices
}
StrictMode.initVmDefaults(null);
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
final long uptimeMillis = SystemClock.elapsedRealtime();
FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED,
FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SYSTEM_SERVER_READY,
uptimeMillis);
final long maxUptimeMillis = 60 * 1000;
if (uptimeMillis > maxUptimeMillis) {
Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
"SystemServer init took too long. uptimeMillis=" + uptimeMillis);
}
}
// Set binder transaction callback after starting system services
Binder.setTransactionCallback(new IBinderCallback() {
@Override
public void onTransactionError(int pid, int code, int flags, int err) {
mActivityManagerService.frozenBinderTransactionDetected(pid, code, flags, err);
}
});
// Loop forever.
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
如上代码,可以持续优化,所有的核心服务开始在此处启动,其中包括AMS,WMS等服务,其中WMS和AMS依赖关系如下:
- WMS初始化需AMS注册窗口管理接口(
ServiceManager.addService("window", wms)) - PMS需等待Installer服务就绪(
mInstaller = mSystemServiceManager.startService(Installer.class))
接下来,进入AMS,WMS,PMS等交互全链路
二、AMS-WMS-PMS交互全链路
1. Activity启动触发窗口创建
- 调用链路:
ActivityThread.handleLaunchActivity()→ActivityManagerService.attachApplication()
ActivityThread:frameworks/base/core/java/android/app/ActivityThread.java
/**
* Extended implementation of activity launch. Used when server requests a launch or relaunch.
*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
PendingTransactionActions pendingActions, int deviceId, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
mSomeActivitiesChanged = true;
if (r.profilerInfo != null) {
mProfiler.setProfiler(r.profilerInfo);
mProfiler.startProfiling();
}
// Make sure we are running with the most recent config and resource paths.
applyPendingApplicationInfoChanges(r.activityInfo.packageName);
mConfigurationController.handleConfigurationChanged(null, null);
updateDeviceIdForNonUIContexts(deviceId);
if (localLOGV) Slog.v(
TAG, "Handling launch of " + r);
// Initialize before creating the activity
if (ThreadedRenderer.sRendererEnabled
&& (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) {
HardwareRenderer.preload();
}
WindowManagerGlobal.initialize();
// Hint the GraphicsEnvironment that an activity is launching on the process.
GraphicsEnvironment.hintActivityLaunch();
final Activity a = performLaunchActivity(r, customIntent);
if (a != null) {
r.createdConfig = new Configuration(mConfigurationController.getConfiguration());
reportSizeConfigurations(r);
if (!r.activity.mFinished && pendingActions != null) {
pendingActions.setOldState(r.state);
pendingActions.setRestoreInstanceState(true);
pendingActions.setCallOnPostCreate(true);
}
} else {
// If there was an error, for any reason, tell the activity manager to stop us.
ActivityClient.getInstance().finishActivity(r.token, Activity.RESULT_CANCELED,
null /* resultData */, Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
}
return a;
}
AMS:
2. WMS窗口绑定
WMS启动整体流程:
1.SystemServer: mWindowManagerService = WindowManagerService.main( mContext, mDisplayManager, mPackageManagerService, mPowerManagerService); ServiceManager.addService(Context.WINDOW_SERVICE, mWindowManagerService);
2.创建DisplayContent:初始化物理/虚拟屏幕的显示区域(DisplayContent.java)
3.注册窗口策略:PhoneWindowManager设置系统窗口规则(如状态栏位置)
4.绑定SurfaceFlinger:通过SurfaceComposerClient建立与图形子系统的连接
5 `// WindowManagerGlobal.java public void addView(View view, LayoutParams params) { // 1. 创建WindowState WindowState win = new WindowState(...); // 2. 调用WMS接口 mWindowManager.addView(win, params); }
// WindowManagerService.java (JNI层)
static void android_view_WindowManager_addView(JNIEnv* env, jobject clazz, jobject view, jobject attrs) {
sp<IWindowManager> wms = IWindowManager::asBinder(getService("window"));
wms->addWindow(...); // Binder调用WMS
}`
6.
`
// WindowManagerService.cpp
status_t WindowManagerService::addWindow(...) {
sp<WindowState> win = new WindowState(...);
mWindows.add(win); // 添加到窗口列表
mLayoutNeeded = true; // 触发布局更新
} `
7. `
3. 图形合成机制
```cpp
// SurfaceFlinger.cpp
void SurfaceFlinger::composeSurfaces() {
for (auto& layer : mLayers) {
if (layer->isVisible()) {
layer->latchBuffer(); // 获取GraphicBuffer
mHwc->setLayerBuffer(layer->getHandle(), buffer); // 提交给HWC
}
}
mHwc->commit(); // 提交合成指令
} `
WMS角色:通过SurfaceControl.setLayer()调整窗口Z-order,触发SurfaceFlinger重新排序
三,PMS全流程解析
1.PMS启动流程:
` // SystemServer.java
private void startBootstrapServices() {
mPackageManagerService = PackageManagerService.main(
mContext, mInstaller, mFactoryTestMode != FactoryTest.OFF, mOnlyCore);
ServiceManager.addService("package", mPackageManagerService);
}
// PackageManagerService.java
public static PackageManagerService main(...) {
PackageManagerService pms = new PackageManagerService(...);
pms.mInstaller = mSystemServiceManager.startService(Installer.class); // 依赖Installer
pms.scanPackagesLI(); // 扫描已安装应用
return pms;
} `
2. APK解析与安装
`// PackageParser.java
public Package parsePackage(File apkFile, int flags) {
// 1. 解析AndroidManifest.xml
XmlPullParser parser = Xml.resolvePullParser(manifestFile);
mPackage = new Package(...);
// 2. 提取权限声明
mPackage.mPermissions = parsePermissions(parser);
// 3. 生成应用信息
mPackage.applicationInfo = generateApplicationInfo();
}`
3.权限校验流程
` // PackageManagerService.java
int checkUidPermission(String permName, int uid) {
synchronized (mLock) {
return mSettings.getPermissionsState().checkUidPermission(permName, uid);
}
}
// 权限状态检查(PermissionsState.java)
int checkUidPermission(String permName, int uid) {
UidState uidState = mUidStates.get(uid);
return uidState != null ? uidState.checkPermission(permName) : PERMISSION_DENIED;
} `
关键数据结构:
`// PackageInfo.java
public static class Package {
String packageName; // 包名
int versionCode; // 版本号
Signature[] signatures; // 签名信息
Permission[] permissions; // 声明权限
}`
联动示例图:
联动的基础是IPC的通信,这里就必须介绍一下Binder
说到这里,关于WMS有一个很重要的组成部分(专题)