Based on Android 10 source code analysis

Introduction of AMS

ActivityManagerService is a very important system service in Android system, and it is one of the system services that our upper-layer apps deal with most. ActivityManagerService(AMS) is responsible for starting, switching, and scheduling four components, as well as managing and scheduling required processes. All apps need to work with AMS

Activity Manager consists of the following parts:

  1. Service proxy: Implemented by ActivityManagerProxy, it is used for interprocess communication with system services provided by the Server
  2. Service hub :ActivityManagerNative inherits from Binder and implements IActivityManager, which provides interconversion between service interfaces and Binder interfaces, stores the service proxy image internally and provides the getDefault method to return the service proxy
  3. Client: The ActivityManager encapsulates part of the service interface for the Client to invoke. Internally, ActivityManager calls ActivityManagerNative’s getDefault method to get a reference to an ActivityManagerProxy object, which can then be used to invoke methods on the remote service
  4. Server: Implemented by ActivityManagerService, provides system services on the Server side

The startup process of AMS

AMS is created in the system_service process and runs in the system_service process, so we first analyze the system_service startup process.

For details on how to create system_service, see the Android startup overview. Just a quick review here

Above,ZygoteStart up the core flow chart of our processsystem_serviceThe process is atstartSystemServer()To start.system_serviceAfter the process starts, the main process is as follows, as shown in the figure belowLet’s move on to our code trace

System_service Starts initialization

System_service is the first service process created by Zygote fork. Its main job is to create and maintain a variety of core services such as AMS, WMS, PKMS and other Framework layer use the most frequent core services.

Start systemservice.main ()

public static void main(String[] args) {
    new SystemServer().run();
}

private void run(a) {
    TimingsTraceAndSlog t = new TimingsTraceAndSlog();
    try {
        t.traceBegin("InitBeforeStartServices");
      
      	// omit the code

      	// binder related Settings
        // 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 thread looper
        // 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);

				// omit the code
      
      	// Initialize SystemContext
        createSystemContext();

        / / create SystemServiceManager
        mSystemServiceManager = new SystemServiceManager(mSystemContext);
        mSystemServiceManager.setStartInfo(mRuntimeRestart,
                mRuntimeStartElapsedTime, mRuntimeStartUptime);
        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
      
      	// Prepare a thread pool to handle service creation
        SystemServerInitThreadPool.start();

    } finally {
        t.traceEnd();  // InitBeforeStartServices
    }

    // Start the service
    try {
        t.traceBegin("StartServices");
        startBootstrapServices(t);
        startCoreServices(t);
        startOtherServices(t);
    } catch (Throwable ex) {
        throw ex;
    } finally {
        t.traceEnd(); // StartServices
    }

    // Loop forever.
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}
Copy the code
  • Systemserver. main initializes the SystemServer object and calls its run() method
    • SystemServer.run
      • createSystemContext
      • StartBootstrapServices Starts the boot service
      • StartCoreServices starts the core service
      • StartOtherServices Starts other services
      • Looper.loop Enters the loop loop

SystemService.createSystemContext()

private void createSystemContext(a) {
  	// Create a system thread
    ActivityThread activityThread = ActivityThread.systemMain();
  	// Set the system theme
    mSystemContext = activityThread.getSystemContext();
    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
    final Context systemUiContext = activityThread.getSystemUiContext();
    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}
Copy the code
  • Create system thread ActivityThread. SystemMain ()
  • Msystemcontext. setTheme Sets the system theme

ActivityThread.systemMain()

