In-depth understanding of AMS

Start the

As mentioned in the Android startup process, AMS is started in system_service,

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

ActivityManagerService, PowerManagerService, LightsService, DisplayManagerService, PackageManagerService, UserManagerService.
// Set ActivityManagerService to start the sensor service.
startBootstrapServices(); // Start the boot service

// This method is main
BatteryService Is used to count battery power. LightService is required.
// Start the UsageStatsService to collect statistics on application usage.
// Start service WebViewUpdateService.
startCoreServices();      // Start the core service

// This method starts services InputManagerService, WindowManagerService.
// Wait for the ServiceManager and SurfaceFlinger to complete startup. Then the startup screen is displayed.
// Start service StatusBarManagerService,
// Prepare the window, power, package, display service:
//	- WindowManagerService.systemReady()
//	- PowerManagerService.systemReady()
//	- PackageManagerService.systemReady()
//	- DisplayManagerService.systemReady()
startOtherServices();     // Start other services
Copy the code

In the startup core service function, AMS is started.

   //frameworks/base/services/java/corri/android/server/SystemServer.java
    private void startBootstrapServices(a) {...// The ATMS is registered with the ServiceManager and the ATMS start method is called.
        ActivityTaskManagerService atm = mSystemServiceManager.startService(ActivityTaskManagerService.Lifecycle.class).getService();
        // Focus on method 1. Register the AMS service and return the corresponding object information
        mActivityManagerService = ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm);
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        // Set the app installermActivityManagerService.setInstaller(installer); .// Focus on method 2. Register Binder services with the ServiceManager
        mActivityManagerService.setSystemProcess();
    }
Copy the code

Here we just captured the AMS startup code.

The startService method is used to register and start AMS. Let’s look at the startService method in the specific ActivityManagerService

startService

//    
	public static ActivityManagerService startService(SystemServiceManager ssm, ActivityTaskManagerService atm) {
            sAtm = atm;
            // Call SM's startService method. Create an AMS instance and start AMS
            return ssm.startService(ActivityManagerService.Lifecycle.class).getService();
        }
Copy the code

We explained in the working principle of ServiceManager, systemServiceManager. StartService method corresponding service will be registered to the ServiceManager, then invoke the start method.

//frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
		public SystemService startService(String className) {
        final Class<SystemService> serviceClass;
        serviceClass = (Class<SystemService>)Class.forName(className);
        return startService(serviceClass);
    }

    @SuppressWarnings("unchecked")
    public <T extends SystemService> T startService(Class<T> serviceClass) {
        try {
            final String name = serviceClass.getName();
            final T service;
            try {
                // Reflection constructor
                Constructor<T> constructor = serviceClass.getConstructor(Context.class);
                // Create a serviceservice = constructor.newInstance(mContext); .// Start the service
            startService(service);
            return service;
        } finally{ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); }}public void startService(@NonNull final SystemService service) {
        // Register it.
        // Register with the ServiceManager list
        mServices.add(service);
        // Call the onStart method corresponding to the service
        service.onStart();
    }
Copy the code

When start the AMS incoming parameters are: ActivityManagerService. Lifecycle. The class. So it will actually call ActivityManagerService. The structure of the Lifecycle methods, and then call it onStart method

   public static final class Lifecycle extends SystemService {
        private final ActivityTaskManagerService mService;
        public Lifecycle(Context context) {
            super(context);
            // Create an AMS object
            mService = new ActivityManagerService(context, sAtm);
        }
        @Override
        public void onStart(a) {
            // call AMS's start method
            mService.start();
        }

        public ActivityManagerService getService(a) {
            // an AMS instance is returned
            returnmService; }}Copy the code

During the creation of Lifecycle objects, AMS objects are created and started using the start() method.

The AMS to create

