Fix issue #6968859: home not exiting an ANR'd dream
Add a new call to the activity manager for the input dispatcher
to report about any pid having an ANR. This has a new feature
where it can also tell the activity manager that it is above the
system alert layer, so the activity manager can pop its ANR dialog
on top of everything if it needs to. (Normally we don't want
these dialogs appearing on top of the lock screen.)
Also fixed some debugging stuff here and there that was useful
as I was working on this -- windows now very clearly include
their uid, various system dialogs now have titles so you know
what they are in the window manager, etc.
Change-Id: Ib8f5d29a5572542cc506e6d338599ab64088ce4e
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e90eef9..3ef6767 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -970,7 +970,8 @@
if (mShowDialogs) {
Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
- mContext, proc, (ActivityRecord)data.get("activity"));
+ mContext, proc, (ActivityRecord)data.get("activity"),
+ msg.arg1 != 0);
d.show();
proc.anrDialog = d;
} else {
@@ -3247,7 +3248,7 @@
}
final void appNotResponding(ProcessRecord app, ActivityRecord activity,
- ActivityRecord parent, final String annotation) {
+ ActivityRecord parent, boolean aboveSystem, final String annotation) {
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
@@ -3388,6 +3389,7 @@
HashMap map = new HashMap();
msg.what = SHOW_NOT_RESPONDING_MSG;
msg.obj = map;
+ msg.arg1 = aboveSystem ? 1 : 0;
map.put("app", app);
if (activity != null) {
map.put("activity", activity);
@@ -7340,6 +7342,51 @@
SystemProperties.set("ctl.start", "bugreport");
}
+ public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
+ if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires permission "
+ + android.Manifest.permission.FILTER_EVENTS);
+ }
+
+ ProcessRecord proc;
+
+ // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
+ synchronized (this) {
+ synchronized (mPidsSelfLocked) {
+ proc = mPidsSelfLocked.get(pid);
+ }
+ if (proc != null) {
+ if (proc.debugging) {
+ return -1;
+ }
+
+ if (mDidDexOpt) {
+ // Give more time since we were dexopting.
+ mDidDexOpt = false;
+ return -1;
+ }
+
+ if (proc.instrumentationClass != null) {
+ Bundle info = new Bundle();
+ info.putString("shortMsg", "keyDispatchingTimedOut");
+ info.putString("longMsg", "Timed out while dispatching key event");
+ finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
+ proc = null;
+ }
+ }
+ }
+
+ if (proc != null) {
+ appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
+ if (proc.instrumentationClass != null || proc.usingWrapper) {
+ return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
+ }
+ }
+
+ return KEY_DISPATCHING_TIMEOUT;
+ }
+
public void registerProcessObserver(IProcessObserver observer) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"registerProcessObserver()");