Removed AMS.mStackSuperivor (22/n)

The stack supervisor object should only be accessed through ATMS.

Test: Existing test pass
Bug: 80414790
Change-Id: I0648a95161a6a5c4ad714264d217c7f5e55852d7
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 6398680..b7bbfe8 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -38,7 +38,9 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
 import static android.content.pm.ApplicationInfo.FLAG_FACTORY_TEST;
 import static android.content.pm.ConfigurationInfo.GL_ES_VERSION_UNDEFINED;
 import static android.content.pm.PackageManager.FEATURE_ACTIVITIES_ON_SECONDARY_DISPLAYS;
@@ -51,6 +53,7 @@
 import static android.os.FactoryTest.FACTORY_TEST_HIGH_LEVEL;
 import static android.os.FactoryTest.FACTORY_TEST_LOW_LEVEL;
 import static android.os.FactoryTest.FACTORY_TEST_OFF;
+import static android.os.Process.FIRST_APPLICATION_UID;
 import static android.os.Process.SYSTEM_UID;
 import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
@@ -68,7 +71,22 @@
 import static android.view.WindowManager.TRANSIT_TASK_OPEN;
 import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT;
 
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.Controller.IS_A_MONKEY;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GLOBAL_CONFIGURATION;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.GOING_TO_SLEEP;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HEAVY_WEIGHT_PROC;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.HOME_PROC;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.LAUNCHING_ACTIVITY;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PREVIOUS_PROC_VISIBLE_TIME_MS;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
+import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
 import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_ALL;
+import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
 import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
 import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_FOCUS;
 import static com.android.server.am.ActivityTaskManagerDebugConfig.DEBUG_IMMERSIVE;
@@ -220,9 +238,12 @@
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
 import com.android.internal.notification.SystemNotificationChannels;
+import com.android.internal.os.TransferPipe;
 import com.android.internal.os.logging.MetricsLoggerWrapper;
 import com.android.internal.policy.IKeyguardDismissCallback;
 import com.android.internal.policy.KeyguardDismissCallback;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FastPrintWriter;
 import com.android.internal.util.Preconditions;
 import com.android.internal.util.function.pooled.PooledLambda;
 import com.android.server.AppOpsService;
@@ -239,16 +260,24 @@
 import com.android.server.wm.PinnedStackWindowController;
 import com.android.server.wm.WindowManagerService;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileDescriptor;
 import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.lang.ref.WeakReference;
+import java.text.DateFormat;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Predicate;
 
 /**
  * System service for managing activities and their containers (task, stacks, displays,... ).
@@ -276,6 +305,15 @@
     /** Hardware-reported OpenGLES version. */
     final int GL_ES_VERSION;
 
+    public static final String DUMP_ACTIVITIES_CMD = "activities" ;
+    public static final String DUMP_ACTIVITIES_SHORT_CMD = "a" ;
+    public static final String DUMP_LASTANR_CMD = "lastanr" ;
+    public static final String DUMP_LASTANR_TRACES_CMD = "lastanr-traces" ;
+    public static final String DUMP_STARTER_CMD = "starter" ;
+    public static final String DUMP_CONTAINERS_CMD = "containers" ;
+    public static final String DUMP_RECENTS_CMD = "recents" ;
+    public static final String DUMP_RECENTS_SHORT_CMD = "r" ;
+
     Context mContext;
     /**
      * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
@@ -414,6 +452,12 @@
     String mTopData;
 
     /**
+     * Dump of the activity state at the time of the last ANR. Cleared after
+     * {@link WindowManagerService#LAST_ANR_LIFETIME_DURATION_MSECS}
+     */
+    String mLastANRState;
+
+    /**
      * Used to retain an update lock when the foreground activity is in
      * immersive mode.
      */
@@ -701,6 +745,7 @@
     void setWindowManager(WindowManagerService wm) {
         mWindowManager = wm;
         mLockTaskController.setWindowManager(wm);
+        mStackSupervisor.setWindowManager(wm);
     }
 
     void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