The creation of AMS objects is done through constructors.

    // select * from ();
    public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
        // Get the ActivityThread for the system
        mSystemThread = ActivityThread.currentActivityThread();
        // Create a ServiceThread to handle commands received by AMS
        mHandlerThread = new ServiceThread(TAG,THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
        mHandlerThread.start();
        mHandler = new MainHandler(mHandlerThread.getLooper());
        mUiHandler = mInjector.getUiHandler(this);
        // Low memory monitoring
        mLowMemDetector = new LowMemDetector(this);
        // Initialize the broadcast queue. Here includes the foreground broadcast, backstage broadcast and so on
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", foreConstants, false);
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", backConstants, true);
        mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler, "offload", offloadConstants, true);
        mBroadcastQueues[0] = mFgBroadcastQueue;
        mBroadcastQueues[1] = mBgBroadcastQueue;
        mBroadcastQueues[2] = mOffloadBroadcastQueue;
        // To save the registered Service
        mServices = new ActiveServices(this);
        //map, which holds the registered ContentProvider
        mProviderMap = new ProviderMap(this);
        mPackageWatchdog = PackageWatchdog.getInstance(mUiContext);
        mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog);

        // Create /data/system directory
        final File systemDir = SystemServiceManager.ensureSystemDir();
        // Create a process statistics service and save it in the /data/system/proccstats directory.
        mProcessStats = new ProcessStatsService(this.new File(systemDir, "procstats"));
        // Assign ATM and initialize
        mActivityTaskManager = atm;
        mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController, DisplayThread.get().getLooper());
        //CPU tracker process
        mProcessCpuThread = new Thread("CpuTracker") {
            @Override
            public void run(a) {... }}; }Copy the code

Some initialization is done in the AMS constructor: starting CPU monitoring, starting the process statistics Service, starting low memory monitoring, initializing the Service and the save classes corresponding to the ContentProvider, and so on.

start()

When the AMS class is created, the start() method is called.

   private void start(a) {
    	 // Remove all process groups
        removeAllProcessGroups();
        // Start the CpuTracker thread
        mProcessCpuThread.start();
        // Start the battery statistics service, which can count the battery consumption of a specific application, so as to carry out certain battery statistics
        mBatteryStatsService.publish();
        // Create LocalService and add it to the list of LocalServices
        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
        mActivityTaskManager.onActivityManagerInternalAdded();
        mUgmInternal.onActivityManagerInternalAdded();
        mPendingIntentController.onActivityManagerInternalAdded();
   }
Copy the code

In the start method, some of the threads created in the constructor are started.

setSystemProcess

After it is created and started, some system-specific services are registered with the ServiceManager using the setSystemProcess method.

    public void setSystemProcess(a) {
        try {
        	// Register ActivityService
            ServiceManager.addService(Context.ACTIVITY_SERVICE, this./* allowIsolated= */ true,
                    DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);
            // Register the process status service
            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
            // Register memory Binder
            ServiceManager.addService("meminfo".new MemBinder(this), /* allowIsolated= */ false,DUMP_FLAG_PRIORITY_HIGH);
            // Register image Binder
            ServiceManager.addService("gfxinfo".new GraphicsBinder(this));
            // Register SQLite DB binder
            ServiceManager.addService("dbinfo".new DbBinder(this));
            if (MONITOR_CPU_USAGE) {
            	// Register binders for CPU usage
                ServiceManager.addService("cpuinfo".new CpuBinder(this),/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL);
            }
            // Register permission control Binder
            ServiceManager.addService("permission".new PermissionController(this));
            // Register process management Binder
            ServiceManager.addService("processinfo".new ProcessInfoService(this));
            // Get the ApplicationInfo of the android application and load it to mSystemThread
            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo("android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
            // Create ProcessRecord to maintain information about the process
            synchronized (this) { ProcessRecord app = mProcessList.newProcessRecordLocked(info, info.processName,...) ; app.setPersistent(true);
                app.pid = MY_PID;
                app.getWindowProcessController().setPid(MY_PID);
                app.maxAdj = ProcessList.SYSTEM_ADJ;
                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
                mPidsSelfLocked.put(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

This method sets up some system processes. The main functions are:

  • Register services: Activity, procSTATS, memInfo, GFXInfo, dbInfo, CPUInfo, Permission, ProcessInfo, and so on.
  • Get the ApplicationInfo object of the application whose package name is “Android” and install the ApplicationInfo to SystemThread. Understandably, the system is also a special application.
  • Create ProcessRecord to maintain information about the process, where MY_PID is the SystemServer process ID.
  • Start monitoring application running and interaction.

subsequent

After AMS is created and launched, there is a series of follow-up work to be done. These operations are invoked in **startOtherServices()**

     private void startOtherServices(a) {
            // Register the system's ContentProvider information
            mActivityManagerService.installSystemProviders();
       
            mActivityManagerService.setWindowManager(wm);
           	mActivityManagerService.systemReady(() -> {
                ......//goingCallback
            }, BOOT_TIMINGS_TRACE_LOG);
     }
Copy the code
   public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
        traceLog.traceBegin("PhaseActivityManagerReady");
        synchronized(this) {
        	// The first entry is false
            if (mSystemReady) {
                // If AMS is ready, goingCallback's run method is called and returns
                if(goingCallback ! =null) {
                    goingCallback.run();
                }
                return;
            }
            mLocalDeviceIdleController = LocalServices.getService(DeviceIdleController.LocalService.class);
            // Call the ATMS onSystemReady method
            mActivityTaskManager.onSystemReady();
            mSystemReady = true;
        }
     
        // Close all processes in procsToKill
        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 = newArrayList<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."system update done"); }}// At this point, the entire system is ready. You can create processes and so on.
            mProcessesReady = true; }.../ / run goingCallback
        if(goingCallback ! =null) goingCallback.run(); .// Start the activity of the Launcher
        mAtmInternal.startHomeOnAllDisplays(currentUserId, "systemReady"); . }}Copy the code

