ActivityManagerService(AMS for short) is a particularly important system service in Android system and one of the system services that our upper APP deals with most. AMS is mainly responsible for the startup, switchover, scheduling of four components as well as the management and scheduling of application processes. All APP applications need to deal with AMS. This chapter will analyze the startup process of AMS based on Android11 source code.

1. Start AMS service

AMS as one of the core service system, the startup process is located in the frameworks/base/services/Java/com/android/server/SystemServer. Java, the code is as follows:

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {...// Start to start AMS
    t.traceBegin("StartActivityManager");
    
    / / start ActivityTaskManagerService service, hereinafter referred to as ATM, Android 10 + newly introduced function, used to manage the start of the Activity, scheduling, and other functions
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
            
    // Start the service ActivityManagerService (AMS)mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); t.traceEnd(); .// Set the system process
    t.traceBegin("SetSystemProcess");
    mActivityManagerService.setSystemProcess();
    t.traceEnd();
}
Copy the code

As you can see from the code above, a new feature, called ATM, has been introduced in the android 10+ release, which we’ll examine later.

Ii. AMS Startup process

1. Initialize the System Context

The SystemServer run function calls the createSystemContext method before starting AMS, which is used to initialize the SystemContext and SystemUi Context, and set the theme. When SystemServer calls createSystemContext(), the following two things are done:

  1. You get an ActivityThread object that represents the main thread of the current process (in this case, the system process).
  2. We get a Context object that, for SystemServer, contains the Application runtime environment associated with Framework-res.apk.

frameworks/base/services/java/com/android/server/SystemServer.java

