1c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner/*
2c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * Copyright (C) 2013 The Android Open Source Project
3c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner *
4c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * Licensed under the Apache License, Version 2.0 (the "License");
5c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * you may not use this file except in compliance with the License.
6c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * You may obtain a copy of the License at
7c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner *
8c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner *      http://www.apache.org/licenses/LICENSE-2.0
9c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner *
10c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * Unless required by applicable law or agreed to in writing, software
11c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * distributed under the License is distributed on an "AS IS" BASIS,
12c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * See the License for the specific language governing permissions and
14c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner * limitations under the License.
15c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner */
16c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
17c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautnerpackage com.android.server.wm;
18c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
19f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautnerimport static com.android.server.wm.WindowManagerService.DEBUG_TASK_MOVEMENT;
20f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautnerimport static com.android.server.wm.WindowManagerService.TAG;
21f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautner
2205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautnerimport android.graphics.Rect;
23f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautnerimport android.os.Debug;
242c2549c5f44b712dbbf66a69d91f07d6f5336ee6Craig Mautnerimport android.util.EventLog;
25f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautnerimport android.util.Slog;
2605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautnerimport android.util.TypedValue;
272c2549c5f44b712dbbf66a69d91f07d6f5336ee6Craig Mautnerimport com.android.server.EventLogTags;
2805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
2900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautnerimport java.io.PrintWriter;
30c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautnerimport java.util.ArrayList;
31c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
32c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautnerpublic class TaskStack {
3305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** Amount of time in milliseconds to animate the dim surface from one value to another,
3405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner     * when no window animation is driving it. */
3505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    private static final int DEFAULT_DIM_DURATION = 200;
3605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
3700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    /** Unique identifier */
38c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner    final int mStackId;
3900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner
4005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** The service */
4105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    private final WindowManagerService mService;
4205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
4300af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    /** The display this stack sits under. */
44df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner    private DisplayContent mDisplayContent;
4500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner
4600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    /** The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match
4700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner     * mTaskHistory in the ActivityStack with the same mStackId */
482c2549c5f44b712dbbf66a69d91f07d6f5336ee6Craig Mautner    private final ArrayList<Task> mTasks = new ArrayList<Task>();
4900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner
50b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    /** For comparison with DisplayContent bounds. */
51b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    private Rect mTmpRect = new Rect();
52b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner
53b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    /** Content limits relative to the DisplayContent this sits in. */
54b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    private Rect mBounds = new Rect();
55b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner
56b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    /** Whether mBounds is fullscreen */
57b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    private boolean mFullscreen = true;
58c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
5905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND} */
60b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    private DimLayer mDimLayer;
6105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
6205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer. */
6305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    WindowStateAnimator mDimWinAnimator;
6405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
6505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */
66df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner    DimLayer mAnimationBackgroundSurface;
6705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
6805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** The particular window with an Animation with non-zero background color. */
6905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    WindowStateAnimator mAnimationBackgroundAnimator;
7005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
7105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    /** Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end
7205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner     * then stop any dimming. */
7305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    boolean mDimmingTag;
7405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
75dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner    /** Application tokens that are exiting, but still on screen for animations. */
76dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner    final AppTokenList mExitingAppTokens = new AppTokenList();
77dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner
7895da1087ed3c7b9983b571bc5409827ae390f15fCraig Mautner    /** Detach this stack from its display when animation completes. */
7995da1087ed3c7b9983b571bc5409827ae390f15fCraig Mautner    boolean mDeferDetach;
8095da1087ed3c7b9983b571bc5409827ae390f15fCraig Mautner
81df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner    TaskStack(WindowManagerService service, int stackId) {
8205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mService = service;
83c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner        mStackId = stackId;
84bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        // TODO: remove bounds from log, they are always 0.
85bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
86bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                mBounds.right, mBounds.bottom);
87c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner    }
88c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
89c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner    DisplayContent getDisplayContent() {
90c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner        return mDisplayContent;
91c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner    }
92c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
93d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner    ArrayList<Task> getTasks() {
94d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner        return mTasks;
95d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner    }
96d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner
97b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    void resizeWindows() {
98bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        final boolean underStatusBar = mBounds.top == 0;
99bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner
100bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
101bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
102bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
103bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
104bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
105bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
106bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                    final WindowState win = windows.get(winNdx);
107bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                    if (!resizingWindows.contains(win)) {
108bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                        if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG,
109bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                                "setBounds: Resizing " + win);
110bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                        resizingWindows.add(win);
111bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                    }
112bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                    win.mUnderStatusBar = underStatusBar;
113bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner                }
114bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner            }
115bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        }
116bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    }
117bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner
118bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    boolean setBounds(Rect bounds) {
119b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        boolean oldFullscreen = mFullscreen;
120b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        if (mDisplayContent != null) {
121b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner            mDisplayContent.getLogicalDisplayRect(mTmpRect);
122b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner            mFullscreen = mTmpRect.equals(bounds);
123b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        }
124b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner
125b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        if (mBounds.equals(bounds) && oldFullscreen == mFullscreen) {
126bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner            return false;
127bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        }
128bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner
129bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        mDimLayer.setBounds(bounds);
130bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        mAnimationBackgroundSurface.setBounds(bounds);
131bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        mBounds.set(bounds);
132bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner
133bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        return true;
134bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    }
135bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner
136bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    void getBounds(Rect out) {
137b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        out.set(mBounds);
138b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    }
139b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner
140b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner    void updateDisplayInfo() {
141b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        if (mFullscreen && mDisplayContent != null) {
142b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner            mDisplayContent.getLogicalDisplayRect(mTmpRect);
143b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner            setBounds(mTmpRect);
144bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        }
145bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    }
146bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner
147bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    boolean isFullscreen() {
148b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        return mFullscreen;
149d5d5d0f4b8c75c9ed4fea320b4f31740b88dd37eCraig Mautner    }
150d5d5d0f4b8c75c9ed4fea320b4f31740b88dd37eCraig Mautner
1511bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner    boolean isAnimating() {
1521bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
1531bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
1541bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
1551bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
1561bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
157bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner                    final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
1587c9ee19cbd0360a62dc4322169afc1b0b9c9e022Craig Mautner                    if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) {
1591bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner                        return true;
1601bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner                    }
1611bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner                }
1621bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner            }
1631bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner        }
1641bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner        return false;
1651bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner    }
1661bf2b873470d2ba8a4ac218da73516cc2b20aa76Craig Mautner
16700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    /**
16800af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner     * Put a Task in this stack. Used for adding and moving.
16900af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner     * @param task The task to add.
17000af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner     * @param toTop Whether to add it to the top or bottom.
17100af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner     */
172bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    void addTask(Task task, boolean toTop) {
173ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        int stackNdx;
174ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        if (!toTop) {
175ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner            stackNdx = 0;
176ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        } else {
177ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner            stackNdx = mTasks.size();
178e0d50cc15be2c8aa9e4a4aa6cf34cc7cf23c9109Craig Mautner            if (!mService.isCurrentProfileLocked(task.mUserId)) {
179ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                // Place the task below all current user tasks.
180ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                while (--stackNdx >= 0) {
181e0d50cc15be2c8aa9e4a4aa6cf34cc7cf23c9109Craig Mautner                    if (!mService.isCurrentProfileLocked(mTasks.get(stackNdx).mUserId)) {
182ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                        break;
183ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                    }
184ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                }
185e0d50cc15be2c8aa9e4a4aa6cf34cc7cf23c9109Craig Mautner                // Put it above first non-current user task.
186ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                ++stackNdx;
187ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner            }
188ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        }
189ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "addTask: task=" + task + " toTop=" + toTop
190ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                + " pos=" + stackNdx);
191ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        mTasks.add(stackNdx, task);
192ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner
193967212cb542e6eeb308678367b53381bff984c31Craig Mautner        task.mStack = this;
194bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        mDisplayContent.moveStack(this, true);
195dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner        EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.taskId, toTop ? 1 : 0, stackNdx);
196c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner    }
197c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
198bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    void moveTaskToTop(Task task) {
199f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautner        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
200f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautner                + Debug.getCallers(6));
201d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner        mTasks.remove(task);
202bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        addTask(task, true);
203d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner    }
204d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner
205bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    void moveTaskToBottom(Task task) {
206f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautner        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
207d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner        mTasks.remove(task);
208bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        addTask(task, false);
209d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner    }
210d9a22881fda77e208f54f893a804d0001d27a27eCraig Mautner
21100af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    /**
21204a0ea60ac7e20369e63edc4f3f8cedf8425a439Craig Mautner     * Delete a Task from this stack. If it is the last Task in the stack, move this stack to the
21304a0ea60ac7e20369e63edc4f3f8cedf8425a439Craig Mautner     * back.
21400af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner     * @param task The Task to delete.
21500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner     */
216de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner    void removeTask(Task task) {
217f0ac5c87f2a4a7ee8148a7b8d02b55e439ab130cCraig Mautner        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
218de4ef020ec5c3acdc90c4ba43011dda20d98d4ddCraig Mautner        mTasks.remove(task);
219df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        if (mDisplayContent != null) {
220df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner            if (mTasks.isEmpty()) {
221df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner                mDisplayContent.moveStack(this, false);
222df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner            }
223df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner            mDisplayContent.layoutNeeded = true;
22404a0ea60ac7e20369e63edc4f3f8cedf8425a439Craig Mautner        }
225c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner    }
226c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner
227df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner    void attachDisplayContent(DisplayContent displayContent) {
228df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        if (mDisplayContent != null) {
229df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner            throw new IllegalStateException("attachDisplayContent: Already attached");
230df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        }
231df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner
232df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        mDisplayContent = displayContent;
233df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        mDimLayer = new DimLayer(mService, this, displayContent);
234df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent);
235b660b9d8cf6b951b85a35599d636c470795e9a1aCraig Mautner        updateDisplayInfo();
236df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner    }
237df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner
238dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner    void detachDisplay() {
239df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);
240bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner
241bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner        boolean doAnotherLayoutPass = false;
242dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
243bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner            final AppTokenList appWindowTokens = mTasks.get(taskNdx).mAppTokens;
244bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner            for (int appNdx = appWindowTokens.size() - 1; appNdx >= 0; --appNdx) {
245bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner                final WindowList appWindows = appWindowTokens.get(appNdx).allAppWindows;
246bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner                for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) {
247bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner                    mService.removeWindowInnerLocked(null, appWindows.get(winNdx));
248bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner                    doAnotherLayoutPass = true;
249bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner                }
250bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner            }
251dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner        }
252bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner        if (doAnotherLayoutPass) {
253bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner            mService.requestTraversalLocked();
254bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner        }
255bc2a6dff1f0edfb2856377fbdb6378158621bd16Craig Mautner
25605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mAnimationBackgroundSurface.destroySurface();
257df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        mAnimationBackgroundSurface = null;
25805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mDimLayer.destroySurface();
259df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        mDimLayer = null;
260df88d73092c62a1a3cd2b2056ca63ae2e70cc238Craig Mautner        mDisplayContent = null;
26100af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    }
26200af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner
26305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    void resetAnimationBackgroundAnimator() {
26405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mAnimationBackgroundAnimator = null;
26505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mAnimationBackgroundSurface.hide();
26605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
26705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
26805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    private long getDimBehindFadeDuration(long duration) {
26905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        TypedValue tv = new TypedValue();
27005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mService.mContext.getResources().getValue(
27105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
27205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (tv.type == TypedValue.TYPE_FRACTION) {
27305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            duration = (long)tv.getFraction(duration, duration);
27405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
27505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            duration = tv.data;
27605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
27705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        return duration;
27805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
27905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
28005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    boolean animateDimLayers() {
28105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        final int dimLayer;
28205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        final float dimAmount;
28305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (mDimWinAnimator == null) {
28405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            dimLayer = mDimLayer.getLayer();
28505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            dimAmount = 0;
28605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        } else {
28705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
28805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
28905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
29005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        final float targetAlpha = mDimLayer.getTargetAlpha();
29105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (targetAlpha != dimAmount) {
29205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            if (mDimWinAnimator == null) {
29305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                mDimLayer.hide(DEFAULT_DIM_DURATION);
29405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            } else {
29505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
29605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                        ? mDimWinAnimator.mAnimation.computeDurationHint()
29705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                        : DEFAULT_DIM_DURATION;
29805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                if (targetAlpha > dimAmount) {
29905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                    duration = getDimBehindFadeDuration(duration);
30005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                }
30105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                mDimLayer.show(dimLayer, dimAmount, duration);
30205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            }
30305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        } else if (mDimLayer.getLayer() != dimLayer) {
30405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mDimLayer.setLayer(dimLayer);
30505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
30605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (mDimLayer.isAnimating()) {
30705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            if (!mService.okToDisplay()) {
30805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                // Jump to the end of the animation.
30905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                mDimLayer.show();
31005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            } else {
31105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                return mDimLayer.stepAnimation();
31205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            }
31305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
31405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        return false;
31505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
31605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
31705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    void resetDimmingTag() {
31805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mDimmingTag = false;
31905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
32005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
32105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    void setDimmingTag() {
32205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        mDimmingTag = true;
32305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
32405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
32505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    boolean testDimmingTag() {
32605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        return mDimmingTag;
32705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
32805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
32905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    boolean isDimming() {
33005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        return mDimLayer.isDimming();
33105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
33205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
33305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    boolean isDimming(WindowStateAnimator winAnimator) {
33405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
33505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
33605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
33705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    void startDimmingIfNeeded(WindowStateAnimator newWinAnimator) {
33805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        // Only set dim params on the highest dimmed layer.
33905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        final WindowStateAnimator existingDimWinAnimator = mDimWinAnimator;
34005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
34105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
34205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                || !existingDimWinAnimator.mSurfaceShown
34305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
34405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mDimWinAnimator = newWinAnimator;
345c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner        }
34605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
34705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
34805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    void stopDimmingIfNeeded() {
34905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (!mDimmingTag && isDimming()) {
35005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mDimWinAnimator = null;
35105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
35205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
35305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
35405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    void setAnimationBackground(WindowStateAnimator winAnimator, int color) {
35505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        int animLayer = winAnimator.mAnimLayer;
35605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (mAnimationBackgroundAnimator == null
35705d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
35805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mAnimationBackgroundAnimator = winAnimator;
35905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            animLayer = mService.adjustAnimationBackground(winAnimator);
36005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mAnimationBackgroundSurface.show(animLayer - WindowManagerService.LAYER_OFFSET_DIM,
36105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner                    ((color >> 24) & 0xff) / 255f, 0);
36205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
36305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner    }
36405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner
365ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner    void switchUser(int userId) {
366ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        int top = mTasks.size();
367ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
368ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner            Task task = mTasks.get(taskNdx);
369e0d50cc15be2c8aa9e4a4aa6cf34cc7cf23c9109Craig Mautner            if (mService.isCurrentProfileLocked(task.mUserId)) {
370ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                mTasks.remove(taskNdx);
371ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                mTasks.add(task);
372ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner                --top;
373ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner            }
374ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner        }
375ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner    }
376ac6f843c917b68ea8805711965b149a9338e3a0eCraig Mautner
377bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    void close() {
378bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        mDimLayer.mDimSurface.destroy();
379bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner        mAnimationBackgroundSurface.mDimSurface.destroy();
380bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner    }
381bdc748af8ce62778d2ad15040ecdfada6e4635fdCraig Mautner
38200af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    public void dump(String prefix, PrintWriter pw) {
38300af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner        pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
38495da1087ed3c7b9983b571bc5409827ae390f15fCraig Mautner        pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
38500af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner        for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
38600af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner            pw.print(prefix); pw.println(mTasks.get(taskNdx));
38700af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner        }
38805d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (mAnimationBackgroundSurface.isDimming()) {
38905d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            pw.print(prefix); pw.println("mWindowAnimationBackgroundSurface:");
39005d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mAnimationBackgroundSurface.printTo(prefix + "  ", pw);
39105d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
39205d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        if (mDimLayer.isDimming()) {
39305d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            pw.print(prefix); pw.println("mDimLayer:");
39405d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            mDimLayer.printTo(prefix, pw);
39505d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner            pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
39605d290365f0b9ed781ffcb30b38a0c7c6e450e9dCraig Mautner        }
397dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner        if (!mExitingAppTokens.isEmpty()) {
398dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner            pw.println();
399dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner            pw.println("  Exiting application tokens:");
400dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner            for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
401dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner                WindowToken token = mExitingAppTokens.get(i);
402dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner                pw.print("  Exiting App #"); pw.print(i);
403dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner                pw.print(' '); pw.print(token);
404dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner                pw.println(':');
405dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner                token.dump(pw, "    ");
406dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner            }
407dc548483ae90ba26ad9e2e2cb79f4673140edb49Craig Mautner        }
40800af9fe6ae0da5b716212fa754163d90b60c1ee6Craig Mautner    }
4094cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner
4104cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner    @Override
4114cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner    public String toString() {
4124cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner        return "{stackId=" + mStackId + " tasks=" + mTasks + "}";
4134cd0c13f8f765118a24e31548c058b5029481beaCraig Mautner    }
414c00204b4d14d49a0417b44ca21aee4f0d4c466e0Craig Mautner}
415