@@ -2617,7 +2662,7 @@
                 pae.intent.setFlags(FLAG_ACTIVITY_NEW_TASK
                         | Intent.FLAG_ACTIVITY_SINGLE_TOP
                         | Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                mAmInternal.closeSystemDialogs("assist");
+                mInternal.closeSystemDialogs("assist");
 
                 try {
                     mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
@@ -4304,16 +4349,177 @@
                 || transit == TRANSIT_TASK_TO_FRONT;
     }
 
-    void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
-        synchronized (mGlobalLock) {
-            pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
-            if (mRunningVoice != null) {
-                pw.println("  mRunningVoice=" + mRunningVoice);
-                pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
+    void dumpLastANRLocked(PrintWriter pw) {
+        pw.println("ACTIVITY MANAGER LAST ANR (dumpsys activity lastanr)");
+        if (mLastANRState == null) {
+            pw.println("  <no ANR has occurred since boot>");
+        } else {
+            pw.println(mLastANRState);
+        }
+    }
+
+    void dumpLastANRTracesLocked(PrintWriter pw) {
+        pw.println("ACTIVITY MANAGER LAST ANR TRACES (dumpsys activity lastanr-traces)");
+
+        final File[] files = new File(ANR_TRACE_DIR).listFiles();
+        if (ArrayUtils.isEmpty(files)) {
+            pw.println("  <no ANR has occurred since boot>");
+            return;
+        }
+        // Find the latest file.
+        File latest = null;
+        for (File f : files) {
+            if ((latest == null) || (latest.lastModified() < f.lastModified())) {
+                latest = f;
             }
-            pw.println("  mSleeping=" + mSleeping);
-            pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
-            pw.println("  mVrController=" + mVrController);
+        }
+        pw.print("File: ");
+        pw.print(latest.getName());
+        pw.println();
+        try (BufferedReader in = new BufferedReader(new FileReader(latest))) {
+            String line;
+            while ((line = in.readLine()) != null) {
+                pw.println(line);
+            }
+        } catch (IOException e) {
+            pw.print("Unable to read: ");
+            pw.print(e);
+            pw.println();
+        }
+    }
+
+    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
+        dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage,
+                "ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
+    }
+
+    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage, String header) {
+        pw.println(header);
+
+        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
+                dumpPackage);
+        boolean needSep = printedAnything;
+
+        boolean printed = ActivityStackSupervisor.printThisActivity(pw,
+                mStackSupervisor.getTopResumedActivity(),  dumpPackage, needSep,
+                "  ResumedActivity: ");
+        if (printed) {
+            printedAnything = true;
+            needSep = false;
+        }
+
+        if (dumpPackage == null) {
+            if (needSep) {
+                pw.println();
+            }
+            printedAnything = true;
+            mStackSupervisor.dump(pw, "  ");
+        }
+
+        if (!printedAnything) {
+            pw.println("  (nothing)");
+        }
+    }
+
+    void dumpActivityContainersLocked(PrintWriter pw) {
+        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity containers)");
+        mStackSupervisor.dumpChildrenNames(pw, " ");
+        pw.println(" ");
+    }
+
+    void dumpActivityStarterLocked(PrintWriter pw, String dumpPackage) {
+        pw.println("ACTIVITY MANAGER STARTER (dumpsys activity starter)");
+        getActivityStartController().dump(pw, "", dumpPackage);
+    }
+
+    /**
+     * There are three things that cmd can be:
+     *  - a flattened component name that matches an existing activity
+     *  - the cmd arg isn't the flattened component name of an existing activity:
+     *    dump all activity whose component contains the cmd as a substring
+     *  - A hex number of the ActivityRecord object instance.
+     *
+     *  @param dumpVisibleStacksOnly dump activity with {@param name} only if in a visible stack
+     *  @param dumpFocusedStackOnly dump activity with {@param name} only if in the focused stack
+     */
+    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
+            int opti, boolean dumpAll, boolean dumpVisibleStacksOnly, boolean dumpFocusedStackOnly) {
+        ArrayList<ActivityRecord> activities;
+
+        synchronized (mGlobalLock) {
+            activities = mStackSupervisor.getDumpActivitiesLocked(name, dumpVisibleStacksOnly,
+                    dumpFocusedStackOnly);
+        }
+
+        if (activities.size() <= 0) {
+            return false;
+        }
+
+        String[] newArgs = new String[args.length - opti];
+        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
+
+        TaskRecord lastTask = null;
+        boolean needSep = false;
+        for (int i = activities.size() - 1; i >= 0; i--) {
+            ActivityRecord r = activities.get(i);
+            if (needSep) {
+                pw.println();
+            }
+            needSep = true;
+            synchronized (mGlobalLock) {
+                final TaskRecord task = r.getTask();
+                if (lastTask != task) {
+                    lastTask = task;
+                    pw.print("TASK "); pw.print(lastTask.affinity);
+                    pw.print(" id="); pw.print(lastTask.taskId);
+                    pw.print(" userId="); pw.println(lastTask.userId);
+                    if (dumpAll) {
+                        lastTask.dump(pw, "  ");
+                    }
+                }
+            }
+            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
+        }
+        return true;
+    }
+
+    /**
+     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
+     * there is a thread associated with the activity.
+     */
+    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
+            final ActivityRecord r, String[] args, boolean dumpAll) {
+        String innerPrefix = prefix + "  ";
+        synchronized (mGlobalLock) {
+            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
+            pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
+            pw.print(" pid=");
+            if (r.hasProcess()) pw.println(r.app.getPid());
+            else pw.println("(not running)");
+            if (dumpAll) {
+                r.dump(pw, innerPrefix);
+            }
+        }
+        if (r.attachedToProcess()) {
+            // flush anything that is already in the PrintWriter since the thread is going
+            // to write to the file descriptor directly
+            pw.flush();
+            try {
+                TransferPipe tp = new TransferPipe();
+                try {
+                    r.app.getThread().dumpActivity(tp.getWriteFd(),
+                            r.appToken, innerPrefix, args);
+                    tp.go(fd);
+                } finally {
+                    tp.kill();
+                }
+            } catch (IOException e) {
+                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
+            } catch (RemoteException e) {
+                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
+            }
         }
     }
 
