一 前言

Android 系统服务进程 system_server,进入消息循环前的最后一步,就是调用 AMS 的 systemReady() 方法。今天我们分析一下这里的流程。

二 systemReady 第一部分

ActivityManagerService.java

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {

synchronized(this) {

if (mSystemReady) {

// If we're done calling all the receivers, run the next "boot phase" passed in

// by the SystemServer

if (goingCallback != null) {

goingCallback.run();

}

return;

}

mLocalDeviceIdleController

= LocalServices.getService(DeviceIdleController.LocalService.class);

mActivityTaskManager.onSystemReady();

// Make sure we have the current profile info, since it is needed for security checks.

mUserController.onSystemReady();

mAppOpsService.systemReady();

mSystemReady = true;

}

......

}

这里 mSystemReady 是 false,所以回调方法不会在这里被执行。接下来会调用一些关联类的 systemReady() 方法,然后把标志位 mSystemReady 置为 true。

ArrayList procsToKill = null;

synchronized(mPidsSelfLocked) {

for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {

ProcessRecord proc = mPidsSelfLocked.valueAt(i);

if (!isAllowedWhileBooting(proc.info)){

if (procsToKill == null) {

procsToKill = new ArrayList();

}

procsToKill.add(proc);

}

}

}

synchronized(this) {

if (procsToKill != null) {

for (int i=procsToKill.size()-1; i>=0; i--) {

ProcessRecord proc = procsToKill.get(i);

Slog.i(TAG, "Removing system update proc: " + proc);

mProcessList.removeProcessLocked(proc, true, false, "system update done");

}

}

// Now that we have cleaned up any update processes, we

// are ready to start launching real processes and know that

// we won't trample on them any more.

mProcessesReady = true;

}

清理进程,把不允许在开机阶段运行的进程都结束掉。判断标准是:应用程序的 AM 配置文件是否有配置 android:persistent 属性。

mAtmInternal.updateTopComponentForFactoryTest();

工厂测试相关的逻辑,正常情况下这个条件不成立,所以不管它。

if (goingCallback != null) goingCallback.run();

执行 systemReady() 传入的回调方法,在 SystemServer.java 类中

三 systemReady 第二部分之回调方法

SystemServer.java 这个回调方法很长,足有 200 行,我们单独作为一节来分析。

traceBeginAndSlog("StartActivityManagerReadyPhase");

mSystemServiceManager.startBootPhase(

SystemService.PHASE_ACTIVITY_MANAGER_READY);

traceEnd();

AMS 启动完成,系统进入阶段 PHASE_ACTIVITY_MANAGER_READY,对其它服务调用 onBootPhase() 方法传出这个PHASE。

traceBeginAndSlog("StartObservingNativeCrashes");

try {

mActivityManagerService.startObservingNativeCrashes();

} catch (Throwable e) {

reportWtf("observing native crashes", e);

}

traceEnd();

启动 native crash监测。

// No dependency on Webview preparation in system server. But this should

// be completed before allowing 3rd party

final String WEBVIEW_PREPARATION = "WebViewFactoryPreparation";

Future webviewPrep = null;

if (!mOnlyCore && mWebViewUpdateService != null) {

webviewPrep = SystemServerInitThreadPool.get().submit(() -> {

Slog.i(TAG, WEBVIEW_PREPARATION);

TimingsTraceLog traceLog = new TimingsTraceLog(

SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);

traceLog.traceBegin(WEBVIEW_PREPARATION);

ConcurrentUtils.waitForFutureNoInterrupt(mZygotePreload, "Zygote preload");

mZygotePreload = null;

mWebViewUpdateService.prepareWebViewInSystemServer();

traceLog.traceEnd();

}, WEBVIEW_PREPARATION);

}

这里判断要不要启动 webview。

traceBeginAndSlog("StartSystemUI");

try {

startSystemUi(context, windowManagerF);

} catch (Throwable e) {

reportWtf("starting System UI", e);

}

traceEnd();

启动 SystemUI。

if (safeMode) {

traceBeginAndSlog("EnableAirplaneModeInSafeMode");

try {

connectivityF.setAirplaneMode(true);

} catch (Throwable e) {

reportWtf("enabling Airplane Mode during Safe Mode bootup", e);

}

traceEnd();

}

traceBeginAndSlog("MakeNetworkManagementServiceReady");

try {

if (networkManagementF != null) {

networkManagementF.systemReady();

}

} catch (Throwable e) {

reportWtf("making Network Managment Service ready", e);

}

CountDownLatch networkPolicyInitReadySignal = null;

if (networkPolicyF != null) {

networkPolicyInitReadySignal = networkPolicyF

.networkScoreAndNetworkManagementServiceReady();

}

traceEnd();

traceBeginAndSlog("MakeIpSecServiceReady");

try {

if (ipSecServiceF != null) {

ipSecServiceF.systemReady();

}

} catch (Throwable e) {

reportWtf("making IpSec Service ready", e);

}

