入口ActivityManagerService.systemReady()
public void systemReady(final Runnable goingCallback, @NonNull TimingsTraceAndSlog t) {
...
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();
}
t.traceEnd(); // PhaseActivityManagerReady
return;
}
...
}
try {
...
t.traceBegin("killProcesses");
//杀掉非persist进程(由Zygot fork出进程,然后调用ActivityThread.main() ,创建ActivityThread对象,调用attach(false), 创建Context,LoadedAPK,Application,调用Application.onCreate())
ArrayList<ProcessRecord> 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<ProcessRecord>();
}
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,
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_SYSTEM_UPDATE_DONE,
"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;
}
t.traceEnd(); // KillProcesses
Slog.i(TAG, "System now ready");
...
t.traceBegin("registerActivityLaunchObserver");
mAtmInternal.getLaunchObserverRegistry().registerLaunchObserver(mActivityLaunchObserver);
t.traceEnd();
...
t.traceBegin("retrieveSettings");
retrieveSettings();
t.traceEnd();
....
//调用传递的Runnable.run(),在这里StartSystemUI
if (goingCallback != null) goingCallback.run();
...
synchronized (this) {
// Only start up encryption-aware persistent apps; once user is
// unlocked we'll come back around and start unaware apps
t.traceBegin("startPersistentApps");
//启动Persistent APP
startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
t.traceEnd();
// Start up initial activity.
mBooting = true;
// Enable home activity for system user, so that the system can always boot. We don't
// do this when the system user is not setup since the setup wizard should be the one
// to handle home activity in this case.
if (UserManager.isSplitSystemUser() &&
Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0) != 0
|| SystemProperties.getBoolean(SYSTEM_USER_HOME_NEEDED, false)) {
t.traceBegin("enableHomeActivity");
ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
try {
AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
t.traceEnd();
}
if (bootingSystemUser) {
//启动桌面
t.traceBegin("startHomeOnAllDisplays");
mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady");
t.traceEnd();
}
....
t.traceBegin("resumeTopActivities");
mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
t.traceEnd();
}
}
启动桌面入口mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); 实际调用ATMS.startHomeOnAllDisplays(currentUserId, "systemReady");
public boolean startHomeOnAllDisplays(int userId, String reason) {
synchronized (mGlobalLock) {
return mRootWindowContainer.startHomeOnAllDisplays(userId, reason);
}
}
RootWindowContainer.startHomeOnAllDisplays(userId, reason)
boolean startHomeOnAllDisplays(int userId, String reason) {
boolean homeStarted = false;
for (int i = getChildCount() - 1; i >= 0; i--) {
final int displayId = getChildAt(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 or default display if the displayId is invalid.
if (displayId == INVALID_DISPLAY) {
final Task rootTask = getTopDisplayFocusedRootTask();
displayId = rootTask != null ? rootTask.getDisplayId() : DEFAULT_DISPLAY;
}
final DisplayContent display = getDisplayContent(displayId);
return display.reduceOnAllTaskDisplayAreas((taskDisplayArea, result) ->
result | startHomeOnTaskDisplayArea(userId, reason, taskDisplayArea,
allowInstrumenting, fromHomeKey),
false /* initValue */);
}
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
boolean allowInstrumenting, boolean fromHomeKey) {
// Fallback to top focused display area if the provided one is invalid.
if (taskDisplayArea == null) {
final Task rootTask = getTopDisplayFocusedRootTask();
taskDisplayArea = rootTask != null ? rootTask.getDisplayArea()
: getDefaultTaskDisplayArea();
}
Intent homeIntent = null;
ActivityInfo aInfo = null;
if (taskDisplayArea == getDefaultTaskDisplayArea()) {
// mService = ActivityTaskManagerService
homeIntent = mService.getHomeIntent();
aInfo = resolveHomeActivity(userId, homeIntent);
} else if (shouldPlaceSecondaryHomeOnDisplayArea(taskDisplayArea)) {
Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, taskDisplayArea);
aInfo = info.first;
homeIntent = info.second;
}
if (aInfo == null || homeIntent == null) {
return false;
}
if (!canStartHomeOnDisplayArea(aInfo, taskDisplayArea, 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);
if (mWindowManager.getRecentsAnimationController() != null) {
mWindowManager.getRecentsAnimationController().cancelAnimationForHomeStart();
}
}
homeIntent.putExtra(WindowManagerPolicy.EXTRA_START_REASON, reason);
....
mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
taskDisplayArea);
return true;
}
调用ActivityTaskManagerService.getHomeIntent()
Intent getHomeIntent() {
Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
intent.setComponent(mTopComponent);
intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
//设置桌面的Category为Intent.CATEGORY_HOME,识别桌面唯一表示
intent.addCategory(Intent.CATEGORY_HOME);
}
return intent;
}
ActivityStartController.startHomeActivity
void startHomeActivity(Intent intent, ActivityInfo aInfo, String reason,
TaskDisplayArea taskDisplayArea) {
final ActivityOptions options = ActivityOptions.makeBasic();
options.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
if (!ActivityRecord.isResolverActivity(aInfo.name)) {
// The resolver activity shouldn't be put in root home task because when the
// foreground is standard type activity, the resolver activity should be put on the
// top of current foreground instead of bring root home task to front.
options.setLaunchActivityType(ACTIVITY_TYPE_HOME);
}
final int displayId = taskDisplayArea.getDisplayId();
options.setLaunchDisplayId(displayId);
options.setLaunchTaskDisplayArea(taskDisplayArea.mRemoteToken
.toWindowContainerToken());
// The home activity will be started later, defer resuming to avoid unnecessary operations
// (e.g. start home recursively) when creating root home task.
mSupervisor.beginDeferResume();
final Task rootHomeTask;
try {
// Make sure root home task exists on display area.
rootHomeTask = taskDisplayArea.getOrCreateRootHomeTask(ON_TOP);
} finally {
mSupervisor.endDeferResume();
}
mLastHomeActivityStartResult = obtainStarter(intent, "startHomeActivity: " + reason)
.setOutActivity(tmpOutRecord)
.setCallingUid(0)
.setActivityInfo(aInfo)
.setActivityOptions(options.toBundle())
.execute();
mLastHomeActivityStartRecord = tmpOutRecord[0];
if (rootHomeTask.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();
}
}
ActivityStarter.execute()
int execute() {
try {
// Refuse possible leaked file descriptors
if (mRequest.intent != null && mRequest.intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
final LaunchingState launchingState;
synchronized (mService.mGlobalLock) {
final ActivityRecord caller = ActivityRecord.forTokenLocked(mRequest.resultTo);
final int callingUid = mRequest.realCallingUid == Request.DEFAULT_REAL_CALLING_UID
? Binder.getCallingUid() : mRequest.realCallingUid;
launchingState = mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(
mRequest.intent, caller, callingUid);
}
// If the caller hasn't already resolved the activity, we're willing
// to do so here. If the caller is already holding the WM lock here,
// and we need to check dynamic Uri permissions, then we're forced
// to assume those permissions are denied to avoid deadlocking.
if (mRequest.activityInfo == null) {
mRequest.resolveActivity(mSupervisor);
}
// Add checkpoint for this shutdown or reboot attempt, so we can record the original
// intent action and package name.
if (mRequest.intent != null) {
String intentAction = mRequest.intent.getAction();
String callingPackage = mRequest.callingPackage;
if (intentAction != null && callingPackage != null
&& (Intent.ACTION_REQUEST_SHUTDOWN.equals(intentAction)
|| Intent.ACTION_SHUTDOWN.equals(intentAction)
|| Intent.ACTION_REBOOT.equals(intentAction))) {
ShutdownCheckPoints.recordCheckPoint(intentAction, callingPackage, null);
}
}
int res;
synchronized (mService.mGlobalLock) {
final boolean globalConfigWillChange = mRequest.globalConfig != null
&& mService.getGlobalConfiguration().diff(mRequest.globalConfig) != 0;
final Task rootTask = mRootWindowContainer.getTopDisplayFocusedRootTask();
if (rootTask != null) {
rootTask.mConfigWillChange = globalConfigWillChange;
}
ProtoLog.v(WM_DEBUG_CONFIGURATION, "Starting activity when config "
+ "will change = %b", globalConfigWillChange);
final long origId = Binder.clearCallingIdentity();
res = resolveToHeavyWeightSwitcherIfNeeded();
if (res != START_SUCCESS) {
return res;
}
res = executeRequest(mRequest);
Binder.restoreCallingIdentity(origId);
if (globalConfigWillChange) {
// If the caller also wants to switch to a new configuration, do so now.
// This allows a clean switch, as we are waiting for the current activity
// to pause (so we will not destroy it), and have not yet started the
// next activity.
mService.mAmInternal.enforceCallingPermission(
android.Manifest.permission.CHANGE_CONFIGURATION,
"updateConfiguration()");
if (rootTask != null) {
rootTask.mConfigWillChange = false;
}
ProtoLog.v(WM_DEBUG_CONFIGURATION,
"Updating to new configuration after starting activity.");
mService.updateConfigurationLocked(mRequest.globalConfig, null, false);
}
// The original options may have additional info about metrics. The mOptions is not
// used here because it may be cleared in setTargetRootTaskIfNeeded.
final ActivityOptions originalOptions = mRequest.activityOptions != null
? mRequest.activityOptions.getOriginalOptions() : null;
// If the new record is the one that started, a new activity has created.
final boolean newActivityCreated = mStartActivity == mLastStartActivityRecord;
// Notify ActivityMetricsLogger that the activity has launched.
// ActivityMetricsLogger will then wait for the windows to be drawn and populate
// WaitResult.
mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(launchingState, res,
newActivityCreated, mLastStartActivityRecord, originalOptions);
if (mRequest.waitResult != null) {
mRequest.waitResult.result = res;
res = waitResultIfNeeded(mRequest.waitResult, mLastStartActivityRecord,
launchingState);
}
return getExternalResult(res);
}
} finally {
onExecutionComplete();
}
}