diff options
| -rw-r--r-- | api/current.txt | 5 | ||||
| -rw-r--r-- | core/java/android/app/ApplicationExitInfo.java | 174 | ||||
| -rw-r--r-- | core/proto/android/app/appexit_enums.proto | 240 | ||||
| -rw-r--r-- | core/proto/android/app/appexitinfo.proto | 146 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityManagerService.java | 60 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/AppErrors.java | 14 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/AppExitInfoTracker.java | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/OomAdjuster.java | 6 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ProcessList.java | 34 |
9 files changed, 493 insertions, 187 deletions
diff --git a/api/current.txt b/api/current.txt index 02b87342329c..f5135b2349b8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -4572,14 +4572,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 { diff --git a/core/java/android/app/ApplicationExitInfo.java b/core/java/android/app/ApplicationExitInfo.java index c55453e94960..5df3257f2444 100644 --- a/core/java/android/app/ApplicationExitInfo.java +++ b/core/java/android/app/ApplicationExitInfo.java @@ -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. @@ -202,6 +222,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} */ private int mPid; @@ -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"; } diff --git a/core/proto/android/app/appexit_enums.proto b/core/proto/android/app/appexit_enums.proto new file mode 100644 index 000000000000..491e1dc203b5 --- /dev/null +++ b/core/proto/android/app/appexit_enums.proto @@ -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; +} diff --git a/core/proto/android/app/appexitinfo.proto b/core/proto/android/app/appexitinfo.proto index 6a4922000805..66173f60bfd5 100644 --- a/core/proto/android/app/appexitinfo.proto +++ b/core/proto/android/app/appexitinfo.proto @@ -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; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index fbcb0102eb47..9058ac451455 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -81,6 +81,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; @@ -4243,7 +4245,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 { @@ -4269,7 +4272,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); } @@ -4757,6 +4763,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 |= @@ -4820,7 +4829,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") @@ -4925,7 +4937,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 { @@ -9054,7 +9066,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; } } @@ -9068,10 +9081,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); } @@ -9396,7 +9416,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"); } } @@ -14400,7 +14423,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) { @@ -15892,7 +15916,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( @@ -18622,7 +18649,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"); } } } @@ -18844,7 +18874,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. @@ -18861,7 +18892,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); } } } @@ -19547,7 +19578,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); diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 789f7199948d..b1fc0296518b 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -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; diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java index cba6b92bf440..a09aa64476c1 100644 --- a/services/core/java/com/android/server/am/AppExitInfoTracker.java +++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java @@ -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()); diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index e7b467adf487..aa37b4accc40 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -840,7 +840,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); @@ -2166,7 +2167,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; diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 3a5447edfdf0..a9d18e05e350 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -2378,7 +2378,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); @@ -2463,7 +2463,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; } @@ -2481,10 +2481,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") @@ -2517,7 +2518,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 @@ -2589,7 +2591,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); @@ -2598,13 +2601,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, @@ -2640,7 +2644,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); @@ -2838,7 +2842,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"); } } @@ -4004,7 +4009,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()); |