traceEnd();

traceBeginAndSlog("MakeNetworkStatsServiceReady");

try {

if (networkStatsF != null) {

networkStatsF.systemReady();

}

} catch (Throwable e) {

reportWtf("making Network Stats Service ready", e);

}

traceEnd();

traceBeginAndSlog("MakeConnectivityServiceReady");

try {

if (connectivityF != null) {

connectivityF.systemReady();

}

} catch (Throwable e) {

reportWtf("making Connectivity Service ready", e);

}

traceEnd();

traceBeginAndSlog("MakeNetworkPolicyServiceReady");

try {

if (networkPolicyF != null) {

networkPolicyF.systemReady(networkPolicyInitReadySignal);

}

} catch (Throwable e) {

reportWtf("making Network Policy Service ready", e);

}

traceEnd();

调用一堆网络相关服务的 systemReady() 方法。

// It is now okay to let the various system services start their

// third party code...

traceBeginAndSlog("PhaseThirdPartyAppsCanStart");

// confirm webview completion before starting 3rd party

if (webviewPrep != null) {

ConcurrentUtils.waitForFutureNoInterrupt(webviewPrep, WEBVIEW_PREPARATION);

}

mSystemServiceManager.startBootPhase(

SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);

traceEnd();

系统进入阶段 PHASE_THIRD_PARTY_APPS_CAN_START。对其它服务调用 onBootPhase() 方法传出这个 PHASE。

traceBeginAndSlog("MakeLocationServiceReady");

try {

if (locationF != null) {

locationF.systemRunning();

}

} catch (Throwable e) {

reportWtf("Notifying Location Service running", e);

}

traceEnd();

traceBeginAndSlog("MakeCountryDetectionServiceReady");

try {

if (countryDetectorF != null) {

countryDetectorF.systemRunning();

}

} catch (Throwable e) {

reportWtf("Notifying CountryDetectorService running", e);

}

traceEnd();

traceBeginAndSlog("MakeNetworkTimeUpdateReady");

try {

if (networkTimeUpdaterF != null) {

networkTimeUpdaterF.systemRunning();

}

} catch (Throwable e) {

reportWtf("Notifying NetworkTimeService running", e);

}

traceEnd();

traceBeginAndSlog("MakeInputManagerServiceReady");

try {

// TODO(BT) Pass parameter to input manager

if (inputManagerF != null) {

inputManagerF.systemRunning();

}

} catch (Throwable e) {

reportWtf("Notifying InputManagerService running", e);

}

traceEnd();

traceBeginAndSlog("MakeTelephonyRegistryReady");

try {

if (telephonyRegistryF != null) {

telephonyRegistryF.systemRunning();

}

} catch (Throwable e) {

reportWtf("Notifying TelephonyRegistry running", e);

}

traceEnd();

traceBeginAndSlog("MakeMediaRouterServiceReady");

try {

if (mediaRouterF != null) {

mediaRouterF.systemRunning();

}

} catch (Throwable e) {

reportWtf("Notifying MediaRouterService running", e);

}

traceEnd();

traceBeginAndSlog("MakeMmsServiceReady");

try {

if (mmsServiceF != null) {

mmsServiceF.systemRunning();

}

} catch (Throwable e) {

reportWtf("Notifying MmsService running", e);

}

traceEnd();

对其他相关服务调用 systemRunning() 方法。包括:位置、国家检测、网络时间、输入管理、网络评分等等。 至此回调方法分析结束。

四 systemReady第三部分

继续回到 AMS 的 systemReady() 方法。

// Only start up encryption-aware persistent apps; once user is

// unlocked we'll come back around and start unaware apps

startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);

启动锁屏状态下的应用,通过应用配置文件的 android:directBoot 属性过滤。

if (bootingSystemUser) {

mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");

}

启动 Home 程序。这个在下一节分析。

mAtmInternal.showSystemReadyErrorDialogsIfNeeded();

public void showSystemReadyErrorDialogsIfNeeded() {

synchronized (mGlobalLock) {

try {

if (AppGlobals.getPackageManager().hasSystemUidErrors()) {

Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"

+ " data partition or your device will be unstable.");

mUiHandler.post(() -> {

if (mShowDialogs) {

AlertDialog d = new BaseErrorDialog(mUiContext);

d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);

d.setCancelable(false);

d.setTitle(mUiContext.getText(R.string.android_system_label));

d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));

d.setButton(DialogInterface.BUTTON_POSITIVE,

mUiContext.getText(R.string.ok),

mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));

d.show();

}

});

}

} catch (RemoteException e) {

}

if (!Build.isBuildConsistent()) {

Slog.e(TAG, "Build fingerprint is not consistent, warning user");

mUiHandler.post(() -> {

if (mShowDialogs) {

AlertDialog d = new BaseErrorDialog(mUiContext);

d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);

d.setCancelable(false);

d.setTitle(mUiContext.getText(R.string.android_system_label));

d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));

d.setButton(DialogInterface.BUTTON_POSITIVE,

mUiContext.getText(R.string.ok),

mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));

