OSDN Git Service

Show dialog if top app is killed by lmk
authorNg Zhi An <zhin@google.com>
Wed, 13 Sep 2017 22:09:32 +0000 (15:09 -0700)
committerNg Zhi An <zhin@google.com>
Wed, 27 Sep 2017 22:12:46 +0000 (15:12 -0700)
Bug: 65488249
Fixes: 65488249
Test: run an app, then kill from command line like so
      adb shell "kill \$(pidof app)"

Change-Id: I7c259542723a9659c52e4571071ec5809693816d
Merged-In: I7c259542723a9659c52e4571071ec5809693816d

core/res/res/values/strings.xml
core/res/res/values/symbols.xml
services/core/java/com/android/server/am/ActivityManagerService.java

index ce6815f..5347719 100644 (file)
     <string name="yes">OK</string>
     <!-- Preference framework strings. -->
     <string name="no">Cancel</string>
+    <!-- Preference framework strings. -->
+    <string name="close">CLOSE</string>
     <!-- This is the generic "attention" string to be used in attention dialogs.  Typically
          combined with setIconAttribute(android.R.attr.alertDialogIcon)
          (or setIcon(android.R.drawable.ic_dialog_alert) on legacy versions of the platform) -->
     <!-- [CHAR LIMIT=200] Compat mode dialog: hint to re-enable compat mode dialog. -->
     <string name="screen_compat_mode_hint">Re-enable this in System settings &gt; Apps &gt; Downloaded.</string>
 
+    <!-- Text of the alert that is displayed when a top application is killed by lmk. -->
+    <string name="top_app_killed_title">App isn\'t responding</string>
+    <!-- Top app killed by lmk dialog message. -->
+    <string name="top_app_killed_message"><xliff:g id="app_name">%1$s</xliff:g> may be using too much memory.</string>
+
     <!-- [CHAR LIMIT=200] Unsupported display size dialog: message. Refers to "Display size" setting. -->
     <string name="unsupported_display_size_message"><xliff:g id="app_name">%1$s</xliff:g> does not support the current Display size setting and may behave unexpectedly.</string>
     <!-- [CHAR LIMIT=50] Unsupported display size dialog: check box label. -->
index 0548db6..b36630e 100644 (file)
   <java-symbol type="string" name="anr_application_process" />
   <java-symbol type="string" name="anr_process" />
   <java-symbol type="string" name="anr_title" />
+  <java-symbol type="string" name="top_app_killed_title" />
+  <java-symbol type="string" name="top_app_killed_message" />
+  <java-symbol type="string" name="close" />
   <java-symbol type="string" name="car_mode_disable_notification_message" />
   <java-symbol type="string" name="car_mode_disable_notification_title" />
   <java-symbol type="string" name="chooser_wallpaper" />
index cbfc747..bffccaf 100644 (file)
@@ -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