public static ActivityThread systemMain(a) {
    if(! ActivityManager.isHighEndGfx()) { ThreadedRenderer.disable(true);
    } else {
        ThreadedRenderer.enableForegroundTrimming();
    }
    ActivityThread thread = new ActivityThread();
    thread.attach(true.0);
    return thread;
}
Copy the code
  • new ActivityThread()

    • Create the ApplicationThread object

    • Create the H (Class H extends Handler) object when Looper of mH is ready at SystemService.run()

    • MInitialApplication assignment

      • The system_server process is assigned by the ActivityThread.attach() procedure
      • Ordinary app process is thus by ActivityThread handleBindApplication assignment () process
    • Access to materials management instance ResourcesManager. GetInstance ()

  • thread.attach(true, 0)

    @UnsupportedAppUsage
    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        if(! system) {// do not return to execute here
        } else {
            try {
              	/ / create Instrumentation
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
              	1. Run getSystemContext() to create the singleton mSystemContext
              	/ / 2. Create appContext
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
              	// Create Application instance
                mInitialApplication = context.mPackageInfo.makeApplication(true.null);
              	// Call Application onCreate
                mInitialApplication.onCreate();
            } catch (Exception e) {
              	/ /...}}/ /...
    }
    Copy the code
    • Create Instrumentation
    • ContextImpl.createAppContext
      • activityThread.getSystemContext
        • Objects created mSystemContext ContextImpl. CreateSystemContext singleton pattern
          • Create the LoadedApk object
            • Create the ApplicationInfo object
            • To create this
          • Create ContextImpl
            • The first execution of getSystemContext creates LoadedApk and contextImpl objects, and then uses the LoadedApk object to create a new contextImpl object
    • makeApplication
      • InitializeJavaContextClassLoader sets the current thread Context this
      • newApplication
        • InstantiateApplication Creates an Application object
          • Save the newly created ContextImpl object to the Application’s parent class member variable mBase
          • Save the newly created LoadedApk object to the Application parent variable mLoadedApk
    • mInitialApplication.onCreate()

AMS Startup process

Following the system_service startup process described above, let’s start the AMS service.

SystemServer.startBootstrapServices()

Start our boot service, and this is where our AMS starts.

private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
  	Start the Watchdog as early as possible to cause a system service breakdown if a deadlock occurs during startup
    final Watchdog watchdog = Watchdog.getInstance();
    watchdog.start();
		/ /...
  	// Start installation service
    Installer installer = mSystemServiceManager.startService(Installer.class);
  	/ /...
  	// Start ATMS, more asM-related services than 6.0 source code.
  	// It is mainly responsible for Activity management and scheduling and so on
    ActivityTaskManagerService atm = mSystemServiceManager.startService(
            ActivityTaskManagerService.Lifecycle.class).getService();
  	// Start AMS is responsible for managing four major components and processes, including life cycle and state transitions.
    mActivityManagerService = ActivityManagerService.Lifecycle.startService(
            mSystemServiceManager, atm);
  	/ / set mSystemServiceManager
    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
  	/ / set the installer
    mActivityManagerService.setInstaller(installer);
  	/ /...
  	// Initialize the AMS related PMS, which must be called after the PMS service is started
    mActivityManagerService.initPowerManagement();
  	/ / set ApplicationInfo
    mActivityManagerService.setSystemProcess();
  	// The watchdog starts listening to the AMS service and restarts the AMS when it detects an exception
    // Complete the watchdog setup with an ActivityManager instance and listen for reboots
    // Do this only after the ActivityManagerService is properly started as a system process
    watchdog.init(mSystemContext, mActivityManagerService);
}
Copy the code
  • Enable the Watchdog function
  • Start the Installer installation service
  • MSystemServiceManager. Start startService ATMS
  • AMS ActivityManagerService. Lifecycle. StartService started
  • MActivityManagerService. SetInstaller set AMS APP installer
  • MActivityManagerService initPowerManagement initialization AMS related PMS
  • SystemServer mActivityManagerService. SetSystemProcess Settings
  • The watchdog starts to listen to the AMS service and restarts the AMS if an exception occurs
SystemServiceManager startService startup services

ATMS and AMS by mSystemServiceManager startService start.

