Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +21 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 % private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25% private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100% private static final long DEFAULT_PROCESS_KILL_TIMEOUT_MS = 10 * 1000; static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000; static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000; Loading Loading @@ -286,6 +287,11 @@ final class ActivityManagerConstants extends ContentObserver { private static final String KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR = "push_messaging_over_quota_behavior"; /** * Time in milliseconds; the allowed duration from a process is killed until it's really gone. */ private static final String KEY_PROCESS_KILL_TIMEOUT = "process_kill_timeout"; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -565,6 +571,11 @@ final class ActivityManagerConstants extends ContentObserver { volatile long mKillBgRestrictedAndCachedIdleSettleTimeMs = DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS; /** * The allowed duration from a process is killed until it's really gone. */ volatile long mProcessKillTimeoutMs = DEFAULT_PROCESS_KILL_TIMEOUT_MS; /** * Whether to allow "opt-out" from the foreground service restrictions. * (https://developer.android.com/about/versions/12/foreground-services) Loading Loading @@ -828,6 +839,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_COMPONENT_ALIAS_OVERRIDES: updateComponentAliases(); break; case KEY_PROCESS_KILL_TIMEOUT: updateProcessKillTimeout(); break; default: break; } Loading Loading @@ -1271,6 +1285,13 @@ final class ActivityManagerConstants extends ContentObserver { mService.mComponentAliasResolver.update(mEnableComponentAlias, mComponentAliasOverrides); } private void updateProcessKillTimeout() { mProcessKillTimeoutMs = DeviceConfig.getLong( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_PROCESS_KILL_TIMEOUT, DEFAULT_PROCESS_KILL_TIMEOUT_MS); } private void updateImperceptibleKillExemptions() { IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear(); IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages); Loading services/core/java/com/android/server/am/ActivityManagerService.java +53 −16 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSER import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.MemoryStatUtil.hasMemcg; import static com.android.server.am.ProcessList.ProcStartHandler; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; Loading Loading @@ -1502,7 +1503,7 @@ public class ActivityManagerService extends IActivityManager.Stub final MainHandler mHandler; final Handler mUiHandler; final ServiceThread mProcStartHandlerThread; final Handler mProcStartHandler; final ProcStartHandler mProcStartHandler; ActivityManagerConstants mConstants; Loading Loading @@ -1691,7 +1692,7 @@ public class ActivityManagerService extends IActivityManager.Stub case PROC_START_TIMEOUT_MSG: { ProcessRecord app = (ProcessRecord) msg.obj; synchronized (ActivityManagerService.this) { processStartTimedOutLocked(app); handleProcessStartOrKillTimeoutLocked(app, /* isKillTimeout */ false); } } break; case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: { Loading Loading @@ -2261,7 +2262,7 @@ public class ActivityManagerService extends IActivityManager.Stub mProcStartHandlerThread = new ServiceThread(TAG + ":procStart", THREAD_PRIORITY_FOREGROUND, false /* allowIo */); mProcStartHandlerThread.start(); mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper()); mProcStartHandler = new ProcStartHandler(this, mProcStartHandlerThread.getLooper()); mConstants = new ActivityManagerConstants(mContext, this, mHandler); final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */); Loading Loading @@ -4254,48 +4255,78 @@ public class ActivityManagerService extends IActivityManager.Stub } @GuardedBy("this") private final void processStartTimedOutLocked(ProcessRecord app) { void handleProcessStartOrKillTimeoutLocked(ProcessRecord app, boolean isKillTimeout) { final int pid = app.getPid(); boolean gone = removePidIfNoThreadLocked(app); boolean gone = isKillTimeout || removePidIfNoThreadLocked(app); if (gone) { if (isKillTimeout) { // It's still alive... maybe blocked at uninterruptible sleep ? final ProcessRecord successor = app.mSuccessor; Slog.wtf(TAG, app.toString() + " " + app.getDyingPid() + " refused to die while trying to launch " + successor + ", cancelling the process start"); // It doesn't make sense to proceed with launching the new instance while the old // instance is still alive, abort the launch. app.mSuccessorStartRunnable = null; app.mSuccessor = null; successor.mPredecessor = null; // We're going to cleanup the successor process record, which wasn't started at all. app = successor; } else { Slog.w(TAG, "Process " + app + " failed to attach"); EventLogTags.writeAmProcessStartTimeout(app.userId, pid, app.uid, app.processName); } synchronized (mProcLock) { mProcessList.removeProcessNameLocked(app.processName, app.uid); mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController()); mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); // Take care of any launching providers waiting for this process. mCpHelper.cleanupAppInLaunchingProvidersLocked(app, true); // Take care of any services that are waiting for the process. mServices.processStartTimedOutLocked(app); app.killLocked("start timeout", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, true); if (!isKillTimeout) { mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); app.killLocked("start timeout", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, true); removeLruProcessLocked(app); } if (app.isolated) { mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); mProcessList.mAppExitInfoTracker.mIsolatedUidRecords.removeIsolatedUid( app.uid, app.info.uid); getPackageManagerInternal().removeIsolatedUid(app.uid); } removeLruProcessLocked(app); } final BackupRecord backupTarget = mBackupTargets.get(app.userId); if (backupTarget != null && backupTarget.app.getPid() == pid) { if (!isKillTimeout && backupTarget != null && backupTarget.app.getPid() == pid) { Slog.w(TAG, "Unattached app died before backup, skipping"); final int userId = app.userId; final String packageName = app.info.packageName; mHandler.post(new Runnable() { @Override public void run(){ try { IBackupManager bm = IBackupManager.Stub.asInterface( ServiceManager.getService(Context.BACKUP_SERVICE)); bm.agentDisconnectedForUser(app.userId, app.info.packageName); bm.agentDisconnectedForUser(userId, packageName); } catch (RemoteException e) { // Can't happen; the backup manager is local } } }); } if (!isKillTimeout) { if (isPendingBroadcastProcessLocked(pid)) { Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); skipPendingBroadcastLocked(pid); } } else { if (isPendingBroadcastProcessLocked(app)) { skipCurrentReceiverLocked(app); } } } else { Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); } Loading Loading @@ -12394,6 +12425,12 @@ public class ActivityManagerService extends IActivityManager.Stub || mOffloadBroadcastQueue.isPendingBroadcastProcessLocked(pid); } boolean isPendingBroadcastProcessLocked(ProcessRecord app) { return mFgBroadcastQueue.isPendingBroadcastProcessLocked(app) || mBgBroadcastQueue.isPendingBroadcastProcessLocked(app) || mOffloadBroadcastQueue.isPendingBroadcastProcessLocked(app); } void skipPendingBroadcastLocked(int pid) { Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); for (BroadcastQueue queue : mBroadcastQueues) { services/core/java/com/android/server/am/AppExitInfoTracker.java +14 −0 Original line number Diff line number Diff line Loading @@ -1507,6 +1507,20 @@ public final class AppExitInfoTracker { } } void removeIsolatedUid(int isolatedUid, int uid) { synchronized (mLock) { final int index = mUidToIsolatedUidMap.indexOfKey(uid); if (index >= 0) { final ArraySet<Integer> set = mUidToIsolatedUidMap.valueAt(index); set.remove(isolatedUid); if (set.isEmpty()) { mUidToIsolatedUidMap.removeAt(index); } } mIsolatedUidToUidMap.remove(isolatedUid); } } @GuardedBy("mLock") Integer getUidByIsolatedUid(int isolatedUid) { if (UserHandle.isIsolated(isolatedUid)) { Loading services/core/java/com/android/server/am/BroadcastQueue.java +4 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,10 @@ public final class BroadcastQueue { return mPendingBroadcast != null && mPendingBroadcast.curApp.getPid() == pid; } boolean isPendingBroadcastProcessLocked(ProcessRecord app) { return mPendingBroadcast != null && mPendingBroadcast.curApp == app; } public void enqueueParallelBroadcastLocked(BroadcastRecord r) { mParallelBroadcasts.add(r); enqueueBroadcastHelper(r); Loading services/core/java/com/android/server/am/PhantomProcessRecord.java +2 −2 Original line number Diff line number Diff line Loading @@ -122,7 +122,7 @@ public final class PhantomProcessRecord { // We'll notify the listener when we're notified it's dead. // Meanwhile, we'd also need handle the case of zombie processes. mKillHandler.postDelayed(mProcKillTimer, this, ProcessList.PROC_KILL_TIMEOUT); mService.mConstants.mProcessKillTimeoutMs); } Process.killProcessQuiet(mPid); ProcessList.killProcessGroup(mUid, mPid); Loading @@ -138,7 +138,7 @@ public final class PhantomProcessRecord { synchronized (mLock) { // The process is maybe in either D or Z state. Slog.w(TAG, "Process " + toString() + " is still alive after " + ProcessList.PROC_KILL_TIMEOUT + "ms"); + mService.mConstants.mProcessKillTimeoutMs + "ms"); // Force a cleanup as we can't keep the fd open forever mZombie = true; onProcDied(false); Loading Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +21 −0 Original line number Diff line number Diff line Loading @@ -169,6 +169,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 % private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25% private static final float DEFAULT_FGS_START_DENIED_LOG_SAMPLE_RATE = 1; // 100% private static final long DEFAULT_PROCESS_KILL_TIMEOUT_MS = 10 * 1000; static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60 * 1000; static final long DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS = 60 * 1000; Loading Loading @@ -286,6 +287,11 @@ final class ActivityManagerConstants extends ContentObserver { private static final String KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR = "push_messaging_over_quota_behavior"; /** * Time in milliseconds; the allowed duration from a process is killed until it's really gone. */ private static final String KEY_PROCESS_KILL_TIMEOUT = "process_kill_timeout"; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -565,6 +571,11 @@ final class ActivityManagerConstants extends ContentObserver { volatile long mKillBgRestrictedAndCachedIdleSettleTimeMs = DEFAULT_KILL_BG_RESTRICTED_CACHED_IDLE_SETTLE_TIME_MS; /** * The allowed duration from a process is killed until it's really gone. */ volatile long mProcessKillTimeoutMs = DEFAULT_PROCESS_KILL_TIMEOUT_MS; /** * Whether to allow "opt-out" from the foreground service restrictions. * (https://developer.android.com/about/versions/12/foreground-services) Loading Loading @@ -828,6 +839,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_COMPONENT_ALIAS_OVERRIDES: updateComponentAliases(); break; case KEY_PROCESS_KILL_TIMEOUT: updateProcessKillTimeout(); break; default: break; } Loading Loading @@ -1271,6 +1285,13 @@ final class ActivityManagerConstants extends ContentObserver { mService.mComponentAliasResolver.update(mEnableComponentAlias, mComponentAliasOverrides); } private void updateProcessKillTimeout() { mProcessKillTimeoutMs = DeviceConfig.getLong( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_PROCESS_KILL_TIMEOUT, DEFAULT_PROCESS_KILL_TIMEOUT_MS); } private void updateImperceptibleKillExemptions() { IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.clear(); IMPERCEPTIBLE_KILL_EXEMPT_PACKAGES.addAll(mDefaultImperceptibleKillExemptPackages); Loading
services/core/java/com/android/server/am/ActivityManagerService.java +53 −16 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSER import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; import static com.android.server.am.MemoryStatUtil.hasMemcg; import static com.android.server.am.ProcessList.ProcStartHandler; import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP; import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; Loading Loading @@ -1502,7 +1503,7 @@ public class ActivityManagerService extends IActivityManager.Stub final MainHandler mHandler; final Handler mUiHandler; final ServiceThread mProcStartHandlerThread; final Handler mProcStartHandler; final ProcStartHandler mProcStartHandler; ActivityManagerConstants mConstants; Loading Loading @@ -1691,7 +1692,7 @@ public class ActivityManagerService extends IActivityManager.Stub case PROC_START_TIMEOUT_MSG: { ProcessRecord app = (ProcessRecord) msg.obj; synchronized (ActivityManagerService.this) { processStartTimedOutLocked(app); handleProcessStartOrKillTimeoutLocked(app, /* isKillTimeout */ false); } } break; case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: { Loading Loading @@ -2261,7 +2262,7 @@ public class ActivityManagerService extends IActivityManager.Stub mProcStartHandlerThread = new ServiceThread(TAG + ":procStart", THREAD_PRIORITY_FOREGROUND, false /* allowIo */); mProcStartHandlerThread.start(); mProcStartHandler = new Handler(mProcStartHandlerThread.getLooper()); mProcStartHandler = new ProcStartHandler(this, mProcStartHandlerThread.getLooper()); mConstants = new ActivityManagerConstants(mContext, this, mHandler); final ActiveUids activeUids = new ActiveUids(this, true /* postChangesToAtm */); Loading Loading @@ -4254,48 +4255,78 @@ public class ActivityManagerService extends IActivityManager.Stub } @GuardedBy("this") private final void processStartTimedOutLocked(ProcessRecord app) { void handleProcessStartOrKillTimeoutLocked(ProcessRecord app, boolean isKillTimeout) { final int pid = app.getPid(); boolean gone = removePidIfNoThreadLocked(app); boolean gone = isKillTimeout || removePidIfNoThreadLocked(app); if (gone) { if (isKillTimeout) { // It's still alive... maybe blocked at uninterruptible sleep ? final ProcessRecord successor = app.mSuccessor; Slog.wtf(TAG, app.toString() + " " + app.getDyingPid() + " refused to die while trying to launch " + successor + ", cancelling the process start"); // It doesn't make sense to proceed with launching the new instance while the old // instance is still alive, abort the launch. app.mSuccessorStartRunnable = null; app.mSuccessor = null; successor.mPredecessor = null; // We're going to cleanup the successor process record, which wasn't started at all. app = successor; } else { Slog.w(TAG, "Process " + app + " failed to attach"); EventLogTags.writeAmProcessStartTimeout(app.userId, pid, app.uid, app.processName); } synchronized (mProcLock) { mProcessList.removeProcessNameLocked(app.processName, app.uid); mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController()); mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); // Take care of any launching providers waiting for this process. mCpHelper.cleanupAppInLaunchingProvidersLocked(app, true); // Take care of any services that are waiting for the process. mServices.processStartTimedOutLocked(app); app.killLocked("start timeout", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, true); if (!isKillTimeout) { mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); app.killLocked("start timeout", ApplicationExitInfo.REASON_INITIALIZATION_FAILURE, true); removeLruProcessLocked(app); } if (app.isolated) { mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); mProcessList.mAppExitInfoTracker.mIsolatedUidRecords.removeIsolatedUid( app.uid, app.info.uid); getPackageManagerInternal().removeIsolatedUid(app.uid); } removeLruProcessLocked(app); } final BackupRecord backupTarget = mBackupTargets.get(app.userId); if (backupTarget != null && backupTarget.app.getPid() == pid) { if (!isKillTimeout && backupTarget != null && backupTarget.app.getPid() == pid) { Slog.w(TAG, "Unattached app died before backup, skipping"); final int userId = app.userId; final String packageName = app.info.packageName; mHandler.post(new Runnable() { @Override public void run(){ try { IBackupManager bm = IBackupManager.Stub.asInterface( ServiceManager.getService(Context.BACKUP_SERVICE)); bm.agentDisconnectedForUser(app.userId, app.info.packageName); bm.agentDisconnectedForUser(userId, packageName); } catch (RemoteException e) { // Can't happen; the backup manager is local } } }); } if (!isKillTimeout) { if (isPendingBroadcastProcessLocked(pid)) { Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); skipPendingBroadcastLocked(pid); } } else { if (isPendingBroadcastProcessLocked(app)) { skipCurrentReceiverLocked(app); } } } else { Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); } Loading Loading @@ -12394,6 +12425,12 @@ public class ActivityManagerService extends IActivityManager.Stub || mOffloadBroadcastQueue.isPendingBroadcastProcessLocked(pid); } boolean isPendingBroadcastProcessLocked(ProcessRecord app) { return mFgBroadcastQueue.isPendingBroadcastProcessLocked(app) || mBgBroadcastQueue.isPendingBroadcastProcessLocked(app) || mOffloadBroadcastQueue.isPendingBroadcastProcessLocked(app); } void skipPendingBroadcastLocked(int pid) { Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); for (BroadcastQueue queue : mBroadcastQueues) {
services/core/java/com/android/server/am/AppExitInfoTracker.java +14 −0 Original line number Diff line number Diff line Loading @@ -1507,6 +1507,20 @@ public final class AppExitInfoTracker { } } void removeIsolatedUid(int isolatedUid, int uid) { synchronized (mLock) { final int index = mUidToIsolatedUidMap.indexOfKey(uid); if (index >= 0) { final ArraySet<Integer> set = mUidToIsolatedUidMap.valueAt(index); set.remove(isolatedUid); if (set.isEmpty()) { mUidToIsolatedUidMap.removeAt(index); } } mIsolatedUidToUidMap.remove(isolatedUid); } } @GuardedBy("mLock") Integer getUidByIsolatedUid(int isolatedUid) { if (UserHandle.isIsolated(isolatedUid)) { Loading
services/core/java/com/android/server/am/BroadcastQueue.java +4 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,10 @@ public final class BroadcastQueue { return mPendingBroadcast != null && mPendingBroadcast.curApp.getPid() == pid; } boolean isPendingBroadcastProcessLocked(ProcessRecord app) { return mPendingBroadcast != null && mPendingBroadcast.curApp == app; } public void enqueueParallelBroadcastLocked(BroadcastRecord r) { mParallelBroadcasts.add(r); enqueueBroadcastHelper(r); Loading
services/core/java/com/android/server/am/PhantomProcessRecord.java +2 −2 Original line number Diff line number Diff line Loading @@ -122,7 +122,7 @@ public final class PhantomProcessRecord { // We'll notify the listener when we're notified it's dead. // Meanwhile, we'd also need handle the case of zombie processes. mKillHandler.postDelayed(mProcKillTimer, this, ProcessList.PROC_KILL_TIMEOUT); mService.mConstants.mProcessKillTimeoutMs); } Process.killProcessQuiet(mPid); ProcessList.killProcessGroup(mUid, mPid); Loading @@ -138,7 +138,7 @@ public final class PhantomProcessRecord { synchronized (mLock) { // The process is maybe in either D or Z state. Slog.w(TAG, "Process " + toString() + " is still alive after " + ProcessList.PROC_KILL_TIMEOUT + "ms"); + mService.mConstants.mProcessKillTimeoutMs + "ms"); // Force a cleanup as we can't keep the fd open forever mZombie = true; onProcDied(false); Loading