Skip to content

Commit 5fe7e2a

Browse files
author
Dianne Hackborn
committed
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
1 parent f7ee2a0 commit 5fe7e2a

17 files changed

+148
-23
lines changed

core/java/android/app/ActivityManagerNative.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,7 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
17721772
IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
17731773
data.readStrongBinder());
17741774
registerUserSwitchObserver(observer);
1775+
reply.writeNoException();
17751776
return true;
17761777
}
17771778

@@ -1780,12 +1781,24 @@ public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
17801781
IUserSwitchObserver observer = IUserSwitchObserver.Stub.asInterface(
17811782
data.readStrongBinder());
17821783
unregisterUserSwitchObserver(observer);
1784+
reply.writeNoException();
17831785
return true;
17841786
}
17851787

17861788
case REQUEST_BUG_REPORT_TRANSACTION: {
17871789
data.enforceInterface(IActivityManager.descriptor);
17881790
requestBugReport();
1791+
reply.writeNoException();
1792+
return true;
1793+
}
1794+
1795+
case INPUT_DISPATCHING_TIMED_OUT_TRANSACTION: {
1796+
data.enforceInterface(IActivityManager.descriptor);
1797+
int pid = data.readInt();
1798+
boolean aboveSystem = data.readInt() != 0;
1799+
long res = inputDispatchingTimedOut(pid, aboveSystem);
1800+
reply.writeNoException();
1801+
reply.writeLong(res);
17891802
return true;
17901803
}
17911804

@@ -4082,5 +4095,19 @@ public void requestBugReport() throws RemoteException {
40824095
reply.recycle();
40834096
}
40844097

4098+
public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException {
4099+
Parcel data = Parcel.obtain();
4100+
Parcel reply = Parcel.obtain();
4101+
data.writeInterfaceToken(IActivityManager.descriptor);
4102+
data.writeInt(pid);
4103+
data.writeInt(aboveSystem ? 1 : 0);
4104+
mRemote.transact(INPUT_DISPATCHING_TIMED_OUT_TRANSACTION, data, reply, 0);
4105+
reply.readException();
4106+
long res = reply.readInt();
4107+
data.recycle();
4108+
reply.recycle();
4109+
return res;
4110+
}
4111+
40854112
private IBinder mRemote;
40864113
}

core/java/android/app/IActivityManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,8 @@ public boolean navigateUpTo(IBinder token, Intent target, int resultCode, Intent
363363

364364
public void requestBugReport() throws RemoteException;
365365

366+
public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
367+
366368
/*
367369
* Private non-Binder interfaces
368370
*/
@@ -616,4 +618,5 @@ private WaitResult(Parcel source) {
616618
int UNREGISTER_USER_SWITCH_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+155;
617619
int GET_RUNNING_USER_IDS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+156;
618620
int REQUEST_BUG_REPORT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+157;
621+
int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
619622
}

policy/src/com/android/internal/policy/impl/GlobalActions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ private void handleShow() {
149149
mDialog = createDialog();
150150
prepareDialog();
151151

152+
WindowManager.LayoutParams attrs = mDialog.getWindow().getAttributes();
153+
attrs.setTitle("GlobalActions");
154+
mDialog.getWindow().setAttributes(attrs);
152155
mDialog.show();
153156
mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND);
154157
}

services/java/com/android/server/am/ActiveServices.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1850,7 +1850,7 @@ void serviceTimeout(ProcessRecord proc) {
18501850
}
18511851

18521852
if (anrMessage != null) {
1853-
mAm.appNotResponding(proc, null, null, anrMessage);
1853+
mAm.appNotResponding(proc, null, null, false, anrMessage);
18541854
}
18551855
}
18561856

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,8 @@ public void handleMessage(Message msg) {
970970

971971
if (mShowDialogs) {
972972
Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
973-
mContext, proc, (ActivityRecord)data.get("activity"));
973+
mContext, proc, (ActivityRecord)data.get("activity"),
974+
msg.arg1 != 0);
974975
d.show();
975976
proc.anrDialog = d;
976977
} else {
@@ -3247,7 +3248,7 @@ final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
32473248
}
32483249

