diff options
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 58 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ProcessProfileRecord.java | 5 |
2 files changed, 49 insertions, 14 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 19879db1d22e..a97f005f4ebe 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -377,6 +377,7 @@ import android.util.FeatureFlagUtils; import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.Log; +import android.util.MathUtils; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; @@ -562,7 +563,7 @@ public class ActivityManagerService extends IActivityManager.Stub static final int PROC_START_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER; // How long we wait for a launched process to complete its app startup before we ANR. - static final int BIND_APPLICATION_TIMEOUT = 10 * 1000 * Build.HW_TIMEOUT_MULTIPLIER; + static final int BIND_APPLICATION_TIMEOUT = 15 * 1000 * Build.HW_TIMEOUT_MULTIPLIER; // How long we wait to kill an application zygote, after the last process using // it has gone away. @@ -1630,7 +1631,8 @@ public class ActivityManagerService extends IActivityManager.Stub static final int UPDATE_CACHED_APP_HIGH_WATERMARK = 79; static final int ADD_UID_TO_OBSERVER_MSG = 80; static final int REMOVE_UID_FROM_OBSERVER_MSG = 81; - static final int BIND_APPLICATION_TIMEOUT_MSG = 82; + static final int BIND_APPLICATION_TIMEOUT_SOFT_MSG = 82; + static final int BIND_APPLICATION_TIMEOUT_HARD_MSG = 83; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1983,15 +1985,11 @@ public class ActivityManagerService extends IActivityManager.Stub case UPDATE_CACHED_APP_HIGH_WATERMARK: { mAppProfiler.mCachedAppsWatermarkData.updateCachedAppsSnapshot((long) msg.obj); } break; - case BIND_APPLICATION_TIMEOUT_MSG: { - ProcessRecord app = (ProcessRecord) msg.obj; - - final String anrMessage; - synchronized (app) { - anrMessage = "Process " + app + " failed to complete startup"; - } - - mAnrHelper.appNotResponding(app, TimeoutRecord.forAppStart(anrMessage)); + case BIND_APPLICATION_TIMEOUT_SOFT_MSG: { + handleBindApplicationTimeoutSoft((ProcessRecord) msg.obj, msg.arg1); + } break; + case BIND_APPLICATION_TIMEOUT_HARD_MSG: { + handleBindApplicationTimeoutHard((ProcessRecord) msg.obj); } break; } } @@ -4757,6 +4755,7 @@ public class ActivityManagerService extends IActivityManager.Stub mPlatformCompat.resetReporting(app.info); } final ProviderInfoList providerList = ProviderInfoList.fromList(providers); + app.mProfile.mLastCpuDelayTime.set(app.getCpuDelayTime()); if (app.getIsolatedEntryPoint() != null) { // This is an isolated process which should just call an entry point instead of // being bound to an application. @@ -4794,9 +4793,10 @@ public class ActivityManagerService extends IActivityManager.Stub app.getStartElapsedTime(), app.getStartUptime()); } - Message msg = mHandler.obtainMessage(BIND_APPLICATION_TIMEOUT_MSG); + Message msg = mHandler.obtainMessage(BIND_APPLICATION_TIMEOUT_SOFT_MSG); msg.obj = app; - mHandler.sendMessageDelayed(msg, BIND_APPLICATION_TIMEOUT); + msg.arg1 = BIND_APPLICATION_TIMEOUT; + mHandler.sendMessageDelayed(msg, msg.arg1 /* BIND_APPLICATION_TIMEOUT */); mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); if (profilerInfo != null) { @@ -4873,7 +4873,8 @@ public class ActivityManagerService extends IActivityManager.Stub } if (app != null && app.getStartUid() == uid && app.getStartSeq() == startSeq) { - mHandler.removeMessages(BIND_APPLICATION_TIMEOUT_MSG, app); + mHandler.removeMessages(BIND_APPLICATION_TIMEOUT_SOFT_MSG, app); + mHandler.removeMessages(BIND_APPLICATION_TIMEOUT_HARD_MSG, app); } else { Slog.wtf(TAG, "Mismatched or missing ProcessRecord: " + app + ". Pid: " + pid + ". Uid: " + uid); @@ -5010,6 +5011,35 @@ public class ActivityManagerService extends IActivityManager.Stub } } + private void handleBindApplicationTimeoutSoft(ProcessRecord app, int softTimeoutMillis) { + // Similar logic as the broadcast delivery timeout: + // instead of immediately triggering an ANR, extend the timeout by + // the amount of time the process was runnable-but-waiting; we're + // only willing to do this once before triggering an hard ANR. + final long cpuDelayTime = app.getCpuDelayTime() - app.mProfile.mLastCpuDelayTime.get(); + final long hardTimeoutMillis = MathUtils.constrain(cpuDelayTime, 0, softTimeoutMillis); + + if (hardTimeoutMillis == 0) { + handleBindApplicationTimeoutHard(app); + return; + } + + Slog.i(TAG, "Extending process start timeout by " + hardTimeoutMillis + "ms for " + app); + Trace.instant(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplicationTimeSoft " + + app.processName + "(" + app.getPid() + ")"); + final Message msg = mHandler.obtainMessage(BIND_APPLICATION_TIMEOUT_HARD_MSG, app); + mHandler.sendMessageDelayed(msg, hardTimeoutMillis); + } + + private void handleBindApplicationTimeoutHard(ProcessRecord app) { + final String anrMessage; + synchronized (app) { + anrMessage = "Process " + app + " failed to complete startup"; + } + + mAnrHelper.appNotResponding(app, TimeoutRecord.forAppStart(anrMessage)); + } + /** * @return The last part of the string of an intent's action. */ diff --git a/services/core/java/com/android/server/am/ProcessProfileRecord.java b/services/core/java/com/android/server/am/ProcessProfileRecord.java index db74f1aed422..c1f86e0c9bb4 100644 --- a/services/core/java/com/android/server/am/ProcessProfileRecord.java +++ b/services/core/java/com/android/server/am/ProcessProfileRecord.java @@ -142,6 +142,11 @@ final class ProcessProfileRecord { final AtomicLong mCurCpuTime = new AtomicLong(0); /** + * How long the process has spent on waiting in the runqueue since fork. + */ + final AtomicLong mLastCpuDelayTime = new AtomicLong(0); + + /** * Last selected memory trimming level. */ @CompositeRWLock({"mService", "mProcLock"}) |