The source code based on Android11 analysis

Related source code:

/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
/frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
/packages/apps/Launcher3/src/com/android/launcher3/Launcher.java
/packages/apps/Launcher3/src/com/android/launcher3/LauncherModel.java
/packages/apps/Launcher3/src/com/android/launcher3/model/LoaderTask.java

Copy the code

Start ActivityManagerService(ActivityTaskMan) in **startBootstrapServices() and startOtherServices()** AgerService and PackageManagerService System services.

  1. ActivityManagerService: Is responsible for the creation and management of the four components.
  2. PackageManagerService: queries, installs, and uninstalls installation packages.

The desktop process Launcher starts after ActivityManagerService is started.

Start the process Launcher

ActivityManagerService. SystemReady method began the process of the Launcher

public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl. BatteryCallback {/ / mAtmInternal for ActivityTaskManagerService LocalService public class ActivityTaskManagerInternal mAtmInternal; Public void systemReady(final Runnable goingCallback, @ NonNull TimingsTraceAndSlog t) {/ / call setup process of the Launcher mAtmInternal startHomeOnAllDisplays (currentUserId "systemReady"); } } public class ActivityTaskManagerService extends IActivityTaskManager.Stub { RootWindowContainer mRootWindowContainer; final class LocalService extends ActivityTaskManagerInternal { @Override public boolean startHomeOnAllDisplays(int userId, String reason) { synchronized (mGlobalLock) { return mRootWindowContainer.startHomeOnAllDisplays(userId, reason); }}}}Copy the code
  1. Start the Launcher process in AMS’s systemReady method, but you don’t actually start the processActivityTaskManagerService.LocalServiceThe startHomeOnAllDisplays method of the class continues execution.
  2. Don’t do processing in ActivityTaskManagerService, but the callRootWindowContainer.startHomeOnAllDisplaysMethod.

RootWindowContainer. StartHomeOnAllDisplays through a series of calls eventually call to RootWindowContainer startHomeOnTaskDisplayArea method:

class RootWindowContainer extends WindowContainer<DisplayContent> implements DisplayManager.DisplayListener { ActivityTaskManagerService mService; boolean startHomeOnAllDisplays(int userId, String reason) { boolean homeStarted = false; // getChildCount retrieves the number of display devices from the mChildren argument. // mChildren is a WindowList object that contains data when setWindowManager is called. For (int I = getChildCount() -1; i >= 0; Final int displayId = getChildAt(I).mDisplayId; / / startHomeOnDisplay function called homeStarted | = startHomeOnDisplay (userId, reason, displayId); } return homeStarted; } / / a series of calls eventually call startHomeOnTaskDisplayArea... 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 ActivityStack stack = getTopDisplayFocusedStack(); taskDisplayArea = stack ! = null ? stack.getDisplayArea() : getDefaultTaskDisplayArea(); } Intent homeIntent = null; ActivityInfo aInfo = null; if (taskDisplayArea == getDefaultTaskDisplayArea()) { // 1. Intention to start ActivityTaskManagerService obtain the Launcher homeIntent = mService. GetHomeIntent (); ActivityInfo 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); mWindowManager.cancelRecentsAnimation(REORDER_KEEP_IN_PLACE, "startHomeActivity"); } // 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) + ":" + taskDisplayArea.getDisplayId(); // According to homeIntent, aInfo, Call startHomeActivity method to start and create the Launcher mService. GetActivityStartController () startHomeActivity (homeIntent aInfo, myReason, taskDisplayArea); return true; ActivityInfo resolveHomeActivity(int userId, ActivityInfo resolveHomeActivity, ActivityInfo resolveHomeActivity, ActivityInfo resolveHomeActivity) Intent homeIntent) { final int flags = ActivityManagerService.STOCK_PM_FLAGS; final ComponentName comp = homeIntent.getComponent(); ActivityInfo aInfo = null; try { if (comp ! = null) { // Factory test. aInfo = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); } else { final String resolvedType = homeIntent.resolveTypeIfNeeded(mService.mContext.getContentResolver()); final ResolveInfo info = AppGlobals.getPackageManager() .resolveIntent(homeIntent, resolvedType, flags, userId); if (info ! = null) { aInfo = info.activityInfo; } } } catch (RemoteException e) { // ignore } if (aInfo == null) { Slog.wtf(TAG, "No home screen found for " + homeIntent, new Throwable()); return null; } aInfo = new ActivityInfo(aInfo); aInfo.applicationInfo = mService.getAppInfoForUser(aInfo.applicationInfo, userId); return aInfo; } } public class ActivityTaskManagerService extends IActivityTaskManager.Stub { String mTopAction = Intent.ACTION_MAIN; String mTopData; // homeIntent.action = Intent.ACTION_MAIN ACTION_MAIN = "android.intent.action.MAIN" // FLAG_DEBUG_TRIAGED_MISSING // The category of a homeIntent contains intent.category_HOME CATEGORY_HOME = "android.intent.category.HOME"; 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) { intent.addCategory(Intent.CATEGORY_HOME); } return intent; }}Copy the code

The code is long, but it does two things:

  • Call ActivityTaskManagerService. Obtained getHomeIntent Intent intention
  • Intent.ponent Queries the corresponding ActivityInfo from the PackageManagerService according to the intent.ponent intent

Finally, by ActivityStartController. StartHomeActivity method, through layer upon layer called the last callProcess.startMethod to start and create a Launcher. This article will continue to analyze how to query all App information after the Launcher is started

Launcher Queries App information

In LauncherActivity, all App information is queried in the onCreate method:

public class Launcher extends StatefulActivity<LauncherState> implements LauncherExterns, Callbacks, InvariantDeviceProfile.OnIDPChangeListener, PluginListener<OverlayPlugin> { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); / / instantiate LauncherAppState LauncherAppState app. = LauncherAppState getInstance (this); LauncherModel mModel = app.getModel(); / / LauncherModel. AddCallbacksAndLoad will go to query the App information if (! mModel.addCallbacksAndLoad(this)) { if (! internalStateHandled) { // If we are not binding synchronously, show a fade in animation when // the first page bind completes. mDragLayer.getAlphaProperty(ALPHA_INDEX_LAUNCHER_LOAD).setValue(0); }}}}Copy the code

By calling in onCreate LauncherModel. AddCallbacksAndLoad App to query information, this method by a Handler to perform a Runnable task to execute the query.

public class LauncherModel extends LauncherApps.Callback implements InstallSessionTracker.Callback { // Callbacks public Boolean addCallbacksAndLoad(Callbacks Callbacks) {synchronized (mLock) {// Add Launcher to the list of callbacks. // call startLoader() return startLoader(); } } public boolean startLoader() { synchronized (mLock) { //..... stopLoader(); LoaderResults loaderResults = new LoaderResults( mApp, mBgDataModel, mBgAllAppsList, callbacksList, mMainExecutor); StartLoaderForResults (loaderResults); return false; } } public void startLoaderForResults(LoaderResults results) { synchronized (mLock) { stopLoader(); // LoaderTask is a Runnable mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, mBgDataModel, results); // Handler executes LoaderTask model_executor. post(mLoaderTask); }}}Copy the code

By looking at the key code, the LauncherModel simply sends a LoaderTask Runnable for the Handler to execute. So the App query is in the Run () method of the LoaderTask class.

public class LoaderTask implements Runnable { public void run() { //..... <LauncherActivityInfo> allActivityList = loadAllApps(); / /... } // Query all App private List<LauncherActivityInfo> loadAllApps() {final List<UserHandle> profiles = mUserCache.getUserProfiles(); List<LauncherActivityInfo> allActivityList = new ArrayList<>(); // Clear the list of apps mBgAllAppsList.clear(); for (UserHandle user : profiles) { // Query for the set of apps final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user); // Fail if we don't have any apps // TODO: Fix this. Only fail for the current user. if (apps == null || apps.isEmpty()) { return allActivityList; } / /... allActivityList.addAll(apps); } / /... return allActivityList; } } public class LauncherApps { public List<LauncherActivityInfo> getActivityList(String packageName, UserHandle user) { logErrorForInvalidProfileAccess(user); try { return convertToActivityList(mService.getLauncherActivities(mContext.getPackageName(), packageName, user), user); } catch (RemoteException re) { throw re.rethrowFromSystemServer(); }}}Copy the code

The run method of LoaderTask queries all apps.

conclusion

The Launcher is the system’s desktop process that starts after ActivityManagerService is ready. Start by getting the Intent Intent from ActivityManagerService and the corresponding ActivityInfo from PackageManagerService. When the Activity starts, it looks up all the App information in the onCreate() method.