Update the categories of app kill reaons

Prepare for the metrics, added additional subreasons.

Bug: 148087795
Test: atest CtsAppExitTestCases:ActivityManagerAppExitInfoTest
Change-Id: Id4218f9af44c43824a9f530d48bbf8cd88c32a06
This commit is contained in:
Jing Ji
2020-02-19 10:04:44 -08:00
parent 5ea95b843e
commit 14870e0849
9 changed files with 493 additions and 189 deletions

View File

@@ -4574,14 +4574,17 @@ package android.app {
field public static final int REASON_ANR = 6; // 0x6
field public static final int REASON_CRASH = 4; // 0x4
field public static final int REASON_CRASH_NATIVE = 5; // 0x5
field public static final int REASON_DEPENDENCY_DIED = 12; // 0xc
field public static final int REASON_EXCESSIVE_RESOURCE_USAGE = 9; // 0x9
field public static final int REASON_EXIT_SELF = 1; // 0x1
field public static final int REASON_INITIALIZATION_FAILURE = 7; // 0x7
field public static final int REASON_LOW_MEMORY = 3; // 0x3
field public static final int REASON_OTHER = 10; // 0xa
field public static final int REASON_OTHER = 13; // 0xd
field public static final int REASON_PERMISSION_CHANGE = 8; // 0x8
field public static final int REASON_SIGNALED = 2; // 0x2
field public static final int REASON_UNKNOWN = 0; // 0x0
field public static final int REASON_USER_REQUESTED = 10; // 0xa
field public static final int REASON_USER_STOPPED = 11; // 0xb
}
public final class AsyncNotedAppOp implements android.os.Parcelable {

View File

@@ -16,6 +16,7 @@
package android.app;
import android.annotation.CurrentTimeMillisLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -121,11 +122,30 @@ public final class ApplicationExitInfo implements Parcelable {
public static final int REASON_EXCESSIVE_RESOURCE_USAGE = 9;
/**
* Application process was killed by the system for various other reasons,
* for example, the application package got disabled by the user;
* {@link #getDescription} will specify the cause given by the system.
* Application process was killed because of the user request, for example,
* user clicked the "Force stop" button of the application in the Settings,
* or removed the application away from Recents.
*/
public static final int REASON_OTHER = 10;
public static final int REASON_USER_REQUESTED = 10;
/**
* Application process was killed, because the user it is running as on devices
* with mutlple users, was stopped.
*/
public static final int REASON_USER_STOPPED = 11;
/**
* Application process was killed because its dependency was going away, for example,
* a stable content provider connection's client will be killed if the provider is killed.
*/
public static final int REASON_DEPENDENCY_DIED = 12;
/**
* Application process was killed by the system for various other reasons which are
* not by problems in apps and not actionable by apps, for example, the system just
* finished updates; {@link #getDescription} will specify the cause given by the system.
*/
public static final int REASON_OTHER = 13;
/**
* Application process kills subreason is unknown.
@@ -201,6 +221,105 @@ public final class ApplicationExitInfo implements Parcelable {
*/
public static final int SUBREASON_EXCESSIVE_CPU = 7;
/**
* System update has done (so the system update process should be killed);
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_SYSTEM_UPDATE_DONE = 8;
/**
* Kill all foreground services, for now it only occurs when enabling the quiet
* mode for the managed profile;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_KILL_ALL_FG = 9;
/**
* All background processes except certain ones were killed, for now it only occurs
* when the density of the default display is changed;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_KILL_ALL_BG_EXCEPT = 10;
/**
* The process associated with the UID was explicitly killed, for example,
* it could be because of platform compatibility overrides;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_KILL_UID = 11;
/**
* The process was explicitly killed with its PID, typically because of
* the low memory for surfaces;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_KILL_PID = 12;
/**
* The start of the process was invalid;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_INVALID_START = 13;
/**
* The process was killed because it's in an invalid state, typically
* it's triggered from SHELL;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_INVALID_STATE = 14;
/**
* The process was killed when it's imperceptible to user, because it was
* in a bad state;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_IMPERCEPTIBLE = 15;
/**
* The process was killed because it's being moved out from LRU list;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_REMOVE_LRU = 16;
/**
* The process was killed because it's isolated and was in a cached state;
* this would be set only when the reason is {@link #REASON_OTHER}.
*
* For internal use only.
* @hide
*/
public static final int SUBREASON_ISOLATED_NOT_NEEDED = 17;
// If there is any OEM code which involves additional app kill reasons, it should
// be categorized in {@link #REASON_OTHER}, with subreason code starting from 1000.
/**
* @see {@link #getPid}
*/
@@ -254,7 +373,7 @@ public final class ApplicationExitInfo implements Parcelable {
/**
* @see {@link #getTimestamp}
*/
private long mTimestamp;
private @CurrentTimeMillisLong long mTimestamp;
/**
* @see {@link #getDescription}
@@ -293,6 +412,9 @@ public final class ApplicationExitInfo implements Parcelable {
REASON_INITIALIZATION_FAILURE,
REASON_PERMISSION_CHANGE,
REASON_EXCESSIVE_RESOURCE_USAGE,
REASON_USER_REQUESTED,
REASON_USER_STOPPED,
REASON_DEPENDENCY_DIED,
REASON_OTHER,
})
@Retention(RetentionPolicy.SOURCE)
@@ -308,6 +430,16 @@ public final class ApplicationExitInfo implements Parcelable {
SUBREASON_LARGE_CACHED,
SUBREASON_MEMORY_PRESSURE,
SUBREASON_EXCESSIVE_CPU,
SUBREASON_SYSTEM_UPDATE_DONE,
SUBREASON_KILL_ALL_FG,
SUBREASON_KILL_ALL_BG_EXCEPT,
SUBREASON_KILL_UID,
SUBREASON_KILL_PID,
SUBREASON_INVALID_START,
SUBREASON_INVALID_STATE,
SUBREASON_IMPERCEPTIBLE,
SUBREASON_REMOVE_LRU,
SUBREASON_ISOLATED_NOT_NEEDED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface SubReason {}
@@ -403,7 +535,7 @@ public final class ApplicationExitInfo implements Parcelable {
* The timestamp of the process's death, in milliseconds since the epoch,
* as returned by {@link System#currentTimeMillis System.currentTimeMillis()}.
*/
public long getTimestamp() {
public @CurrentTimeMillisLong long getTimestamp() {
return mTimestamp;
}
@@ -564,7 +696,7 @@ public final class ApplicationExitInfo implements Parcelable {
*
* @hide
*/
public void setTimestamp(final long timestamp) {
public void setTimestamp(final @CurrentTimeMillisLong long timestamp) {
mTimestamp = timestamp;
}
@@ -656,6 +788,8 @@ public final class ApplicationExitInfo implements Parcelable {
mRss = other.mRss;
mTimestamp = other.mTimestamp;
mDescription = other.mDescription;
mPackageName = other.mPackageName;
mPackageList = other.mPackageList;
}
private ApplicationExitInfo(@NonNull Parcel in) {
@@ -748,6 +882,12 @@ public final class ApplicationExitInfo implements Parcelable {
return "PERMISSION CHANGE";
case REASON_EXCESSIVE_RESOURCE_USAGE:
return "EXCESSIVE RESOURCE USAGE";
case REASON_USER_REQUESTED:
return "USER REQUESTED";
case REASON_USER_STOPPED:
return "USER STOPPED";
case REASON_DEPENDENCY_DIED:
return "DEPENDENCY DIED";
case REASON_OTHER:
return "OTHER KILLS BY SYSTEM";
default:
@@ -772,6 +912,26 @@ public final class ApplicationExitInfo implements Parcelable {
return "MEMORY PRESSURE";
case SUBREASON_EXCESSIVE_CPU:
return "EXCESSIVE CPU USAGE";
case SUBREASON_SYSTEM_UPDATE_DONE:
return "SYSTEM UPDATE_DONE";
case SUBREASON_KILL_ALL_FG:
return "KILL ALL FG";
case SUBREASON_KILL_ALL_BG_EXCEPT:
return "KILL ALL BG EXCEPT";
case SUBREASON_KILL_UID:
return "KILL UID";
case SUBREASON_KILL_PID:
return "KILL PID";
case SUBREASON_INVALID_START:
return "INVALID START";
case SUBREASON_INVALID_STATE:
return "INVALID STATE";
case SUBREASON_IMPERCEPTIBLE:
return "IMPERCEPTIBLE";
case SUBREASON_REMOVE_LRU:
return "REMOVE LRU";
case SUBREASON_ISOLATED_NOT_NEEDED:
return "ISOLATED NOT NEEDED";
default:
return "UNKNOWN";
}

View File

@@ -0,0 +1,240 @@
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
syntax = "proto2";
option java_multiple_files = true;
package android.app;
/**
* The reason code that why app process is killed.
*/
enum AppExitReasonCode {
/**
* Application process died due to unknown reason.
*/
REASON_UNKNOWN = 0;
/**
* Application process exit normally by itself, for example,
* via {@link android.os.Process#exit}; {@link #status} will specify the exit code.
*
* <p>Applications should normally not do this, as the system has a better knowledge
* in terms of process management.</p>
*/
REASON_EXIT_SELF = 1;
/**
* Application process died due to the result of an OS signal; for example,
* {@link android.os.Process#SIGNAL_KILL}; {@link #status} will specify the signum.
*/
REASON_SIGNALED = 2;
/**
* Application process was killed by the system low memory killer, meaning the system was
* under memory pressure at the time of kill.
*/
REASON_LOW_MEMORY = 3;
/**
* Application process died because of an unhandled exception in Java code.
*/
REASON_CRASH = 4;
/**
* Application process died because it's crashed due to a native code crash.
*/
REASON_CRASH_NATIVE = 5;
/**
* Application process was killed due to being unresponsive (ANR).
*/
REASON_ANR = 6;
/**
* Application process was killed because it took too long to attach to the system
* during the start.
*/
REASON_INITIALIZATION_FAILURE = 7;
/**
* Application process was killed because of initialization failure,
* for example, it took too long to attach to the system during the start,
* or there was an error during initialization.
*/
REASON_PERMISSION_CHANGE = 8;
/**
* Application process was killed by the activity manager due to excessive resource usage.
*/
REASON_EXCESSIVE_RESOURCE_USAGE = 9;
/**
* Application process was killed because of the user request, for example,
* user clicked the "Force stop" button of the application in the Settings,
* or swiped away the application from Recents.
*/
REASON_USER_REQUESTED = 10;
/**
* Application process was killed, because the user they are running as on devices
* with mutlple users, was stopped.
*/
REASON_USER_STOPPED = 11;
/**
* Application process was killed because its dependency was going away, for example,
* a stable content provider connection's client will be killed if the provider is killed.
*/
REASON_DEPENDENCY_DIED = 12;
/**
* Application process was killed by the system for various other reasons,
* for example, the application package got disabled by the user;
* {@link #description} will specify the cause given by the system.
*/
REASON_OTHER = 13;
}
/**
* The supplemental reason code that why app process is killed
*/
enum AppExitSubReasonCode {
/**
* Application process kills subReason is unknown.
*/
SUBREASON_UNKNOWN = 0;
/**
* Application process was killed because user quit it on the "wait for debugger" dialog.
*/
SUBREASON_WAIT_FOR_DEBUGGER = 1;
/**
* Application process was killed by the activity manager because there were too many cached
* processes.
*/
SUBREASON_TOO_MANY_CACHED = 2;
/**
* Application process was killed by the activity manager because there were too many empty
* processes.
*/
SUBREASON_TOO_MANY_EMPTY = 3;
/**
* Application process was killed by the activity manager because there were too many cached
* processes and this process had been in empty state for a long time.
*/
SUBREASON_TRIM_EMPTY = 4;
/**
* Application process was killed by the activity manager because system was on
* memory pressure and this process took large amount of cached memory.
*/
SUBREASON_LARGE_CACHED = 5;
/**
* Application process was killed by the activity manager because the system was on
* low memory pressure for a significant amount of time since last idle.
*/
SUBREASON_MEMORY_PRESSURE = 6;
/**
* Application process was killed by the activity manager due to excessive CPU usage.
*/
SUBREASON_EXCESSIVE_CPU = 7;
/**
* System update has done (so the system update process should be killed).
*/
SUBREASON_SYSTEM_UPDATE_DONE = 8;
/**
* Kill all foreground services, for now it only occurs when enabling the quiet
* mode for the managed profile.
*/
SUBREASON_KILL_ALL_FG = 9;
/**
* All background processes except certain ones were killed, for now it only occurs
* when the density of the default display is changed.
*/
SUBREASON_KILL_ALL_BG_EXCEPT = 10;
/**
* The process associated with the UID was explicitly killed, for example,
* it could be because of permission changes.
*/
SUBREASON_KILL_UID = 11;
/**
* The process was explicitly killed with its PID, typically because of
* the low memory for surfaces.
*/
SUBREASON_KILL_PID = 12;
/**
* The start of the process was invalid.
*/
SUBREASON_INVALID_START = 13;
/**
* The process was killed because it's in an invalid state, typically
* it's triggered from SHELL.
*/
SUBREASON_INVALID_STATE = 14;
/**
* The process was killed when it's imperceptible to user, because it was
* in a bad state.
*/
SUBREASON_IMPERCEPTIBLE = 15;
/**
* The process was killed because it's being moved out from LRU list.
*/
SUBREASON_REMOVE_LRU = 16;
/**
* The process was killed because it's isolated and was in a cached state.
*/
SUBREASON_ISOLATED_NOT_NEEDED = 17;
}
/**
* The relative importance level that the system places on a process.
* Keep sync with the definitions in
* {@link android.app.ActivityManager.RunningAppProcessInfo}
*/
enum Importance {
option allow_alias = true;
IMPORTANCE_FOREGROUND = 100;
IMPORTANCE_FOREGROUND_SERVICE = 125;
IMPORTANCE_TOP_SLEEPING_PRE_28 = 150;
IMPORTANCE_VISIBLE = 200;
IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;
IMPORTANCE_PERCEPTIBLE = 230;
IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
IMPORTANCE_SERVICE = 300;
IMPORTANCE_TOP_SLEEPING = 325;
IMPORTANCE_CANT_SAVE_STATE = 350;
IMPORTANCE_CACHED = 400;
IMPORTANCE_BACKGROUND = 400;
IMPORTANCE_EMPTY = 500;
IMPORTANCE_GONE = 1000;
}

View File

@@ -20,6 +20,7 @@ option java_multiple_files = true;
package android.app;
import "frameworks/base/core/proto/android/privacy.proto";
import "frameworks/base/core/proto/android/app/appexit_enums.proto";
/**
* An android.app.ApplicationExitInfo object.
@@ -33,150 +34,9 @@ message ApplicationExitInfoProto {
optional int32 defining_uid = 4;
optional string process_name = 5;
optional int32 connection_group = 6;
enum ReasonCode {
/**
* Application process died due to unknown reason.
*/
REASON_UNKNOWN = 0;
/**
* Application process exit normally by itself, for example,
* via {@link android.os.Process#exit}; {@link #status} will specify the exit code.
*
* <p>Applications should normally not do this, as the system has a better knowledge
* in terms of process management.</p>
*/
REASON_EXIT_SELF = 1;
/**
* Application process died due to the result of an OS signal; for example,
* {@link android.os.Process#SIGNAL_KILL}; {@link #status} will specify the signum.
*/
REASON_SIGNALED = 2;
/**
* Application process was killed by the system low memory killer, meaning the system was
* under memory pressure at the time of kill.
*/
REASON_LOW_MEMORY = 3;
/**
* Application process died because of an unhandled exception in Java code.
*/
REASON_CRASH = 4;
/**
* Application process died because it's crashed due to a native code crash.
*/
REASON_CRASH_NATIVE = 5;
/**
* Application process was killed due to being unresponsive (ANR).
*/
REASON_ANR = 6;
/**
* Application process was killed because it took too long to attach to the system
* during the start.
*/
REASON_INITIALIZATION_FAILURE = 7;
/**
* Application process was killed because of initialization failure,
* for example, it took too long to attach to the system during the start,
* or there was an error during initialization.
*/
REASON_PERMISSION_CHANGE = 8;
/**
* Application process was killed by the activity manager due to excessive resource usage.
*/
REASON_EXCESSIVE_RESOURCE_USAGE = 9;
/**
* Application process was killed by the system for various other reasons,
* for example, the application package got disabled by the user;
* {@link #description} will specify the cause given by the system.
*/
REASON_OTHER = 10;
}
optional ReasonCode reason = 7;
enum SubReason {
/**
* Application process kills subReason is unknown.
*/
SUBREASON_UNKNOWN = 0;
/**
* Application process was killed because user quit it on the "wait for debugger" dialog.
*/
SUBREASON_WAIT_FOR_DEBUGGER = 1;
/**
* Application process was killed by the activity manager because there were too many cached
* processes.
*/
SUBREASON_TOO_MANY_CACHED = 2;
/**
* Application process was killed by the activity manager because there were too many empty
* processes.
*/
SUBREASON_TOO_MANY_EMPTY = 3;
/**
* Application process was killed by the activity manager because there were too many cached
* processes and this process had been in empty state for a long time.
*/
SUBREASON_TRIM_EMPTY = 4;
/**
* Application process was killed by the activity manager because system was on
* memory pressure and this process took large amount of cached memory.
*/
SUBREASON_LARGE_CACHED = 5;
/**
* Application process was killed by the activity manager because the system was on
* low memory pressure for a significant amount of time since last idle.
*/
SUBREASON_MEMORY_PRESSURE = 6;
/**
* Application process was killed by the activity manager due to excessive CPU usage.
*/
SUBREASON_EXCESSIVE_CPU = 7;
}
optional SubReason sub_reason = 8;
optional AppExitReasonCode reason = 7;
optional AppExitSubReasonCode sub_reason = 8;
optional int32 status = 9;
enum Importance {
option allow_alias = true;
/**
* Keep sync with the definitions in
* {@link android.app.ActivityManager.RunningAppProcessInfo}
*/
IMPORTANCE_FOREGROUND = 100;
IMPORTANCE_FOREGROUND_SERVICE = 125;
IMPORTANCE_TOP_SLEEPING_PRE_28 = 150;
IMPORTANCE_VISIBLE = 200;
IMPORTANCE_PERCEPTIBLE_PRE_26 = 130;
IMPORTANCE_PERCEPTIBLE = 230;
IMPORTANCE_CANT_SAVE_STATE_PRE_26 = 170;
IMPORTANCE_SERVICE = 300;
IMPORTANCE_TOP_SLEEPING = 325;
IMPORTANCE_CANT_SAVE_STATE = 350;
IMPORTANCE_CACHED = 400;
IMPORTANCE_BACKGROUND = 400;
IMPORTANCE_EMPTY = 500;
IMPORTANCE_GONE = 1000;
}
optional Importance importance = 10;
optional int64 pss = 11;
optional int64 rss = 12;

View File

@@ -77,6 +77,8 @@ import static android.os.Process.removeAllProcessGroups;
import static android.os.Process.sendSignal;
import static android.os.Process.setThreadPriority;
import static android.os.Process.setThreadScheduler;
import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
import static android.permission.PermissionManager.KILL_APP_REASON_PERMISSIONS_REVOKED;
import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
import static android.provider.Settings.Global.DEBUG_APP;
import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
@@ -4238,7 +4240,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
synchronized (this) {
mProcessList.killPackageProcessesLocked(packageName, appId, targetUserId,
ProcessList.SERVICE_ADJ, "kill background");
ProcessList.SERVICE_ADJ, ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_UNKNOWN, "kill background");
}
}
} finally {
@@ -4264,7 +4267,10 @@ public class ActivityManagerService extends IActivityManager.Stub
// because this method is also used to simulate low memory.
mAllowLowerMemLevel = true;
mProcessList.killPackageProcessesLocked(null /* packageName */, -1 /* appId */,
UserHandle.USER_ALL, ProcessList.CACHED_APP_MIN_ADJ, "kill all background");
UserHandle.USER_ALL, ProcessList.CACHED_APP_MIN_ADJ,
ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_UNKNOWN,
"kill all background");
doLowMemReportIfNeededLocked(null);
}
@@ -4752,6 +4758,9 @@ public class ActivityManagerService extends IActivityManager.Stub
boolean didSomething = mProcessList.killPackageProcessesLocked(packageName, appId, userId,
ProcessList.INVALID_ADJ, callerWillRestart, false /* allowRestart */, doit,
evenPersistent, true /* setRemoved */,
packageName == null ? ApplicationExitInfo.REASON_USER_STOPPED
: ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_UNKNOWN,
packageName == null ? ("stop user " + userId) : ("stop " + packageName));
didSomething |=
@@ -4815,7 +4824,10 @@ public class ActivityManagerService extends IActivityManager.Stub
@GuardedBy("this")
private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
cleanupAppInLaunchingProvidersLocked(app, true);
mProcessList.removeProcessLocked(app, false, true, "timeout publishing content providers");
mProcessList.removeProcessLocked(app, false, true,
ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
ApplicationExitInfo.SUBREASON_UNKNOWN,
"timeout publishing content providers");
}
@GuardedBy("this")
@@ -4920,7 +4932,7 @@ public class ActivityManagerService extends IActivityManager.Stub
if (pid > 0 && pid != MY_PID) {
killProcessQuiet(pid);
//TODO: killProcessGroup(app.info.uid, pid);
mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
mProcessList.noteAppKill(app, ApplicationExitInfo.REASON_INITIALIZATION_FAILURE,
ApplicationExitInfo.SUBREASON_UNKNOWN, "attach failed");
} else {
try {
@@ -9050,7 +9062,8 @@ public class ActivityManagerService extends IActivityManager.Stub
}
int adj = proc.setAdj;
if (adj >= worstType && !proc.killedByAm) {
proc.kill(reason, ApplicationExitInfo.REASON_OTHER, true);
proc.kill(reason, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_KILL_PID, true);
killed = true;
}
}
@@ -9064,10 +9077,17 @@ public class ActivityManagerService extends IActivityManager.Stub
synchronized (this) {
final long identity = Binder.clearCallingIdentity();
try {
boolean permissionChange = KILL_APP_REASON_PERMISSIONS_REVOKED.equals(reason)
|| KILL_APP_REASON_GIDS_CHANGED.equals(reason);
mProcessList.killPackageProcessesLocked(null /* packageName */, appId, userId,
ProcessList.PERSISTENT_PROC_ADJ, false /* callerWillRestart */,
true /* callerWillRestart */, true /* doit */, true /* evenPersistent */,
false /* setRemoved */, reason != null ? reason : "kill uid");
false /* setRemoved */,
permissionChange ? ApplicationExitInfo.REASON_PERMISSION_CHANGE
: ApplicationExitInfo.REASON_OTHER,
permissionChange ? ApplicationExitInfo.SUBREASON_UNKNOWN
: ApplicationExitInfo.SUBREASON_KILL_UID,
reason != null ? reason : "kill uid");
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -9392,7 +9412,10 @@ public class ActivityManagerService extends IActivityManager.Stub
for (int i=procsToKill.size()-1; i>=0; i--) {
ProcessRecord proc = procsToKill.get(i);
Slog.i(TAG, "Removing system update proc: " + proc);
mProcessList.removeProcessLocked(proc, true, false, "system update done");
mProcessList.removeProcessLocked(proc, true, false,
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_SYSTEM_UPDATE_DONE,
"system update done");
}
}
@@ -14396,7 +14419,8 @@ public class ActivityManagerService extends IActivityManager.Stub
+ cpr.name.flattenToShortString()
+ " in dying proc " + (proc != null ? proc.processName : "??")
+ " (adj " + (proc != null ? proc.setAdj : "??") + ")",
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.REASON_DEPENDENCY_DIED,
ApplicationExitInfo.SUBREASON_UNKNOWN,
true);
}
} else if (capp.thread != null && conn.provider.provider != null) {
@@ -15887,7 +15911,10 @@ public class ActivityManagerService extends IActivityManager.Stub
-1);
mProcessList.killPackageProcessesLocked(ssp,
UserHandle.getAppId(extraUid),
userId, ProcessList.INVALID_ADJ, "change " + ssp);
userId, ProcessList.INVALID_ADJ,
ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_UNKNOWN,
"change " + ssp);
}
cleanupDisabledPackageComponentsLocked(ssp, userId,
intent.getStringArrayExtra(
@@ -18615,7 +18642,10 @@ public class ActivityManagerService extends IActivityManager.Stub
final int N = procs.size();
for (int i = 0; i < N; i++) {
mProcessList.removeProcessLocked(procs.get(i), false, true, "kill all fg");
mProcessList.removeProcessLocked(procs.get(i), false, true,
ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_KILL_ALL_FG,
"kill all fg");
}
}
}
@@ -18837,7 +18867,8 @@ public class ActivityManagerService extends IActivityManager.Stub
final ProcessRecord pr = (ProcessRecord) wpc.mOwner;
if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
&& pr.curReceivers.isEmpty()) {
pr.kill("remove task", ApplicationExitInfo.REASON_OTHER, true);
pr.kill("remove task", ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_UNKNOWN, true);
} else {
// We delay killing processes that are not in the background or running a
// receiver.
@@ -18854,7 +18885,7 @@ public class ActivityManagerService extends IActivityManager.Stub
true /* keepIfLarge */);
if (proc != null) {
mProcessList.removeProcessLocked(proc, false /* callerWillRestart */,
true /* allowRestart */, reason);
true /* allowRestart */, ApplicationExitInfo.REASON_OTHER, reason);
}
}
}
@@ -19540,7 +19571,10 @@ public class ActivityManagerService extends IActivityManager.Stub
try {
synchronized(this) {
mProcessList.killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid),
userId, ProcessList.FOREGROUND_APP_ADJ, "dep: " + packageName);
userId, ProcessList.FOREGROUND_APP_ADJ,
ApplicationExitInfo.REASON_DEPENDENCY_DIED,
ApplicationExitInfo.SUBREASON_UNKNOWN,
"dep: " + packageName);
}
} finally {
Binder.restoreCallingIdentity(callingId);

View File

@@ -395,7 +395,7 @@ class AppErrors {
() -> {
synchronized (mService) {
killAppImmediateLocked(p, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_UNKNOWN,
ApplicationExitInfo.SUBREASON_INVALID_STATE,
"forced", "killed for invalid state");
}
},
@@ -510,8 +510,8 @@ class AppErrors {
stopReportingCrashesLocked(r);
}
if (res == AppErrorDialog.RESTART) {
mService.mProcessList.removeProcessLocked(r, false, true, "crash",
ApplicationExitInfo.REASON_CRASH);
mService.mProcessList.removeProcessLocked(r, false, true,
ApplicationExitInfo.REASON_CRASH, "crash");
if (taskId != INVALID_TASK_ID) {
try {
mService.startActivityFromRecents(taskId,
@@ -529,8 +529,8 @@ class AppErrors {
// Kill it with fire!
mService.mAtmInternal.onHandleAppCrash(r.getWindowProcessController());
if (!r.isPersistent()) {
mService.mProcessList.removeProcessLocked(r, false, false, "crash",
ApplicationExitInfo.REASON_CRASH);
mService.mProcessList.removeProcessLocked(r, false, false,
ApplicationExitInfo.REASON_CRASH, "crash");
mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
}
} finally {
@@ -747,8 +747,8 @@ class AppErrors {
// Don't let services in this process be restarted and potentially
// annoy the user repeatedly. Unless it is persistent, since those
// processes run critical code.
mService.mProcessList.removeProcessLocked(app, false, tryAgain, "crash",
ApplicationExitInfo.REASON_CRASH);
mService.mProcessList.removeProcessLocked(app, false, tryAgain,
ApplicationExitInfo.REASON_CRASH, "crash");
mService.mAtmInternal.resumeTopActivities(false /* scheduleIdle */);
if (!showBackground) {
return false;

View File

@@ -348,6 +348,7 @@ public final class AppExitInfoTracker {
} else {
// always override the existing info since we are now more informational.
info.setReason(raw.getReason());
info.setSubReason(raw.getSubReason());
info.setStatus(0);
info.setTimestamp(System.currentTimeMillis());
info.setDescription(raw.getDescription());

View File

@@ -838,7 +838,8 @@ public final class OomAdjuster {
// definition not re-use the same process again, and it is
// good to avoid having whatever code was running in them
// left sitting around after no longer needed.
app.kill("isolated not needed", ApplicationExitInfo.REASON_OTHER, true);
app.kill("isolated not needed", ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true);
} else {
// Keeping this process, update its uid.
updateAppUidRecLocked(app);
@@ -2141,7 +2142,8 @@ public final class OomAdjuster {
}
if (app.waitingToKill != null && app.curReceivers.isEmpty()
&& app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
app.kill(app.waitingToKill, ApplicationExitInfo.REASON_OTHER, true);
app.kill(app.waitingToKill, ApplicationExitInfo.REASON_USER_REQUESTED,
ApplicationExitInfo.SUBREASON_UNKNOWN, true);
success = false;
} else {
int processGroup;

View File

@@ -80,13 +80,11 @@ import android.os.Bundle;
import android.os.DropBoxManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.IVold;
import android.os.Looper;
import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
@@ -2363,7 +2361,7 @@ public final class ProcessList {
killProcessQuiet(pid);
Process.killProcessGroup(app.uid, app.pid);
noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
ApplicationExitInfo.SUBREASON_INVALID_START, reason);
return false;
}
mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
@@ -2450,7 +2448,7 @@ public final class ProcessList {
killProcessQuiet(app.pid);
ProcessList.killProcessGroup(app.uid, app.pid);
noteAppKill(app, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_UNKNOWN, "hasn't been killed");
ApplicationExitInfo.SUBREASON_REMOVE_LRU, "hasn't been killed");
} else {
app.pendingStart = false;
}
@@ -2468,10 +2466,11 @@ public final class ProcessList {
@GuardedBy("mService")
boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj,
String reason) {
int reasonCode, int subReason, String reason) {
return killPackageProcessesLocked(packageName, appId, userId, minOomAdj,
false /* callerWillRestart */, true /* allowRestart */, true /* doit */,
false /* evenPersistent */, false /* setRemoved */, reason);
false /* evenPersistent */, false /* setRemoved */, reasonCode,
subReason, reason);
}
@GuardedBy("mService")
@@ -2504,7 +2503,8 @@ public final class ProcessList {
@GuardedBy("mService")
final boolean killPackageProcessesLocked(String packageName, int appId,
int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
boolean doit, boolean evenPersistent, boolean setRemoved, String reason) {
boolean doit, boolean evenPersistent, boolean setRemoved, int reasonCode,
int subReason, String reason) {
ArrayList<ProcessRecord> procs = new ArrayList<>();
// Remove all processes this package may have touched: all with the
@@ -2576,7 +2576,8 @@ public final class ProcessList {
int N = procs.size();
for (int i=0; i<N; i++) {
removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
removeProcessLocked(procs.get(i), callerWillRestart, allowRestart,
reasonCode, subReason, reason);
}
killAppZygotesLocked(packageName, appId, userId, false /* force */);
mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END);
@@ -2585,13 +2586,14 @@ public final class ProcessList {
@GuardedBy("mService")
boolean removeProcessLocked(ProcessRecord app,
boolean callerWillRestart, boolean allowRestart, String reason) {
return removeProcessLocked(app, callerWillRestart, allowRestart, reason,
ApplicationExitInfo.REASON_OTHER);
boolean callerWillRestart, boolean allowRestart, int reasonCode, String reason) {
return removeProcessLocked(app, callerWillRestart, allowRestart, reasonCode,
ApplicationExitInfo.SUBREASON_UNKNOWN, reason);
}
boolean removeProcessLocked(ProcessRecord app,
boolean callerWillRestart, boolean allowRestart, String reason, int reasonCode) {
@GuardedBy("mService")
boolean removeProcessLocked(ProcessRecord app, boolean callerWillRestart,
boolean allowRestart, int reasonCode, int subReason, String reason) {
final String name = app.processName;
final int uid = app.uid;
if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
@@ -2627,7 +2629,7 @@ public final class ProcessList {
needRestart = true;
}
}
app.kill(reason, reasonCode, true);
app.kill(reason, reasonCode, subReason, true);
mService.handleAppDiedLocked(app, willRestart, allowRestart);
if (willRestart) {
removeLruProcessLocked(app);
@@ -2824,7 +2826,8 @@ public final class ProcessList {
final int N = procs.size();
for (int i = 0; i < N; i++) {
removeProcessLocked(procs.get(i), false, true, "kill all background except");
removeProcessLocked(procs.get(i), false, true, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_KILL_ALL_BG_EXCEPT, "kill all background except");
}
}
@@ -3989,7 +3992,8 @@ public final class ProcessList {
return false;
}
app.kill(reason, ApplicationExitInfo.REASON_OTHER, true);
app.kill(reason, ApplicationExitInfo.REASON_OTHER,
ApplicationExitInfo.SUBREASON_IMPERCEPTIBLE, true);
if (!app.isolated) {
mLastProcessKillTimes.put(app.processName, app.uid, SystemClock.uptimeMillis());