32493250
final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3250-
ActivityRecord parent, final String annotation) {
3251+
ActivityRecord parent, boolean aboveSystem, final String annotation) {
32513252
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
32523253
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
32533254

@@ -3388,6 +3389,7 @@ final void appNotResponding(ProcessRecord app, ActivityRecord activity,
33883389
HashMap map = new HashMap();
33893390
msg.what = SHOW_NOT_RESPONDING_MSG;
33903391
msg.obj = map;
3392+
msg.arg1 = aboveSystem ? 1 : 0;
33913393
map.put("app", app);
33923394
if (activity != null) {
33933395
map.put("activity", activity);
@@ -7340,6 +7342,51 @@ public void requestBugReport() {
73407342
SystemProperties.set("ctl.start", "bugreport");
73417343
}
73427344

7345+
public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7346+
if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7347+
!= PackageManager.PERMISSION_GRANTED) {
7348+
throw new SecurityException("Requires permission "
7349+
+ android.Manifest.permission.FILTER_EVENTS);
7350+
}
7351+
7352+
ProcessRecord proc;
7353+
7354+
// TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7355+
synchronized (this) {
7356+
synchronized (mPidsSelfLocked) {
7357+
proc = mPidsSelfLocked.get(pid);
7358+
}
7359+
if (proc != null) {
7360+
if (proc.debugging) {
7361+
return -1;
7362+
}
7363+
7364+
if (mDidDexOpt) {
7365+
// Give more time since we were dexopting.
7366+
mDidDexOpt = false;
7367+
return -1;
7368+
}
7369+
7370+
if (proc.instrumentationClass != null) {
7371+
Bundle info = new Bundle();
7372+
info.putString("shortMsg", "keyDispatchingTimedOut");
7373+
info.putString("longMsg", "Timed out while dispatching key event");
7374+
finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7375+
proc = null;
7376+
}
7377+
}
7378+
}
7379+
7380+
if (proc != null) {
7381+
appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7382+
if (proc.instrumentationClass != null || proc.usingWrapper) {
7383+
return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7384+
}
7385+
}
7386+
7387+
return KEY_DISPATCHING_TIMEOUT;
7388+
}
7389+
73437390
public void registerProcessObserver(IProcessObserver observer) {
73447391
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
73457392
"registerProcessObserver()");

services/java/com/android/server/am/ActivityRecord.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ private ActivityRecord getWaitingHistoryRecordLocked() {
841841
}
842842

843843
public boolean keyDispatchingTimedOut() {
844+
// TODO: Unify this code with ActivityManagerService.inputDispatchingTimedOut().
844845
ActivityRecord r;
845846
ProcessRecord anrApp = null;
846847
synchronized(service) {
@@ -869,8 +870,7 @@ public boolean keyDispatchingTimedOut() {
869870
}
870871

871872
if (anrApp != null) {
872-
service.appNotResponding(anrApp, r, this,
873-
"keyDispatchingTimedOut");
873+
service.appNotResponding(anrApp, r, this, false, "keyDispatchingTimedOut");
874874
}
875875

876876
return true;

services/java/com/android/server/am/ActivityStack.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2436,8 +2436,8 @@ final int startActivityLocked(IApplicationThread caller,
24362436

24372437
if (err == ActivityManager.START_SUCCESS) {
24382438
final int userId = aInfo != null ? UserHandle.getUserId(aInfo.applicationInfo.uid) : 0;
2439-
Slog.i(TAG, "START {" + intent.toShortString(true, true, true, false)
2440-
+ " u=" + userId + "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
2439+
Slog.i(TAG, "START u" + userId + " {" + intent.toShortString(true, true, true, false)
2440+
+ "} from pid " + (callerApp != null ? callerApp.pid : callingPid));
24412441
}
24422442

24432443
ActivityRecord sourceRecord = null;

services/java/com/android/server/am/AppErrorDialog.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@
2323
import android.content.res.Resources;
2424
import android.os.Handler;
2525
import android.os.Message;
26-
import android.util.Slog;
2726
import android.view.WindowManager;
2827

2928
class AppErrorDialog extends BaseErrorDialog {
30-
private final static String TAG = "AppErrorDialog";
31-
3229
private final ActivityManagerService mService;
3330
private final AppErrorResult mResult;
3431
private final ProcessRecord mProc;
@@ -76,7 +73,9 @@ public AppErrorDialog(Context context, ActivityManagerService service,
7673

7774
setTitle(res.getText(com.android.internal.R.string.aerr_title));
7875
getWindow().addFlags(FLAG_SYSTEM_ERROR);
79-
getWindow().setTitle("Application Error: " + app.info.processName);
76+
WindowManager.LayoutParams attrs = getWindow().getAttributes();
77+
attrs.setTitle("Application Error: " + app.info.processName);
78+
getWindow().setAttributes(attrs);
8079
if (app.persistent) {
8180
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
8281
}

services/java/com/android/server/am/AppNotRespondingDialog.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import android.content.res.Resources;
2626
import android.os.Handler;
2727
import android.os.Message;
28-
import android.os.Process;
2928
import android.util.Slog;
29+
import android.view.WindowManager;
3030

3131
class AppNotRespondingDialog extends BaseErrorDialog {
3232
private static final String TAG = "AppNotRespondingDialog";
@@ -40,7 +40,7 @@ class AppNotRespondingDialog extends BaseErrorDialog {
4040
private final ProcessRecord mProc;
4141

4242
public AppNotRespondingDialog(ActivityManagerService service, Context context,
43-
ProcessRecord app, ActivityRecord activity) {
43+
ProcessRecord app, ActivityRecord activity, boolean aboveSystem) {
4444
super(context);
4545

4646
mService = service;
@@ -91,8 +91,13 @@ public AppNotRespondingDialog(ActivityManagerService service, Context context,
9191
}
9292

9393
setTitle(res.getText(com.android.internal.R.string.anr_title));
94+
if (aboveSystem) {
95+
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
96+
}
9497
getWindow().addFlags(FLAG_SYSTEM_ERROR);
95-
getWindow().setTitle("Application Not Responding: " + app.info.processName);
98+
WindowManager.LayoutParams attrs = getWindow().getAttributes();
99+
attrs.setTitle("Application Not Responding: " + app.info.processName);
100+
getWindow().setAttributes(attrs);
96101
}
97102

98103
public void onStop() {

services/java/com/android/server/am/AppWaitingForDebuggerDialog.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import android.content.DialogInterface;
2121
import android.os.Handler;
2222
import android.os.Message;
23+
import android.view.WindowManager;
2324

2425
class AppWaitingForDebuggerDialog extends BaseErrorDialog {
2526
final ActivityManagerService mService;
@@ -52,7 +53,9 @@ public AppWaitingForDebuggerDialog(ActivityManagerService service,
5253
setMessage(text.toString());
5354
setButton(DialogInterface.BUTTON_POSITIVE, "Force Close", mHandler.obtainMessage(1, app));
5455
setTitle("Waiting For Debugger");
55-
getWindow().setTitle("Waiting For Debugger: " + app.info.processName);
56+
WindowManager.LayoutParams attrs = getWindow().getAttributes();
57+
attrs.setTitle("Waiting For Debugger: " + app.info.processName);
58+
getWindow().setAttributes(attrs);
5659
}
5760

5861
public void onStop() {

0 commit comments

Comments
 (0)