@@ -5870,6 +6076,13 @@
         }
 
         @Override
+        public void onPackageReplaced(ApplicationInfo aInfo) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
+            }
+        }
+
+        @Override
         public CompatibilityInfo compatibilityInfoForPackage(ApplicationInfo ai) {
             synchronized (mGlobalLock) {
                 return compatibilityInfoForPackageLocked(ai);
@@ -6037,5 +6250,469 @@
                 });
             }
         }
+
+        @Override
+        public void handleAppDied(WindowProcessController wpc, boolean restarting,
+                Runnable finishInstrumentationCallback) {
+            synchronized (mGlobalLock) {
+                // Remove this application's activities from active lists.
+                boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(wpc);
+
+                wpc.clearRecentTasks();
+                wpc.clearActivities();
+
+                if (wpc.isInstrumenting()) {
+                    finishInstrumentationCallback.run();
+                }
+
+                mWindowManager.deferSurfaceLayout();
+                try {
+                    if (!restarting && hasVisibleActivities
+                            && !mStackSupervisor.resumeFocusedStacksTopActivitiesLocked()) {
+                        // If there was nothing to resume, and we are not already restarting this
+                        // process, but there is a visible activity that is hosted by the process...
+                        // then make sure all visible activities are running, taking care of
+                        // restarting this process.
+                        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
+                    }
+                } finally {
+                    mWindowManager.continueSurfaceLayout();
+                }
+            }
+        }
+
+        @Override
+        public void closeSystemDialogs(String reason) {
+            enforceNotIsolatedCaller("closeSystemDialogs");
+
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long origId = Binder.clearCallingIdentity();
+            try {
+                synchronized (mGlobalLock) {
+                    // Only allow this from foreground processes, so that background
+                    // applications can't abuse it to prevent system UI from being shown.
+                    if (uid >= FIRST_APPLICATION_UID) {
+                        final WindowProcessController proc = mPidMap.get(pid);
+                        if (!proc.isPerceptible()) {
+                            Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
+                                    + " from background process " + proc);
+                            return;
+                        }
+                    }
+                    Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
+                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
+                            | Intent.FLAG_RECEIVER_FOREGROUND);
+                    if (reason != null) {
+                        intent.putExtra("reason", reason);
+                    }
+                    mWindowManager.closeSystemDialogs(reason);
+
+                    mStackSupervisor.closeSystemDialogsLocked();
+
+                    mAm.broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
+                            OP_NONE, null, false, false,
+                            -1, SYSTEM_UID, UserHandle.USER_ALL);
+                }
+            } finally {
+                Binder.restoreCallingIdentity(origId);
+            }
+        }
+
+        @Override
+        public void cleanupDisabledPackageComponents(
+                String packageName, Set<String> disabledClasses, int userId, boolean booted) {
+            synchronized (mGlobalLock) {
+                // Clean-up disabled activities.
+                if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
+                        packageName, disabledClasses, true, false, userId) && booted) {
+                    mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+                    mStackSupervisor.scheduleIdleLocked();
+                }
+
+                // Clean-up disabled tasks
+                getRecentTasks().cleanupDisabledPackageTasksLocked(
+                        packageName, disabledClasses, userId);
+            }
+        }
+
+        @Override
+        public boolean onForceStopPackage(String packageName, boolean doit, boolean evenPersistent,
+                int userId) {
+            synchronized (mGlobalLock) {
+
+                boolean didSomething =
+                        getActivityStartController().clearPendingActivityLaunches(packageName);
+                didSomething |= mStackSupervisor.finishDisabledPackageActivitiesLocked(packageName,
+                        null, doit, evenPersistent, userId);
+                return didSomething;
+            }
+        }
+
+        @Override
+        public void resumeTopActivities(boolean scheduleIdle) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.resumeFocusedStacksTopActivitiesLocked();
+                if (scheduleIdle) {
+                    mStackSupervisor.scheduleIdleLocked();
+                }
+            }
+        }
+
+        @Override
+        public void preBindApplication(WindowProcessController wpc) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.getActivityMetricsLogger().notifyBindApplication(wpc.mInfo);
+            }
+        }
+
+        @Override
+        public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
+            synchronized (mGlobalLock) {
+                return mStackSupervisor.attachApplicationLocked(wpc);
+            }
+        }
+
+        @Override
+        public void notifyLockedProfile(@UserIdInt int userId, int currentUserId) {
+            try {
+                if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
+                    throw new SecurityException("Only privileged app can call notifyLockedProfile");
+                }
+            } catch (RemoteException ex) {
+                throw new SecurityException("Fail to check is caller a privileged app", ex);
+            }
+
+            synchronized (mGlobalLock) {
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    if (mAmInternal.shouldConfirmCredentials(userId)) {
+                        if (mKeyguardController.isKeyguardLocked()) {
+                            // Showing launcher to avoid user entering credential twice.
+                            startHomeActivity(currentUserId, "notifyLockedProfile");
+                        }
+                        mStackSupervisor.lockAllProfileTasks(userId);
+                    }
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+
+        @Override
+        public void startConfirmDeviceCredentialIntent(Intent intent, Bundle options) {
+            mAmInternal.enforceCallingPermission(
+                    MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
+
+            synchronized (mGlobalLock) {
+                final long ident = Binder.clearCallingIdentity();
+                try {
+                    intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS |
+                            FLAG_ACTIVITY_TASK_ON_HOME);
+                    ActivityOptions activityOptions = options != null
+                            ? new ActivityOptions(options) : ActivityOptions.makeBasic();
+                    activityOptions.setLaunchTaskId(
+                            mStackSupervisor.getDefaultDisplayHomeActivity().getTask().taskId);
+                    mContext.startActivityAsUser(intent, activityOptions.toBundle(),
+                            UserHandle.CURRENT);
+                } finally {
+                    Binder.restoreCallingIdentity(ident);
+                }
+            }
+        }
+
+        @Override
+        public void writeActivitiesToProto(ProtoOutputStream proto) {
+            synchronized (mGlobalLock) {
+                // The output proto of "activity --proto activities"
+                // is ActivityManagerServiceDumpActivitiesProto
+                mStackSupervisor.writeToProto(proto,
+                        ActivityManagerServiceDumpActivitiesProto.ACTIVITY_STACK_SUPERVISOR);
+            }
+        }
+
+        @Override
+        public void saveANRState(String reason) {
+            synchronized (mGlobalLock) {
+                final StringWriter sw = new StringWriter();
+                final PrintWriter pw = new FastPrintWriter(sw, false, 1024);
+                pw.println("  ANR time: " + DateFormat.getDateTimeInstance().format(new Date()));
+                if (reason != null) {
+                    pw.println("  Reason: " + reason);
+                }
+                pw.println();
+                getActivityStartController().dump(pw, "  ", null);
+                pw.println();
+                pw.println("-------------------------------------------------------------------------------");
+                dumpActivitiesLocked(null /* fd */, pw, null /* args */, 0 /* opti */,
+                        true /* dumpAll */, false /* dumpClient */, null /* dumpPackage */,
+                        "" /* header */);
+                pw.println();
+                pw.close();
+
+                mLastANRState = sw.toString();
+            }
+        }
+
+        @Override
+        public void clearSavedANRState() {
+            synchronized (mGlobalLock) {
+                mLastANRState = null;
+            }
+        }
+
+        @Override
+        public void dump(String cmd, FileDescriptor fd, PrintWriter pw, String[] args, int opti,
+                boolean dumpAll, boolean dumpClient, String dumpPackage) {
+            synchronized (mGlobalLock) {
+                if (DUMP_ACTIVITIES_CMD.equals(cmd) || DUMP_ACTIVITIES_SHORT_CMD.equals(cmd)) {
+                    dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
+                } else if (DUMP_LASTANR_CMD.equals(cmd)) {
+                    dumpLastANRLocked(pw);
+                } else if (DUMP_LASTANR_TRACES_CMD.equals(cmd)) {
+                    dumpLastANRTracesLocked(pw);
+                } else if (DUMP_STARTER_CMD.equals(cmd)) {
+                    dumpActivityStarterLocked(pw, dumpPackage);
+                } else if (DUMP_CONTAINERS_CMD.equals(cmd)) {
+                    dumpActivityContainersLocked(pw);
+                } else if (DUMP_RECENTS_CMD.equals(cmd) || DUMP_RECENTS_SHORT_CMD.equals(cmd)) {
+                    if (getRecentTasks() != null) {
+                        getRecentTasks().dump(pw, dumpAll, dumpPackage);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public boolean dumpForProcesses(FileDescriptor fd, PrintWriter pw, boolean dumpAll,
+                String dumpPackage, int dumpAppId, boolean needSep, boolean testPssMode,
+                int wakefulness) {
+            synchronized (mGlobalLock) {
+                if (mHomeProcess != null && (dumpPackage == null
+                        || mHomeProcess.mPkgList.contains(dumpPackage))) {
+                    if (needSep) {
+                        pw.println();
+                        needSep = false;
+                    }
+                    pw.println("  mHomeProcess: " + mHomeProcess);
+                }
+                if (mPreviousProcess != null && (dumpPackage == null
+                        || mPreviousProcess.mPkgList.contains(dumpPackage))) {
+                    if (needSep) {
+                        pw.println();
+                        needSep = false;
+                    }
+                    pw.println("  mPreviousProcess: " + mPreviousProcess);
+                }
+                if (dumpAll && (mPreviousProcess == null || dumpPackage == null
+                        || mPreviousProcess.mPkgList.contains(dumpPackage))) {
+                    StringBuilder sb = new StringBuilder(128);
+                    sb.append("  mPreviousProcessVisibleTime: ");
+                    TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
+                    pw.println(sb);
+                }
+                if (mHeavyWeightProcess != null && (dumpPackage == null
+                        || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
+                    if (needSep) {
+                        pw.println();
+                        needSep = false;
+                    }
+                    pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
+                }
+                if (dumpPackage == null) {
+                    pw.println("  mGlobalConfiguration: " + getGlobalConfiguration());
+                    mStackSupervisor.dumpDisplayConfigs(pw, "  ");
+                }
+                if (dumpAll) {
+                    if (dumpPackage == null) {
+                        pw.println("  mConfigWillChange: "
+                                + getTopDisplayFocusedStack().mConfigWillChange);
+                    }
+                    if (mCompatModePackages.getPackages().size() > 0) {
+                        boolean printed = false;
+                        for (Map.Entry<String, Integer> entry
+                                : mCompatModePackages.getPackages().entrySet()) {
+                            String pkg = entry.getKey();
+                            int mode = entry.getValue();
+                            if (dumpPackage != null && !dumpPackage.equals(pkg)) {
+                                continue;
+                            }
+                            if (!printed) {
+                                pw.println("  mScreenCompatPackages:");
+                                printed = true;
+                            }
+                            pw.println("    " + pkg + ": " + mode);
+                        }
+                    }
+                }
+
+                if (dumpPackage == null) {
+                    pw.println("  mWakefulness="
+                            + PowerManagerInternal.wakefulnessToString(wakefulness));
+                    pw.println("  mSleepTokens=" + mStackSupervisor.mSleepTokens);
+                    if (mRunningVoice != null) {
+                        pw.println("  mRunningVoice=" + mRunningVoice);
+                        pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
+                    }
+                    pw.println("  mSleeping=" + mSleeping);
+                    pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
+                    pw.println("  mVrController=" + mVrController);
+                }
+                if (mCurAppTimeTracker != null) {
+                    mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
+                }
+                if (mAllowAppSwitchUids.size() > 0) {
+                    boolean printed = false;
+                    for (int i = 0; i < mAllowAppSwitchUids.size(); i++) {
+                        ArrayMap<String, Integer> types = mAllowAppSwitchUids.valueAt(i);
+                        for (int j = 0; j < types.size(); j++) {
+                            if (dumpPackage == null ||
+                                    UserHandle.getAppId(types.valueAt(j).intValue()) == dumpAppId) {
+                                if (needSep) {
+                                    pw.println();
+                                    needSep = false;
+                                }
+                                if (!printed) {
+                                    pw.println("  mAllowAppSwitchUids:");
+                                    printed = true;
+                                }
+                                pw.print("    User ");
+                                pw.print(mAllowAppSwitchUids.keyAt(i));
+                                pw.print(": Type ");
+                                pw.print(types.keyAt(j));
+                                pw.print(" = ");
+                                UserHandle.formatUid(pw, types.valueAt(j).intValue());
+                                pw.println();
+                            }
+                        }
+                    }
+                }
+                if (dumpPackage == null) {
+                    if (mController != null) {
+                        pw.println("  mController=" + mController
+                                + " mControllerIsAMonkey=" + mControllerIsAMonkey);
+                    }
+                    pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
+                    pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
+                }
+
+                return needSep;
+            }
+        }
+
+        @Override
+        public void writeProcessesToProto(ProtoOutputStream proto, String dumpPackage) {
+            synchronized (mGlobalLock) {
+                if (dumpPackage == null) {
+                    getGlobalConfiguration().writeToProto(proto, GLOBAL_CONFIGURATION);
+                    proto.write(CONFIG_WILL_CHANGE, getTopDisplayFocusedStack().mConfigWillChange);
+                    writeSleepStateToProto(proto);
+                    if (mController != null) {
+                        final long token = proto.start(CONTROLLER);
+                        proto.write(CONTROLLER, mController.toString());
+                        proto.write(IS_A_MONKEY, mControllerIsAMonkey);
+                        proto.end(token);
+                    }
+                    mStackSupervisor.mGoingToSleep.writeToProto(proto, GOING_TO_SLEEP);
+                    mStackSupervisor.mLaunchingActivity.writeToProto(proto, LAUNCHING_ACTIVITY);
+                }
+
+                if (mHomeProcess != null && (dumpPackage == null
+                        || mHomeProcess.mPkgList.contains(dumpPackage))) {
+                    ((ProcessRecord) mHomeProcess.mOwner).writeToProto(proto, HOME_PROC);
+                }
+
+                if (mPreviousProcess != null && (dumpPackage == null
+                        || mPreviousProcess.mPkgList.contains(dumpPackage))) {
+                    ((ProcessRecord) mPreviousProcess.mOwner).writeToProto(proto, PREVIOUS_PROC);
+                    proto.write(PREVIOUS_PROC_VISIBLE_TIME_MS, mPreviousProcessVisibleTime);
+                }
+
+                if (mHeavyWeightProcess != null && (dumpPackage == null
+                        || mHeavyWeightProcess.mPkgList.contains(dumpPackage))) {
+                    ((ProcessRecord) mHeavyWeightProcess.mOwner).writeToProto(
+                            proto, HEAVY_WEIGHT_PROC);
+                }
+
+                for (Map.Entry<String, Integer> entry
+                        : mCompatModePackages.getPackages().entrySet()) {
+                    String pkg = entry.getKey();
+                    int mode = entry.getValue();
+                    if (dumpPackage == null || dumpPackage.equals(pkg)) {
+                        long compatToken = proto.start(SCREEN_COMPAT_PACKAGES);
+                        proto.write(PACKAGE, pkg);
+                        proto.write(MODE, mode);
+                        proto.end(compatToken);
+                    }
+                }
+
+                if (mCurAppTimeTracker != null) {
+                    mCurAppTimeTracker.writeToProto(proto, CURRENT_TRACKER, true);
+                }
+
+            }
+        }
+
+        @Override
+        public boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name,
+                String[] args, int opti, boolean dumpAll, boolean dumpVisibleStacksOnly,
+                boolean dumpFocusedStackOnly) {
+            synchronized (mGlobalLock) {
+                return ActivityTaskManagerService.this.dumpActivity(fd, pw, name, args, opti,
+                        dumpAll, dumpVisibleStacksOnly, dumpFocusedStackOnly);
+            }
+        }
+
+        @Override
+        public boolean canGcNow() {
+            synchronized (mGlobalLock) {
+                return isSleeping() || mStackSupervisor.allResumedActivitiesIdle();
+            }
+        }
+
+        @Override
+        public WindowProcessController getTopApp() {
+            synchronized (mGlobalLock) {
+                final ActivityRecord top = mStackSupervisor.getTopResumedActivity();
+                return top != null ? top.app : null;
+            }
+        }
+
+        @Override
+        public void rankTaskLayersIfNeeded() {
+            synchronized (mGlobalLock) {
+                if (mStackSupervisor != null) {
+                    mStackSupervisor.rankTaskLayersIfNeeded();
+                }
+            }
+        }
+
+        @Override
+        public void scheduleDestroyAllActivities(String reason) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.scheduleDestroyAllActivities(null, reason);
+            }
+        }
+
+        @Override
+        public void removeUser(int userId) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.removeUserLocked(userId);
+            }
+        }
+
+        @Override
+        public boolean switchUser(int userId, UserState userState) {
+            synchronized (mGlobalLock) {
+                return mStackSupervisor.switchUserLocked(userId, userState);
+            }
+        }
+
+        @Override
+        public void onHandleAppCrash(WindowProcessController wpc) {
+            synchronized (mGlobalLock) {
+                mStackSupervisor.handleAppCrashLocked(wpc);
+            }
+        }
     }
 }