summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/TimeoutRecord.java7
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java23
2 files changed, 29 insertions, 1 deletions
diff --git a/core/java/com/android/internal/os/TimeoutRecord.java b/core/java/com/android/internal/os/TimeoutRecord.java
index a0e29347d07f..f8a5520c26d5 100644
--- a/core/java/com/android/internal/os/TimeoutRecord.java
+++ b/core/java/com/android/internal/os/TimeoutRecord.java
@@ -58,6 +58,7 @@ public class TimeoutRecord {
int APP_REGISTERED = 7;
int SHORT_FGS_TIMEOUT = 8;
int JOB_SERVICE = 9;
+ int APP_START = 10;
}
/** Kind of timeout, e.g. BROADCAST_RECEIVER, etc. */
@@ -186,4 +187,10 @@ public class TimeoutRecord {
public static TimeoutRecord forJobService(String reason) {
return TimeoutRecord.endingNow(TimeoutKind.JOB_SERVICE, reason);
}
+
+ /** Record for app startup timeout. */
+ @NonNull
+ public static TimeoutRecord forAppStart(String reason) {
+ return TimeoutRecord.endingNow(TimeoutKind.APP_START, reason);
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7ba720eedfba..81858ee6e2c9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -559,6 +559,10 @@ public class ActivityManagerService extends IActivityManager.Stub
// How long we wait for a launched process to attach to the activity manager
// before we decide it's never going to come up for real.
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;
+
// How long we wait to kill an application zygote, after the last process using
// it has gone away.
static final int KILL_APP_ZYGOTE_DELAY_MS = 5 * 1000;
@@ -1624,6 +1628,7 @@ 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 FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1976,6 +1981,16 @@ 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));
+ } break;
}
}
}
@@ -4734,6 +4749,12 @@ public class ActivityManagerService extends IActivityManager.Stub
app.getDisabledCompatChanges(), serializedSystemFontMap,
app.getStartElapsedTime(), app.getStartUptime());
}
+
+ Message msg = mHandler.obtainMessage(BIND_APPLICATION_TIMEOUT_MSG);
+ msg.obj = app;
+ mHandler.sendMessageDelayed(msg, BIND_APPLICATION_TIMEOUT);
+ mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
+
if (profilerInfo != null) {
profilerInfo.closeFd();
profilerInfo = null;
@@ -4808,7 +4829,7 @@ public class ActivityManagerService extends IActivityManager.Stub
}
if (app != null && app.getStartUid() == uid && app.getStartSeq() == startSeq) {
- mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
+ mHandler.removeMessages(BIND_APPLICATION_TIMEOUT_MSG, app);
} else {
Slog.wtf(TAG, "Mismatched or missing ProcessRecord: " + app + ". Pid: " + pid
+ ". Uid: " + uid);