ActivityManagerService (ActivityManagerService, ActivityManagerService, ActivityManagerService)
Today we will look at the startup of ActivityManageerService, which will be referred to as AMS for short.
Start the AMS
The startup of AMS occurs during the BootPhase 0 phase of the SystemServer startup process.
In the start service of the three classification services, the startBootstrapServices method
private void startBootstrapServices() { ... ActivityTaskManagerService atm = mSystemServiceManager.startService( ActivityTaskManagerService.Lifecycle.class).getService(); mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); mActivityManagerService.setSystemServiceManager(mSystemServiceManager); mActivityManagerService.setInstaller(installer); mWindowManagerGlobalLock = atm.getGlobalLock(); . }Copy the code
AMS’s is created through AMS’s internal class Lifecycle, with a call to Lifecycle.onstart () to start AMS.
public static final class Lifecycle extends SystemService { private final ActivityManagerService mService; private static ActivityTaskManagerService sAtm; public Lifecycle(Context context) { super(context); mService = new ActivityManagerService(context, sAtm); } public static ActivityManagerService startService( SystemServiceManager ssm, ActivityTaskManagerService atm) { sAtm = atm; return ssm.startService(ActivityManagerService.Lifecycle.class).getService(); } @Override public void onStart() { mService.start(); }... }Copy the code
Lifecycle inherits from SystemService and starts the Service through the SSM (SystemServiceManager).
Internally Lifecycle instances are created through reflection and AMS is created during Lifecycle instances.
So what do we do when we instantiate AMS
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) { ... // Create a thread named ActivityManager, Create MainHandler // thread to handle various state information (GC, Service_TIMEOUT, update_TIME_zone, kill_application, kill_zygote) mHandlerThread = new ServiceThread(TAG, THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); mHandlerThread.start(); mHandler = new MainHandler(mHandlerThread.getLooper()); // getUiHandler mUiHandler = minector. GetUiHandler (this); MProcStartHandlerThread = new ServiceThread(TAG + ":procStart", THREAD_PRIORITY_FOREGROUND, false /* allowIo */); mProcStartHandlerThread.start(); mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper()); MConstants = new ActivityManagerConstants(mContext, this, mHandler); ActiveUids ActiveUids = new ActiveUids(this, true /* postChangesToAtm */); mProcessList.init(this, activeUids); // mLowMemDetector = new LowMemDetector(this); mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids); / / the foreground radio receiver final BroadcastConstants foreConstants = new BroadcastConstants (Settings. Global. BROADCAST_FG_CONSTANTS); foreConstants.TIMEOUT = BROADCAST_FG_TIMEOUT; / / the background radio receiver final BroadcastConstants backConstants = new BroadcastConstants (Settings. Global. BROADCAST_BG_CONSTANTS); backConstants.TIMEOUT = BROADCAST_BG_TIMEOUT; Final BroadcastConstants offloadConstants = new BroadcastConstants( Settings.Global.BROADCAST_OFFLOAD_CONSTANTS); offloadConstants.TIMEOUT = BROADCAST_BG_TIMEOUT; offloadConstants.SLOW_TIME = Integer.MAX_VALUE; mEnableOffloadQueue = SystemProperties.getBoolean( "persist.device_config.activity_manager_native_boot.offload_queue_enabled", false); 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; mServices = new ActiveServices(this); mProviderMap = new ProviderMap(this); mPackageWatchdog = PackageWatchdog.getInstance(mUiContext); mAppErrors = new AppErrors(mUiContext, this, mPackageWatchdog); final File systemDir = SystemServiceManager.ensureSystemDir(); MBatteryStatsService = new BatteryStatsService(systemContext, systemDir, backgroundThread.get ().gethandler ())); mBatteryStatsService.getActiveStatistics().readLocked(); mBatteryStatsService.scheduleWriteToDisk(); mOnBattery = DEBUG_POWER ? true : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); mBatteryStatsService.getActiveStatistics().setCallback(this); mOomAdjProfiler.batteryPowerChanged(mOnBattery); MProcessStats = new ProcessStatsService(this, new File(systemDir, "procStats ")); mAppOpsService = mInjector.getAppOpsService(new File(systemDir, "appops.xml"), mHandler); . mActivityTaskManager = atm; mActivityTaskManager.initialize(mIntentFirewall, mPendingIntentController, DisplayThread.get().getLooper()); mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class); MProcessCpuThread = new Thread("CpuTracker") {@override public void run() {synchronized (mProcessCpuTracker) { mProcessCpuInitLatch.countDown(); mProcessCpuTracker.init(); } while (true) { try { try { synchronized(this) { final long now = SystemClock.uptimeMillis(); long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; //Slog.i(TAG, "Cpu delay=" + nextCpuDelay // + ", write delay=" + nextWriteDelay); if (nextWriteDelay < nextCpuDelay) { nextCpuDelay = nextWriteDelay; } if (nextCpuDelay > 0) { mProcessCpuMutexFree.set(true); this.wait(nextCpuDelay); }} catch (InterruptedException e) {} // Update CPU information updateCpuStatsNow(); } catch (Exception e) { Slog.e(TAG, "Unexpected exception collecting process stats", e); }}}}; . }Copy the code
So the main thing to do here is to create ActivityManager, Proc, and CpuTracker threads; Create the corresponding broadcast receiver at the same time.
After an AMS instance is created, the start() method is called to start AMS
Private void start() {removeAllProcessGroups(); Mprocesscputhread.start (); / / start battery statistics service mBatteryStatsService. The publish (); mAppOpsService.publish(mContext); / / added to the local LocalServices LocalServices. The addService (ActivityManagerInternal. Class, new LocalService ()); mActivityTaskManager.onActivityManagerInternalAdded(); mUgmInternal.onActivityManagerInternalAdded(); mPendingIntentController.onActivityManagerInternalAdded(); Try {/ / wait for the process CPU statistics thread running mProcessCpuInitLatch. Await (); } catch (InterruptedException e) { Slog.wtf(TAG, "Interrupted wait during start", e); Thread.currentThread().interrupt(); throw new IllegalStateException("Interrupted wait during start"); }}Copy the code
At this point, AMS is already up and running.
What AMS does in SystemServer
startBootstrapServices
private void startBootstrapServices() { ... mActivityManagerService.initPowerManagement(); . mActivityManagerService.setSystemProcess(); . }Copy the code
initPowerManagement
PowerManagement is initialized first
public void initPowerManagement() {
mActivityTaskManager.onInitPowerManagement();
mBatteryStatsService.initPowerManagement();
mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
}
Copy the code
PowerManagement will eventually be initialized via BatterStateService.
setSystemProcess
Next comes setSystemProcess, which registers the related services.
Public void setSystemProcess () {try {/ / registered ActivityManagerService ServiceManager. The addService (Context) ACTIVITY_SERVICE, this, /* allowIsolated= */ true, DUMP_FLAG_PRIORITY_CRITICAL | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO); / / registered ProcessStatsService ServiceManager. The addService (ProcessStats SERVICE_NAME, mProcessStats); / / registered MemBinder ServiceManager. The addService (" meminfo, "new MemBinder (this), allowIsolated = / * * / false, DUMP_FLAG_PRIORITY_HIGH); / / registered GraphicsBinder ServiceManager. The addService (" gfxinfo ", new GraphicsBinder (this)); / / registered DbBinder ServiceManager. The addService (" dbinfo ", new DbBinder (this)); If (MONITOR_CPU_USAGE) {/ / registered CpuBinder ServiceManager. The addService (" cpuinfo, "new CpuBinder (this), /* allowIsolated= */ false, DUMP_FLAG_PRIORITY_CRITICAL); } / / registered PermissionController ServiceManager. The addService (" permission ", new PermissionController (this)); / / registered ProcessInfoService ServiceManager. The addService (" processinfo ", new ProcessInfoService (this)); // Load the package named Android, Finally to load by LoadedApk ApplicationInfo info = mContext. GetPackageManager (). GetApplicationInfo (" android ", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY); mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); . }Copy the code
Note that the AMS is registered with the ServiceManager, and then the registered AMS is retrieved through the ActivityManager.
Next, you enter startCoreServices to start the core service
startCoreServices
private void startCoreServices() { ... mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); . }Copy the code
The thing to do here is very simple, set up the UsageStateManager
startOtherServices
Proceed to start the other service modules
private void startOtherServices() { ... mActivityManagerService.installSystemProviders(); mActivityManagerService.setWindowManager(wm); mActivityManagerService.systemReady(...) . }Copy the code
The main work here is to install the system Provider and set up WindowManagerService and systemReady.
installSystemProviders
public final void installSystemProviders() { List<ProviderInfo> providers; synchronized (this) { ProcessRecord app = mProcessList.mProcessNames.get("system", SYSTEM_UID); / / get will will = generateApplicationProvidersLocked (app); if (providers ! = null) { for (int i=providers.size()-1; i>=0; i--) { ProviderInfo pi = (ProviderInfo)providers.get(i); If ((pi.applicationInfo. flags&applicationInfo. FLAG_SYSTEM) == 0) {Providers. Remove (I); }}}} // Install the system's Providers via ActivityThread. = null) { mSystemThread.installSystemProviders(providers); } synchronized (this) { mSystemProvidersInstalled = true; } mConstants.start(mContext.getContentResolver()); mCoreSettingsObserver = new CoreSettingsObserver(this); mActivityTaskManager.installSystemProviders(); mDevelopmentSettingsObserver = new DevelopmentSettingsObserver(); SettingsToPropertiesMapper.start(mContext.getContentResolver()); mOomAdjuster.initSettings(); }Copy the code
The main task here is to install the system Providers
WindowManagerService
public void setWindowManager(WindowManagerService wm) { synchronized (this) { mWindowManager = wm; mActivityTaskManager.setWindowManager(wm); }}Copy the code
Set up the WindowManagerService service
systemReady
SystemReady has a lot of logic, so let’s break it down
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { goingCallback before if (goingCallback ! = null) goingCallback.run(); goingCallback after }Copy the code
Before calling goingcallback.run
Public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {synchronized(this) { Skip if (mSystemReady) {if (goingCallback! = null) { goingCallback.run(); } return; }... mSystemReady = true; }... ArrayList<ProcessRecord> procsToKill = null; synchronized(mPidsSelfLocked) { for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { ProcessRecord proc = mPidsSelfLocked.valueAt(i); // non-president process if (! isAllowedWhileBooting(proc.info)){ if (procsToKill == null) { procsToKill = new ArrayList<ProcessRecord>(); } // Add procstokill.add (proc); } } } synchronized(this) { if (procsToKill ! = null) {// kill procsToKill process for (int I = procstokill.size ()-1; i>=0; i--) { ProcessRecord proc = procsToKill.get(i); mProcessList.removeProcessLocked(proc, true, false, "system update done"); } } mProcessesReady = true; }... if (goingCallback ! = null) goingCallback.run(); . }Copy the code
The main thing to do is kill the process in procsToKill, at which point the system and process are ready
Goingcallback.run is then called
mActivityManagerService.systemReady(() -> { // BootPhase 550 mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY); try { mActivityManagerService.startObservingNativeCrashes(); } catch (Throwable e) { reportWtf("observing native crashes", e); } traceBeginAndSlog("MakeConnectivityServiceReady"); try { if (connectivityF ! = null) { connectivityF.systemReady(); } } catch (Throwable e) { reportWtf("making Connectivity Service ready", e); }... // BootPhase 600 mSystemServiceManager.startBootPhase( SystemService.PHASE_THIRD_PARTY_APPS_CAN_START); try { if (locationF ! = null) { locationF.systemRunning(); } } catch (Throwable e) { reportWtf("Notifying Location Service running", e); } try { if (countryDetectorF ! = null) { countryDetectorF.systemRunning(); } } catch (Throwable e) { reportWtf("Notifying CountryDetectorService running", e); }... }, BOOT_TIMINGS_TRACE_LOG);Copy the code
This has already been analyzed in the Android SystemServer startup (2), which is not covered here.
It is mainly used for systemReady and systemRuning of some services.
Finally, we come to the last step of systemReady
public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ... if (goingCallback ! = null) goingCallback.run(); final int currentUserId = mUserController.getCurrentUserId(); if (currentUserId ! = UserHandle.USER_SYSTEM && ! mUserController.isSystemUserStarted()) { throw new RuntimeException("System user not started while current user is:" + currentUserId); } mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, Integer.toString(currentUserId), currentUserId); mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, Integer.toString(currentUserId), currentUserId); / / call all SystemService onStartUser method mSystemServiceManager. StartUser (currentUserId); Synchronized (this) {// Enable Persistent app startPersistentApps(packagemanager.match_direct_boot_aware); mBooting = true; if (UserManager.isSplitSystemUser() && Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0) ! = 0) { 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(); }} / / start system desktop Activity mAtmInternal. StartHomeOnAllDisplays (currentUserId "systemReady"); mAtmInternal.showSystemReadyErrorDialogsIfNeeded(); final int callingUid = Binder.getCallingUid(); final int callingPid = Binder.getCallingPid(); long ident = Binder.clearCallingIdentity(); 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); Intent.action_user_starting = new 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); } mAtmInternal.resumeTopActivities(false /* scheduleIdle */); mUserController.sendUserSwitchBroadcasts(-1, currentUserId); BinderInternal.nSetBinderProxyCountWatermarks(BINDER_PROXY_HIGH_WATERMARK, BINDER_PROXY_LOW_WATERMARK); BinderInternal.nSetBinderProxyCountEnabled(true); BinderInternal.setBinderProxyCountCallback( new BinderInternal.BinderProxyLimitListener() { @Override public void onLimitReached(int uid) { Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " + Process.myUid()); BinderProxy.dumpProxyDebugInfo(); if (uid == Process.SYSTEM_UID) { Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); } else { killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), "Too many Binders sent to SYSTEM"); } } }, mHandler); . / / the Activity recovery stack mAtmInternal resumeTopActivities (false scheduleIdle / * * /); / / send User_SWITCH radio mUserController. SendUserSwitchBroadcasts (1, currentUserId); . }}Copy the code
StartUser calls back to the previous SystemService onStartUser method
public void startUser(final int userHandle) { final int serviceLen = mServices.size(); MServices for (int I = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "onStartUser " + service.getClass().getName()); long time = SystemClock.elapsedRealtime(); Try {// Callback onStartUser service.onStartUser(userHandle); } catch (Exception ex) { Slog.wtf(TAG, "Failure reporting start of user " + userHandle + " to service " + service.getClass().getName(), ex); }}}Copy the code
Starthome all displays will eventually come to the startHomeOnDisplay method of RootActivityContainer
boolean startHomeOnDisplay(int userId, String reason, int displayId, boolean allowInstrumenting, boolean fromHomeKey) { if (displayId == INVALID_DISPLAY) { displayId = getTopDisplayFocusedStack().mDisplayId; } Intent homeIntent = null; ActivityInfo aInfo = null; if (displayId == DEFAULT_DISPLAY) { homeIntent = mService.getHomeIntent(); aInfo = resolveHomeActivity(userId, homeIntent); } else if (shouldPlaceSecondaryHomeOnDisplay(displayId)) { Pair<ActivityInfo, Intent> info = resolveSecondaryHomeActivity(userId, displayId); aInfo = info.first; homeIntent = info.second; } if (aInfo == null || homeIntent == null) { return false; } if (! canStartHomeOnDisplay(aInfo, displayId, allowInstrumenting)) { return false; } / / set the home homeIntent. The Intent of Component information setComponent (new the ComponentName (aInfo. ApplicationInfo. PackageName, aInfo.name)); homeIntent.setFlags(homeIntent.getFlags() | FLAG_ACTIVITY_NEW_TASK); / / set up extra if (fromHomeKey) {homeIntent. PutExtra (WindowManagerPolicy EXTRA_FROM_HOME_KEY, true); } final String myReason = reason + ":" + userId + ":" + UserHandle.getUserId( aInfo.applicationInfo.uid) + ":" + displayId; / / start the desktop Activity mService. GetActivityStartController () startHomeActivity (homeIntent aInfo, myReason, displayId); return true; }Copy the code
To summarize, after goingcallback. run, this phase mainly does the following:
- Call all the previously added ones
SystemService
theonStartUser
methods - Start the
Persistent
process - Start the system desktop Activity
- Send USER_STARTED broadcast
- Send a USER_STARTING broadcast
- Resume top of stack Activity
- Sends a User_SWITCH broadcast
This is the whole process of AMS in SystemServer, and also the startup process of AMS.
The main things that the whole process does are:
- through
Lifecycle
createAMS
Instance at the same timeonStart()
Methods to start theAMS
- through
setSystemProcess
registeredAMS
,meminfo
,gfxinfo
,dbinfo
,cpuinfo
And other services toServiceManager
In the - through
installSystemProviders
To load the systemproviders
- through
systemReady
toready
withrunning
Various services simultaneously launch desktop applications, send related broadcasts with restore stack topActivity
Wechat public number: Android supply station, focusing on Android advanced, algorithm and interview analysis, as well as irregular benefits
recommended
Android_startup: Provides a simpler and more efficient way to initialize components at application startup. Developers can use Android-startup to simplify the startup sequence and explicitly set the dependency between the initialization order and the components. Meanwhile, Android-startup supports synchronous and asynchronous wait, and ensures the initialization sequence of internal dependent components by means of directed acyclic topology sorting.
AwesomeGithub: Based on Github client, pure exercise project, support componentized development, support account password and authentication login. Kotlin language for development, the project architecture is based on Jetpack&DataBinding MVVM; Popular open source technologies such as Arouter, Retrofit, Coroutine, Glide, Dagger and Hilt are used in the project.
Flutter_github: a cross-platform Github client based on Flutter, corresponding to AwesomeGithub.
Android-api-analysis: A comprehensive analysis of Knowledge points related to Android with detailed Demo to help readers quickly grasp and understand the main points explained.
Daily_algorithm: advanced algorithm, from shallow to deep, welcome to join us.