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);
+            }
+        }
     }
 }