public <T extends SystemService> T startService(Class<T> serviceClass) {
    try {
      	/ /...
        final T service;
        try {
          	// Create a Service instance through reflection
            Constructor<T> constructor = serviceClass.getConstructor(Context.class);
            service = constructor.newInstance(mContext);
        } catch (InstantiationException ex) {
      			/ /...
        } catch (IllegalAccessException ex) {
      			/ /...
        } catch (NoSuchMethodException ex) {
      			/ /...
        } catch (InvocationTargetException ex) {
      			/ /...
        }

        startService(service);
        return service;
    } finally {
      	/ /...}}public void startService(@NonNull final SystemService service) {
  	// The instance is cached to the mServices container
    mServices.add(service);
    try {
      	// Call the service's onStart method
        service.onStart();
    } catch (RuntimeException ex) {
      	/ /...}}Copy the code

To note here is that ActivityTaskManagerService. Lifecycle and ActivityManagerService Lifecycle are SystemService subclasses They all realized the onStart method. So service.onstart () calls the corresponding overloaded onStart methods, respectively.

The core process here is to create a service instance and then start the service

  • Create ActivityTaskManagerService instance

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public ActivityTaskManagerService(Context context) {
        mContext = context;
        mFactoryTest = FactoryTest.getMode();
      	// System threads
        mSystemThread = ActivityThread.currentActivityThread();
        mUiContext = mSystemThread.getSystemUiContext();
      	// Create lifecycle management
        mLifecycleManager = new ClientLifecycleManager();
      	/ / create ActivityTaskManagerInternal instance
        mInternal = new LocalService();
        / /...
    }
    Copy the code

    LocalService inherited from ActivityTaskManagerInternal

  • ActivityTaskManagerService.Lifecycle.onStart()

    public void onStart(a) {
      	/ / will add to the ServiceManager ActivityTaskManagerService service (Binder bassoon home
        publishBinderService(Context.ACTIVITY_TASK_SERVICE, mService);
      	// Start the service
        mService.start();
    }
    Copy the code
    • ActivityTaskManagerService.onStart()

      private void start(a) {
        	/ / add ActivityTaskManagerInternal to system_service global container, in the process of the process through LocalServices to facilitate access to the service instance
          LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
      }
      Copy the code
  • Create an ActivityManagerService instance

  • ActivityManagerService. Lifecycle. OnStart () eventually drop ActivityManagerService. Start ()

    private void start(a) {
      	// Remove all process groups
        removeAllProcessGroups();
      	// Start the CpuTracker thread
        mProcessCpuThread.start();
    		// Start battery statistics service
        mBatteryStatsService.publish();
        mAppOpsService.publish();
      	/ / ActivityManagerInternal instances are added to the LocalServices, sharing process
        LocalServices.addService(ActivityManagerInternal.class, mInternal);
      	/ / notice ActivityTaskManagerService can get ActivityManagerInternal instance
        mActivityTaskManager.onActivityManagerInternalAdded();
        mPendingIntentController.onActivityManagerInternalAdded();
        try {
            mProcessCpuInitLatch.await();
        } catch (InterruptedException e) {
            / /...}}Copy the code
ActivityManagerService.setSystemProcess
public void setSystemProcess(a) {
    try {
      	// Add AMS services to ServiceManager(Binder manager)
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this./* allowIsolated= */ true,
                DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
      	// Omit the code, here are some binder instances or services added to the ServiceManager code MemBinder GraphicsBinder DbBinder CacheBinder CpuBinder etc
			
				/ / create ApplicationInfo
        ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
                "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
      	// Initialize ApplicationInfo
        mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
				
      	// Create ProcessRecord object
        synchronized (this) {
            ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,
                    false.0.new HostingRecord("system"));
            app.setPersistent(true);
            app.pid = MY_PID;
            app.getWindowProcessController().setPid(MY_PID);
            app.maxAdj = ProcessList.SYSTEM_ADJ;
            app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
            addPidLocked(app);
            mProcessList.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
  • Registration services. First register ActivityManagerService with the ServiceManager, and then register several services related to system performance debugging with the ServiceManager.
  • Query and process ApplicationInfo. The interface of the PackageManagerService is called to query the ApplicationInfo information of the android application program, corresponding to Framework-res.apk. And then to the information for the parameter called ActivityThread installSystemApplicationInfo method.
  • Create and process ProcessRecord. Call newProcessRecordLocked on ActivityManagerService to create an object of type ProcessRecord and save the information for that object

SystemServer.startOtherServices()

private void startOtherServices(@NonNull TimingsTraceAndSlog t) {
    //....
    try {
        //....
        // Set up WMS management
        mActivityManagerService.setWindowManager(wm);
        Install the system Provider
      	// Create a core Settings Observer to monitor Settings changes
        mActivityManagerService.installSystemProviders();
				//....
    } catch (Throwable e) {
        //....
    }
		//....
  	// call AMS systemReady
   mActivityManagerService.systemReady(() -> {
        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_ACTIVITY_MANAGER_READY);
        / /...
        try {
          	//startSystemUi Starts the system UI
            startSystemUi(context, windowManagerF);
        } catch (Throwable e) {
            / /...
        }
     		/ /... Perform systemReady and systemRunning for a range of services
     
        mSystemServiceManager.startBootPhase(t, SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
    }, t);
}
Copy the code
  • MActivityManagerService setWindowManager set WMS management

  • MActivityManagerService. InstallSystemProviders installation system Provider; Create a core Settings Observer to monitor Settings changes

  • MActivityManagerService systemReady notify the AMS system is ready

    • Notifies AMS associated internal service system that the service is ready

    • StartSystemUi Starts the system UI

    • MSystemServiceManager. Inform mSystemServiceManager startBootPhase. MServices all service onBootPhase callback

      public void startBootPhase(@NonNull TimingsTraceAndSlog t, int phase) {
          if (phase <= mCurrentPhase) {
              throw new IllegalArgumentException("Next phase must be larger than previous");
          }
          mCurrentPhase = phase;
          try {
              final int serviceLen = mServices.size();
              for (int i = 0; i < serviceLen; i++) {
                  final SystemService service = mServices.get(i);
                  try {
                      service.onBootPhase(mCurrentPhase);
                  } catch (Exception ex) {
                    	/ /...}}}finally{ t.traceEnd(); }}Copy the code
      • AMS. Lifecycle. OnBootPhase AMS state change notice

        public void onBootPhase(int phase) {
            mService.mBootPhase = phase;
            if (phase == PHASE_SYSTEM_SERVICES_READY) {
                mService.mBatteryStatsService.systemServicesReady();
                mService.mServices.systemServicesReady();
            } else if (phase == PHASE_ACTIVITY_MANAGER_READY) {
                mService.startBroadcastObservers();
            } else if(phase == PHASE_THIRD_PARTY_APPS_CAN_START) { mService.mPackageWatchdog.onPackagesReady(); }}Copy the code

summary

System_server process, from the source point of view into boot services, core services, other services 3 categories.

  1. Bootstrap services (7) : ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService, SensorService;
  2. Core services (3) : BatteryService, UsageStatsService, WebViewUpdateService;
  3. Other services (70 +) : AlarmManagerService, VibratorService, etc.

Service startup SystemServiceManager. StartService:

  • Function:
    • Create a service object;
    • Execute the onStart() method of the service; This method executes sm.addService () above;
    • The onBootPhase() method is called back depending on the startup phase;
    • In addition, there are callback methods for user state changes in multi-user mode. For example onStartUser ();
  • Features: Services often inherit from SystemService themselves or from internal classes;

AMS summary

AMS is a boot service in system services and runs in the system_service process. There is close interaction with many other services.

During the startup of AMS, the AMS service registers its services with the ServiceManager, enabling cross-process communication with the Binder;

In the system_service process, you can interact by referring to or retrieving the corresponding service from the LocalServices service container

  • The mServices container in SystemServiceManager caches all services started by SystemServiceManager
  • LocalServices caches the internal implementation of each service, such as LocalServiceLocalService extends ActivityManagerInternalThese are defined in the inner class of the service and can be used by other processesLocalServices.getService()For instance