private void createSystemContext(a) {
    ActivityThread activityThread = ActivityThread.systemMain();
    
    // Get the system context
    mSystemContext = activityThread.getSystemContext();
    // Set the system theme
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
 
    // Get systemui context
    final Context systemUiContext = activityThread.getSystemUiContext();
    // Set the systemUI theme
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
Copy the code

(1) systemMain ()

The systemMain function creates an ActivityThread object and then calls its Attach method. frameworks/base/core/java/android/app/ActivityThread.java

public static ActivityThread systemMain(a) {
    ThreadedRenderer.initForSystemProcess();
    // Get the ActivityThread object
    ActivityThread thread = new ActivityThread();
    thread.attach(true.0);
    return thread;
}
Copy the code

(1.a) ActivityThread object creation

ActivityThread is a very important class in the Framework layer. It represents the main thread of an application process. Their duty is to scheduling and execution in the thread running in the four major components, related to the source code in the frameworks/base/services/Java/com/android/server/SystemServer Java.

public final class ActivityThread extends ClientTransactionHandler {...// Defines the interface for AMS to communicate with applications and initializes the objects of ApplicationThread
    @UnsupportedAppUsage
    final ApplicationThread mAppThread = new ApplicationThread();

    // Having your own looper shows that ActivityThread does represent event processing threads
    @UnsupportedAppUsage
    final Looper mLooper = Looper.myLooper();

    // Hadndle is initialized. A large number of events in ActivityThread depend on this Handler
    @UnsupportedAppUsage
    final H mH = new H();
    final Executor mExecutor = new HandlerExecutor(mH);
    
    // The ActivityRecord used to save the process
    final ArrayMap<IBinder, ActivityClientRecord> mActivities = new ArrayMap<>();
 
    // Save the Service in the process
    final ArrayMap<IBinder, Service> mServices = new ArrayMap<>();
 
    // Save the Application in the process
    final ArrayList<Application> mAllApplications
        = new ArrayList<Application>();
    // constructor
    @UnsupportedAppUsage
    ActivityThread() {
        // Get a ResourcesManager instance using the singleton pattern
        mResourcesManager = ResourcesManager.getInstance();
    }
Copy the code

Notice that the ActivityThread here was created in the SystemServer process. Because SystemServer also runs some system APKs, such as Framework-res.apk, settingsProvider.apk, it can also be considered as a special application process. AMS is responsible for managing and scheduling processes, so AMS needs to communicate with application processes through Binder mechanisms. To do this, Android provides an IApplicationThread interface that defines the interaction functions between AMS and application processes.

(1 b) attach method

The Attach method of ActivityThread divides the process into two parts: Application process and system process. For system process, the most important work is to create three important members of the Instrumentation, Application and Context. The responsibilities of the three members are as follows:

  • Instrumentation: a utility class in Android that, when enabled, takes precedence over other classes in the application.
  • Context: An abstract class in Android. It is used to maintain global information about the running environment of an application. You can use Context to access application resources and classes, and even perform system-level operations, such as starting activities and sending broadcasts.
  • Application: Saves the global status of an Application.

This part of the code is located in frameworks/base/core/Java/android/app/ActivityThread. Java.

private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mConfigurationController = new ConfigurationController(this);
    mSystemThread = system;
    
    if(! system) {// Process the application process. }else {
        // System process processing flow, this case is only handled in SystemServer
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            // Create the important members of ActivityThread: Instrumentation, Application, and Context

            // Initialize Instrumentation, which is a utility class in Android. When enabled, Instrumentation takes precedence over other classes in the application
            mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);

            // Create the system Context
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);

            // Call LoadedApk's makeApplication function. The Application class is used to store the global state of the Application
            mInitialApplication = context.mPackageInfo.makeApplication(true.null);
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():"+ e.toString(), e); }}Copy the code

(2) getSystemContext()

The getSystemContext() method called in SystemServer#createSystemContext() creates and returns a SystemContext, . In this method calls the ContextImpl createSystemContext method, this method creates a LoadedApk, and then initializes a ContextImpl object. In createSystemContext, LoadApk is created with packageName “Android” (framwork-res.apk). This apk is only used by SystemServer processes. Therefore, the created Context is defined as the System Context. Since the PMS is not started yet, the LoadedApk does not get the actual information from framwork-res.apk. When the PMS is started and the corresponding parsing is completed, AMS will reset the LoadedApk.

frameworks/base/services/java/com/android/server/SystemServer.java

public ContextImpl getSystemContext(a) {
    synchronized (this) {
        if (mSystemContext == null) {
            // Call the ContextImpl createSystemContext method
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        returnmSystemContext; }}// [frameworks/base/core/java/android/app/ContextImpl.java]
static ContextImpl createSystemContext(ActivityThread mainThread) {
    // Create a LoadedApk class that represents an APK loaded into the system. Since PMS is not started, LoadedApk has no content at this point
    LoadedApk packageInfo = new LoadedApk(mainThread);

    // Get the ContextImpl object
    ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
            ContextParams.EMPTY, null.null.null.null.null.0.null.null);
    
    // Initialize the resource information
    context.setResources(packageInfo.getResources());
    context.mResources.updateConfiguration(context.mResourcesManager.getConfiguration(),
            context.mResourcesManager.getDisplayMetrics());
    context.mContextType = CONTEXT_TYPE_SYSTEM_OR_SYSTEM_UI;
    return context;
}
Copy the code

2. ActivityTaskManagerService (ATM) services

ActivityTaskManagerService ATM for short, is’ android 10 + introduced a new feature, used to manage the Activity start, scheduling, and other functions, its prior to AMS launched, the following to the analysis of ATM to start the process. frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public static final class Lifecycle extends SystemService {
        private finalActivityTaskManagerService mService; .public Lifecycle(Context context) {
            super(context);
            / / initialize ActivityTaskManagerService object
            mService = new ActivityTaskManagerService(context);
        }
 
        @Override
        public void onStart(a) {
            publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
            // Start the ATM servicemService.start(); }... }public ActivityTaskManagerService(Context context) {
        // Get the System Context
        mContext = context;  
        mFactoryTest = FactoryTest.getMode();
 
        SCurrentActivityThread is the static variable of ActivityThread
        // This means that mSystemThread is the same as ActivityThread in SystemServer
        mSystemThread = ActivityThread.currentActivityThread();
        
        // Get the System UI Context
        mUiContext = mSystemThread.getSystemUiContext();
        mLifecycleManager = new ClientLifecycleManager();
        // Get the object of LocalService
        mInternal = new LocalService();
        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", GL_ES_VERSION_UNDEFINED);
    }

private void start(a) {
    / / add ActivityTaskManagerInternal to the local service of global registry
    LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}
Copy the code

As you can see from the above code, the startup of the AMT is divided into two parts:

  • Create ActivityTaskManagerService: initialize the ActivityTaskManagerService object in this step,This object, which used to belong to AMS for Activity management, has been moved to ATM, and the path of the object is moved toframeworks/base/services/core/java/com/android/server/wmPath, this path originally went toWindowManagerServiceControl, as you can see from this,Google also hopes to merge Activity and Windows in the future, reduce redundant code and AMS and WMS coordination.
  • Start: The start method is relatively simpleActivityTaskManagerInternalAdd to the global registry of the local service

ATM startup is complete.

3. The ActivityManagerService(AMS) service starts

In 11 of the Android, AMS is responsible for the service, the broadcast, the provider’s management and scheduling. AMS startup code is in the frameworks/base/services/core/Java/com/android/server/am/ActivityManagerService. Java, it is important to note that Lifecycle is also the name of the AMS startup method, which is the same as the ATM startup method, except that:

  • ATM located in frameworks/base/services/core/Java/com/android/server/wm, and AMS in rameworks/base/services/core/Java/com/android/server /am
public static final class Lifecycle extends SystemService {
    private final ActivityManagerService mService;
    private static ActivityTaskManagerService sAtm;
 
    public Lifecycle(Context context) {
        super(context);
        // Initializes ActivityManagerService, passing in the ATM object
        mService = new ActivityManagerService(context, sAtm);
    }
 
    @Override
    public void onStart(a) {
        // Start AMS servicemService.start(); }...Copy the code

(1) Initialize the AMS object

Android 11, the Activity of the management and scheduling into execution in the ATM, AMS reservation service, in the broadcast, the provider’s management and scheduling. Constructor initializes the main job is to initialize variables, for after service, broadcast, the provider’s management and scheduling. frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor.BatteryStatsImpl.BatteryCallback {
    public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {...//AMS runs in the same context as SystemServermContext = systemContext; .The sCurrentActivityThread is the same as the ActivityThread in SystemServer
        mSystemThread = ActivityThread.currentActivityThread();
        mUiContext = mSystemThread.getSystemUiContext();
 
        mHandlerThread = new ServiceThread(TAG,
                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        mHandlerThread.start();
        
        //AMS message handler
        mHandler = new MainHandler(mHandlerThread.getLooper());
        
        //UiHandler corresponds to UiThread in Android
        mUiHandler = mInjector.getUiHandler(this); .// Create a BroadcastQueue foreground broadcast object. The processing timeout is 10 seconds
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "foreground", foreConstants, false);
        // Create a BroadcastQueue. The timeout duration is 60 seconds
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "background", backConstants, true);
        // Create a BroadcastQueue. The timeout duration is 60 seconds
        mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
                "offload", offloadConstants, true);
        mBroadcastQueues[0] = mFgBroadcastQueue;
        mBroadcastQueues[1] = mBgBroadcastQueue;
        mBroadcastQueues[2] = mOffloadBroadcastQueue;
        
        // Create an ActiveServices object to manage the ServiceRecord object
        mServices = new ActiveServices(this); .// To get the ATM object, call atm. initialize
        mActivityTaskManager = atm;
        mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController,
                DisplayThread.get().getLooper());
        // Get ATM service information
        mAtmInternal = LocalServices.getService(
ActivityTaskManagerInternal.class);
 
        // Join Watchdog
        Watchdog.getInstance().addMonitor(this); Watchdog.getInstance().addThread(mHandler); . }}Copy the code

(2) start()

Start does two things

  • Reset the process
  • Register the battery status service and permission Management service

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

private void start(a) {
    // Remove all process groups
    removeAllProcessGroups();

    // Battery status service
    mBatteryStatsService.publish();
    // Permission management service
    mAppOpsService.publish();
    Slog.d("AppOps"."AppOpsService published");
    LocalServices.addService(ActivityManagerInternal.class, mInternal);
    LocalManagerRegistry.addManager(ActivityManagerLocal.class,
            (ActivityManagerLocal) mInternal);
    mActivityTaskManager.onActivityManagerInternalAdded();
    mPendingIntentController.onActivityManagerInternalAdded();
    mAppProfiler.onActivityManagerInternalAdded();
}
Copy the code

4. mActivityManagerService.setSystemProcess()

In the frameworks/base/services/Java/com/android/server/SystemServer java# startOtherServices invokes the AMS setSystemProcess method, The setSystemProcess method has five main functions:

  • Register services including Activity, procSTATS, memInfo, GFXInfo, dbInfo, Permission, processInfo
  • Get ApplicationInfo for the application whose package name is “Android”
  • Install system Application information for ActivityThread. Install ApplicationInfo for Framework-res.apk to mApplicationInfo in LoadedApk
  • Create a ProcessRecord for the SystemServer main process to maintain information about the process
  • AMS process management related operations.
private void startOtherServices(a) {...// Set up the application instance for the system process and start using it
    t.traceBegin("SetSystemProcess"); mActivityManagerService.setSystemProcess(); t.traceEnd(); . }// [frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java]
public void setSystemProcess(a) {
  try {
      // Service registration
      ServiceManager.addService(Context.ACTIVITY_SERVICE, this./* allowIsolated= */ true,
              DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
      ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
      ServiceManager.addService("meminfo".new MemBinder(this), /* allowIsolated= */ false,
              DUMP_FLAG_PRIORITY_HIGH);
      ServiceManager.addService("gfxinfo".new GraphicsBinder(this));
      ServiceManager.addService("dbinfo".new DbBinder(this));
      mAppProfiler.setCpuInfoService();
      ServiceManager.addService("permission".new PermissionController(this));
      ServiceManager.addService("processinfo".new ProcessInfoService(this));
 
      // Get ApplicationInfo by parsing androidmanifest.xml in framework res.apk
      ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
              "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
      // Install system Application information for ActivityThread. Install ApplicationInfo corresponding to Framework-res.apk into mApplicationInfo in LoadedApk
      mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
 
       // Create a ProcessRecord for the systemServer main process to maintain information about the process
      synchronized (this) {
          ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                  false.0.new HostingRecord("system"));
          // Set process resident
          app.setPersistent(true); 
          // Set the process ID, that is, the SYSTEM_server process ID
          app.pid = MY_PID;  
          app.getWindowProcessController().setPid(MY_PID);
          app.maxAdj = ProcessList.SYSTEM_ADJ;
          app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
          // Place ProcessRecord in mPidSelfLocked for unified management
          addPidLocked(app);
          updateLruProcessLocked(app, false.null); updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_NONE); }}catch (PackageManager.NameNotFoundException e) {
      throw new RuntimeException(
              "Unable to find android system package", e); }... }Copy the code