d.show();

}

});

}

}

}

检查 uid 和 fingerprint,如果有异常会弹出 Android System 的弹框。

if (bootingSystemUser) {

final int callingUid = Binder.getCallingUid();

final int callingPid = Binder.getCallingPid();

long ident = Binder.clearCallingIdentity();

try {

Intent intent = new Intent(Intent.ACTION_USER_STARTED);

intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY

| Intent.FLAG_RECEIVER_FOREGROUND);

intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);

broadcastIntentLocked(null, null, intent,

null, null, 0, null, null, null, OP_NONE,

null, false, false, MY_PID, SYSTEM_UID, callingUid, callingPid,

currentUserId);

intent = new Intent(Intent.ACTION_USER_STARTING);

intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);

intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);

broadcastIntentLocked(null, null, intent,

null, new IIntentReceiver.Stub() {

@Override

public void performReceive(Intent intent, int resultCode, String data,

Bundle extras, boolean ordered, boolean sticky, int sendingUser)

throws RemoteException {

}

}, 0, null, null,

new String[] {INTERACT_ACROSS_USERS}, OP_NONE,

null, true, false, MY_PID, SYSTEM_UID, callingUid, callingPid,

UserHandle.USER_ALL);

} catch (Throwable t) {

Slog.wtf(TAG, "Failed sending first user broadcasts", t);

} finally {

Binder.restoreCallingIdentity(ident);

}

} else {

Slog.i(TAG, "Not sending multi-user broadcasts for non-system user "

+ currentUserId);

}

发送两个广播:ACTION_USER_STARTED、ACTION_USER_STARTING。

4.1 Home 启动

@Override

public boolean startHomeOnAllDisplays(int userId, String reason) {

synchronized (mGlobalLock) {

return mRootActivityContainer.startHomeOnAllDisplays(userId, reason);

}

}

RootActivityContainer.java

boolean startHomeOnAllDisplays(int userId, String reason) {

boolean homeStarted = false;

for (int i = mActivityDisplays.size() - 1; i >= 0; i--) {

final int displayId = mActivityDisplays.get(i).mDisplayId;

homeStarted |= startHomeOnDisplay(userId, reason, displayId);

}

return homeStarted;

}

boolean startHomeOnDisplay(int userId, String reason, int displayId) {

return startHomeOnDisplay(userId, reason, displayId, false /* allowInstrumenting */,

false /* fromHomeKey */);

}

boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting,

boolean fromHomeKey) {

// Fallback to top focused display if the displayId is invalid.

if (displayId == INVALID_DISPLAY) {

displayId = getTopDisplayFocusedStack().mDisplayId;

}

Intent homeIntent = null;

ActivityInfo aInfo = null;

if (displayId == DEFAULT_DISPLAY) {

homeIntent = mService.getHomeIntent();

aInfo = resolveHomeActivity(userId, homeIntent);

} else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) {

Pair info = resolveSecondaryHomeActivity(userId, displayId);

aInfo = info.first;

homeIntent = info.second;

}

if (aInfo == null || homeIntent == null) {

return false;

}

if (!canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) {

return false;

}

// Updates the home component of the intent.

homeIntent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));

homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK);

// Updates the extra information of the intent.

if (fromHomeKey) {

homeIntent.putExtra(WindowManagerPolicy.EXTRA_FROM_HOME_KEY, true);

}

// Update the reason for ANR debugging to verify if the user activity is the one that

// actually launched.

final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId(

aInfo.applicationInfo.uid) + ":" + displayId;

mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,

displayId);

return true;

}

ActivityStartController.java

void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason, int displayId) {

final ActivityOptions options = ActivityOptions.makeBasic();

options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);

if (!ActivityRecord.isResolverActivity(aInfo.name)) {

// The resolver activity shouldn't be put in home stack because when the foreground is

// standard type activity, the resolver activity should be put on the top of current

// foreground instead of bring home stack to front.

options.setLaunchActivityType(ACTIVITY_TYPE_HOME);

}

options.setLaunchDisplayId(displayId);

mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)

.setOutActivity(tmpOutRecord)

.setCallingUid(0)

.setActivityInfo(aInfo)

.setActivityOptions(options.toBundle())

.execute(); // 根据 Intent,启动 Home 的主 Activity

mLastHomeActivityStartRecord = tmpOutRecord[0];

final ActivityDisplay display =

mService.mRootActivityContainer.getActivityDisplay(displayId);

final ActivityStack homeStack = display != null ? display.getHomeStack() : null;

if (homeStack != null && homeStack.mInResumeTopActivity) {

// If we are in resume section already, home activity will be initialized, but not

// resumed (to avoid recursive resume) and will stay that way until something pokes it

// again. We need to schedule another resume.

mSupervisor.scheduleResumeTopActivities();

}

}

根据 Intent,启动 Home 的主 Activity。

好文阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: