From 3b31dce7b4f524bb624303dbb06e2407b7417ce9 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Tue, 17 Dec 2024 12:04:56 -0800 Subject: Add shell command to clear bad processes. Bug: 383481659 Test: atest ./tests/app/src/android/app/cts/BroadcastOptionsIntegrationTest.java Test: atest ./tests/app/src/android/app/cts/ActivityManagerFgsBgStartTest.java Flag: EXEMPT shell cmd addition Change-Id: I6910d59529d70c750a9d7140bbcd03f811712395 --- core/java/com/android/internal/app/ProcessMap.java | 5 +++++ .../server/am/ActivityManagerShellCommand.java | 25 ++++++++++++++++++++++ .../core/java/com/android/server/am/AppErrors.java | 18 ++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/core/java/com/android/internal/app/ProcessMap.java b/core/java/com/android/internal/app/ProcessMap.java index 542b6d00ca37..b4945e7fd2ec 100644 --- a/core/java/com/android/internal/app/ProcessMap.java +++ b/core/java/com/android/internal/app/ProcessMap.java @@ -28,6 +28,11 @@ public class ProcessMap { if (uids == null) return null; return uids.get(uid); } + + public SparseArray get(String name) { + SparseArray uids = mMap.get(name); + return uids; + } public E put(String name, int uid, E value) { SparseArray uids = mMap.get(name); diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 9a63546bf5a7..cbebc905796c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -449,6 +449,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return runSetAppZygotePreloadTimeout(pw); case "set-media-foreground-service": return runSetMediaForegroundService(pw); + case "clear-bad-process": + return runClearBadProcess(pw); default: return handleDefaultCommands(cmd); } @@ -4276,6 +4278,27 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } + int runClearBadProcess(PrintWriter pw) throws RemoteException { + final String processName = getNextArgRequired(); + int userId = UserHandle.USER_CURRENT; + String opt; + while ((opt = getNextOption()) != null) { + if ("--user".equals(opt)) { + userId = UserHandle.parseUserArg(getNextArgRequired()); + } else { + getErrPrintWriter().println("Error: unknown option " + opt); + return -1; + } + } + if (userId == UserHandle.USER_CURRENT) { + userId = mInternal.getCurrentUserId(); + } + + pw.println("Clearing '" + processName + "' in u" + userId + " from bad processes list"); + mInternal.mAppErrors.clearBadProcessForUser(processName, userId); + return 0; + } + private Resources getResources(PrintWriter pw) throws RemoteException { // system resources does not contain all the device configuration, construct it manually. Configuration config = mInterface.getConfiguration(); @@ -4717,6 +4740,8 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" set-media-foreground-service inactive|active [--user USER_ID] " + " "); pw.println(" Set an app's media service inactive or active."); + pw.println(" clear-bad-process [--user USER_ID] "); + pw.println(" Clears a process from the bad processes list."); Intent.printIntentArgsHelp(pw, ""); } } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index b7a5f3e4099a..2fbf05eb0061 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -373,6 +373,24 @@ class AppErrors { } } + void clearBadProcessForUser(final String processName, final int userId) { + synchronized (mBadProcessLock) { + final ProcessMap badProcesses = new ProcessMap<>(); + badProcesses.putAll(mBadProcesses); + final SparseArray uids = badProcesses.get(processName); + if (uids == null) { + return; + } + for (int i = uids.size() - 1; i >= 0; --i) { + final int uid = uids.keyAt(i); + if (userId == UserHandle.USER_ALL || userId == UserHandle.getUserId(uid)) { + badProcesses.remove(processName, uid); + } + } + mBadProcesses = badProcesses; + } + } + void markBadProcess(final String processName, final int uid, BadProcessInfo info) { synchronized (mBadProcessLock) { final ProcessMap badProcesses = new ProcessMap<>(); -- cgit v1.2.3-59-g8ed1b