5. systemReady()

AMS after the launch, still need to call a systemReady () method, the code is as follows: frameworks/base/services/Java/com/android/server/SystemServer Java

mActivityManagerService.systemReady(() -> {
    ...
    
})
Copy the code

The method is divided into three stages

  1. This is done by calling the initialization functions of some of the key services, killing processes that don’t have FLAG_PERSISTENT but already exist before AMS starts, and getting some configuration parameters. Note that since only Java processes register with AMS, and Native processes do not register with AMS, the process killed here is a Java process.

  2. GoingCallback notifies services that systemReady, systemRunning, and start services or application processes

  3. Start the Home Activity, and when the start is complete and the ACTION_BOOT_COMPLETED broadcast is sent, the AMS start process comes to an end

The following three phases are explored in combination with specific codes.

(1) Initialization of key services

This phase involves calling the initialization functions of some key services, killing processes that don’t FLAG_PERSISTENT but already exist before AMS is started, and getting some configuration parameters. Note that since only Java processes register with AMS, and Native processes do not register with AMS, the process killed here is a Java process.

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
    synchronized(this) {
        // If mSystemReady is false for the first time, this process is not performed
        if (mSystemReady) {
            if(goingCallback ! =null) {
                goingCallback.run();
            }
            t.traceEnd();
            return;
        }
 
        // This section mainly calls some key service SystemReady related functions,
        // Do some work waiting for AMS to complete
        t.traceBegin("controllersReady");
        mLocalDeviceIdleController =
                LocalServices.getService(DeviceIdleInternal.class);
        mActivityTaskManager.onSystemReady();
        mUserController.onSystemReady();
        mAppOpsService.systemReady();
        mProcessList.onSystemReady();
        mSystemReady = true;
        t.traceEnd();
    }
 
    try {
        sTheRealBuildSerial = IDeviceIdentifiersPolicyService.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_IDENTIFIERS_SERVICE))
                .getSerial();
    } catch (RemoteException e) {}
 
    ArrayList<ProcessRecord> procsToKill = null;
    synchronized(mPidsSelfLocked) {
        // mPidsSelfLocked stores information about all processes that are currently running
        for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
            ProcessRecord proc = mPidsSelfLocked.valueAt(i);
            // If a process with no FLAG_PERSISTENT is started before AMS starts,
            // Add this process to procsToKill
            if(! isAllowedWhileBooting(proc.info)){if (procsToKill == null) {
                    procsToKill = newArrayList<ProcessRecord>(); } procsToKill.add(proc); }}}// Collect started processes and kill them, excluding persistent resident processes
    synchronized(this) {
        Close the process in procsToKill with removeProcessLocked
        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"); }}// System is ready
        mProcessesReady = true; }... mUgmInternal.onSystemReady(); }Copy the code