The main functions here are:

  • Key services continue to be initialized
  • Processes that are already started and do not have the FLAG_PERSISTENT bit will be killed
  • Run goingCallBack
  • Start the Activity of the launcher, that is, the desktop application.

Here we continue to trace the execution of goingCallBack.

goingCallBack

       mActivityManagerService.systemReady(() -> {
            try {
                // Start NativeCrash monitoring
                mActivityManagerService.startObservingNativeCrashes();
            } catch (Throwable e) {
                reportWtf("observing native crashes", e);
            }
            if(! mOnlyCore && mWebViewUpdateService ! =null) {
                webviewPrep = SystemServerInitThreadPool.get().submit(() -> {
                    // Start WebView related
                    mWebViewUpdateService.prepareWebViewInSystemServer();
                }, WEBVIEW_PREPARATION);
            }

            try {
                / / start systemUI
                startSystemUi(context, windowManagerF);
            } catch (Throwable e) {
                reportWtf("starting System UI", e); }... }Copy the code

Some initialization work continues in this:

  • Start Native Rash monitoring
  • Start webView-related services
  • Start the SystemUI

startHomeOnAllDisplays

This function is mainly used to start desktop programs, which is not related to the startup process of AMS. It will not be analyzed in detail here.

Conclusion:

  • AMS is created and started in the SystemServer process
  • In the process of service startup of AMS, some object creation and initialization are carried out through constructors (at the beginning, the list of other three components and the creation of scheduling objects; Memory, battery, permissions, CPU, etc.) and start services (remove process groups, start CPU threads, permissions registration, battery services, etc.) with the start() method.
  • After AMS has created and started the corresponding service, the SystemServer process LoadedApk will be added to the framework-res.apk information through the setSystemProcess method. The SystemServer process ProcessRecord has been added to mPidsSelfLocked, which is managed by AMS
  • The rest of the work after AMS starts is performed by calling systemReady() and the incoming goingCallBack. It is mainly a variety of services or processes that need to be further completed after AMS is started and system related initialization.
  • The desktop application is started in the systemReady() method and the systemUI is done in the goingCallback.
  • When the desktop application has started, the startup broadcast ACTION_BOOT_COMPLETED is sent.

reference

Blog.csdn.net/weixin_3403…

www.cnblogs.com/fanglongxia…

Source code analysis project address: github.com/kailaisi/an…

Synchronous public number [open Ken]