}
void killAppAtUserRequestLocked(ProcessRecord app, Dialog fromDialog) {
- app.crashing = false;
- app.crashingReport = null;
- app.notResponding = false;
- app.notRespondingReport = null;
if (app.anrDialog == fromDialog) {
app.anrDialog = null;
}
if (app.waitDialog == fromDialog) {
app.waitDialog = null;
}
+ killAppImmediateLocked(app, "user-terminated", "user request after error");
+ }
+
+ private void killAppImmediateLocked(ProcessRecord app, String reason, String killReason) {
+ app.crashing = false;
+ app.crashingReport = null;
+ app.notResponding = false;
+ app.notRespondingReport = null;
if (app.pid > 0 && app.pid != MY_PID) {
- handleAppCrashLocked(app, "user-terminated" /*reason*/,
+ handleAppCrashLocked(app, reason,
null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/, null /*data*/);
- app.kill("user request after error", true);
+ app.kill(killReason, true);
}
}
* @param message
*/
void scheduleAppCrashLocked(int uid, int initialPid, String packageName, int userId,
- String message) {
+ String message, boolean force) {
ProcessRecord proc = null;
// Figure out which process to kill. We don't trust that initialPid
}
proc.scheduleCrash(message);
+ if (force) {
+ // If the app is responsive, the scheduled crash will happen as expected
+ // and then the delayed summary kill will be a no-op.
+ final ProcessRecord p = proc;
+ mService.mHandler.postDelayed(
+ () -> killAppImmediateLocked(p, "forced", "killed for invalid state"),
+ 5000L);
+ }
}
/**