(2) Execute goingCallback processing

The main work of this phase is to notify some services that are systemReady and start the service or application process. frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {...// Call the runnable object passed in as the parameter, as defined in SystemServer
    if(goingCallback ! =null) goingCallback.run(); .// Start system services (in this case, battery status management services)
    t.traceBegin("ActivityManagerStartApps");
    mBatteryStatsService.onSystemReady();
    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
            Integer.toString(currentUserId), currentUserId);
    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
        Integer.toString(currentUserId), currentUserId);

    final boolean bootingSystemUser = currentUserId == UserHandle.USER_SYSTEM;

    if (bootingSystemUser) {
        mSystemServiceManager.onUserStarting(t, currentUserId);
    }
    synchronized (this) {
        // Start the process where the application whose persistent is 1 resides
        startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
        
        // Start up initial activity.
        mBooting = true; . }}Copy the code

(2.a) goingCallback.run()

The main body in the frameworks/base/services/Java/com/android/server/SystemServer java# startOtherServices, Goingcallback.run () is used to monitor the Native crash and start the WebView. Execute systemReady and systemRunning methods for some services.

private void startOtherServices(a) {
  mActivityManagerService.systemReady(() -> {
  // Phase 550 Acitvity Manager startup completedmSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); .// Monitor Native crashmActivityManagerService.startObservingNativeCrashes(); , BOOT_TIMINGS_TRACE_LOG); ./ / start the WebView
  mWebViewUpdateService.prepareWebViewInSystemServer();
  
  // Execute systemReady methods for a series of servicesnetworkManagementF.systemReady(); ipSecServiceF.systemReady(); networkStatsF.systemReady(); connectivityF.systemReady(); networkPolicyF.systemReady(networkPolicyInitReadySignal); .// Phase 600 third-party applications can be launched
  mSystemServiceManager.startBootPhase(
              SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
  
  // Execute the systemRunning method for a series of serviceslocationF.systemRunning(); countryDetectorF.systemRunning(); networkTimeUpdaterF.systemRunning(); inputManagerF.systemRunning(); telephonyRegistryF.systemRunning(); mediaRouterF.systemRunning(); mmsServiceF.systemRunning(); . }Copy the code

(2.b) startPersistentApps()

This method is used to start the process where the application whose persistent is 1 resides. frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

void startPersistentApps(int matchFlags) {
  if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
  
  synchronized (this) {
      try {
           // Get ApplicationInfo with persistent 1 from PKMS
          final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
                  .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
          for (ApplicationInfo app : apps) {
               Framework-res.apk is not started here because it has already been started by the system
              if (!"android".equals(app.packageName)) {
                   //addAppLocked will start the application process
                  addAppLocked(app, null.false.null /* ABI override */); }}}catch (RemoteException ex) {
      }
  }
}
Copy the code

(3) Complete AMS startup

The Home Activity is started at this stage, and AMS is started when it is finished and the ACTION_BOOT_COMPLETED broadcast is sent. frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public  void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {...// Start the Home Activity from ATM
  mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); .// Send a broadcast message
  try {
      / / the system to send radio ACTION_USER_STARTED = "android. Intent. Action. USER_STARTED";
      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);
      / / the system to send radio ACTION_USER_STARTING = "android. Intent. Action. USER_STARTING";
      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); }}Copy the code

(3) Start the Home Activity

Android Luncher is actually launched here, after the launch, we can see the Android system’s main screen. frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java

public boolean startHomeOnAllDisplays(int userId, String reason) {
    synchronized (mGlobalLock) {
        // Call startHomeOnAllDisplays() to startHomeOnDisplay()
        returnmRootWindowContainer.startHomeOnAllDisplays(userId, reason); }}// [frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java]
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;
}

// [frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java]
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) {
        finalTask 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 */);
}

// [frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java]
boolean startHomeOnTaskDisplayArea(int userId, String reason, TaskDisplayArea taskDisplayArea,
        boolean allowInstrumenting, boolean fromHomeKey) {...// Start the Home Activity--Luncher
    mService.getActivityStartController().startHomeActivity(homeIntent, aInfo, myReason,
        taskDisplayArea);
    return true;
}
Copy the code

Third, summary

This chapter explores the startup process of AMS in detail. It is worth noting that in Android 9.0 and earlier, Acitivity management is performed in collaboration between AMS and WMS, resulting in difficult collaboration between entities with similar functionality in BOTH AMS and WMS, in addition to a large amount of code redundancy. From the code changes in Android 11, Google’s ultimate goal is to merge activity and Window. In fact, the integration of Activity and Window started as early as Android 10, but now it is just a simple code collated together, still belongs to the intermediate state. According to the Android documentation, full integration won’t be completed until Android 12 or later.