Make ActivityManagerService just kill apps when they crash on headless devices.
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 5a70dcf..4e1e9d9 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -271,6 +271,11 @@
private final boolean mHeadless;
+ // Whether we should show our dialogs (ANR, crash, etc) or just perform their
+ // default actuion automatically. Important for devices without direct input
+ // devices.
+ private boolean mShowDialogs = true;
+
/**
* Description of a request to start a new activity, which has been held
* due to app switches being disabled.
@@ -1678,7 +1683,7 @@
return;
}
AppErrorResult res = (AppErrorResult) data.get("result");
- if (!mSleeping && !mShuttingDown) {
+ if (mShowDialogs && !mSleeping && !mShuttingDown) {
Dialog d = new AppErrorDialog(mContext, res, proc);
d.show();
proc.crashDialog = d;
@@ -1730,7 +1735,7 @@
return;
}
AppErrorResult res = (AppErrorResult) data.get("result");
- if (!mSleeping && !mShuttingDown) {
+ if (mShowDialogs && !mSleeping && !mShuttingDown) {
Dialog d = new StrictModeViolationDialog(mContext, res, proc);
d.show();
proc.crashDialog = d;
@@ -1852,16 +1857,22 @@
}
} break;
case SHOW_UID_ERROR_MSG: {
- // XXX This is a temporary dialog, no need to localize.
- AlertDialog d = new BaseErrorDialog(mContext);
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
- d.setCancelable(false);
- d.setTitle("System UIDs Inconsistent");
- d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
- d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
- mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
- mUidAlert = d;
- d.show();
+ String title = "System UIDs Inconsistent";
+ String text = "UIDs on the system are inconsistent, you need to wipe your"
+ + " data partition or your device will be unstable.";
+ Log.e(TAG, title + ": " + text);
+ if (mShowDialogs) {
+ // XXX This is a temporary dialog, no need to localize.
+ AlertDialog d = new BaseErrorDialog(mContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setCancelable(false);
+ d.setTitle(title);
+ d.setMessage(text);
+ d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
+ mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
+ mUidAlert = d;
+ d.show();
+ }
} break;
case IM_FEELING_LUCKY_MSG: {
if (mUidAlert != null) {
@@ -13853,6 +13864,10 @@
Slog.i(TAG, "Config changed: " + newConfig);
final Configuration configCopy = new Configuration(mConfiguration);
+
+ // TODO: If our config changes, should we auto dismiss any currently
+ // showing dialogs?
+ mShowDialogs = shouldShowDialogs(newConfig);
AttributeCache ac = AttributeCache.instance();
if (ac != null) {
@@ -13919,6 +13934,19 @@
return kept;
}
+
+ /**
+ * Decide based on the configuration whether we should shouw the ANR,
+ * crash, etc dialogs. The idea is that if there is no affordnace to
+ * press the on-screen buttons, we shouldn't show the dialog.
+ *
+ * A thought: SystemUI might also want to get told about this, the Power
+ * dialog / global actions also might want different behaviors.
+ */
+ private static final boolean shouldShowDialogs(Configuration config) {
+ return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
+ && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
+ }
/**
* Save the locale. You must be inside a synchronized (this) block.