diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index ce6815f10b30c..5347719ef9932 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2679,6 +2679,8 @@
OK
Cancel
+
+ CLOSE
@@ -2811,6 +2813,11 @@
Re-enable this in System settings > Apps > Downloaded.
+
+ App isn\'t responding
+
+ %1$s may be using too much memory.
+
%1$s does not support the current Display size setting and may behave unexpectedly.
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0548db69a05da..b36630e07f683 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1890,6 +1890,9 @@
+
+
+
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cbfc747a74810..bffccafc677b4 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1690,6 +1690,7 @@ public class ActivityManagerService extends IActivityManager.Stub
static final int SERVICE_FOREGROUND_CRASH_MSG = 69;
static final int DISPATCH_OOM_ADJ_OBSERVER_MSG = 70;
static final int START_USER_SWITCH_FG_MSG = 712;
+ static final int TOP_APP_KILLED_BY_LMK_MSG = 73;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
static final int FIRST_BROADCAST_QUEUE_MSG = 200;
@@ -1921,6 +1922,17 @@ public class ActivityManagerService extends IActivityManager.Stub
dispatchProcessDied(pid, uid);
break;
}
+ case TOP_APP_KILLED_BY_LMK_MSG: {
+ final String appName = (String) msg.obj;
+ final AlertDialog d = new BaseErrorDialog(mUiContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setTitle(mUiContext.getText(R.string.top_app_killed_title));
+ d.setMessage(mUiContext.getString(R.string.top_app_killed_message, appName));
+ d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.close),
+ obtainMessage(DISMISS_DIALOG_UI_MSG, d));
+ d.show();
+ break;
+ }
case DISPATCH_UIDS_CHANGED_UI_MSG: {
dispatchUidsChanged();
} break;
@@ -5430,6 +5442,7 @@ public class ActivityManagerService extends IActivityManager.Stub
boolean doLowMem = app.instr == null;
boolean doOomAdj = doLowMem;
if (!app.killedByAm) {
+ maybeNotifyTopAppKilled(app);
Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died: "
+ ProcessList.makeOomAdjString(app.setAdj)
+ ProcessList.makeProcStateString(app.setProcState));
@@ -5463,6 +5476,23 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
+ /** Show system error dialog when a top app is killed by LMK */
+ void maybeNotifyTopAppKilled(ProcessRecord app) {
+ if (!shouldNotifyTopAppKilled(app)) {
+ return;
+ }
+
+ Message msg = mHandler.obtainMessage(TOP_APP_KILLED_BY_LMK_MSG);
+ msg.obj = mContext.getPackageManager().getApplicationLabel(app.info);
+ mUiHandler.sendMessage(msg);
+ }
+
+ /** Only show notification when the top app is killed on low ram devices */
+ private boolean shouldNotifyTopAppKilled(ProcessRecord app) {
+ return app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
+ ActivityManager.isLowRamDeviceStatic();
+ }
+
/**
* If a stack trace dump file is configured, dump process stack traces.
* @param clearTraces causes the dump file to be erased prior to the new