FileDocCategorySizeDatePackage
TaskStack.javaAPI DocAndroid 5.1 API15158Thu Mar 12 22:22:42 GMT 2015com.android.server.wm

TaskStack

public class TaskStack extends Object

Fields Summary
private static final int
DEFAULT_DIM_DURATION
Amount of time in milliseconds to animate the dim surface from one value to another, when no window animation is driving it.
final int
mStackId
Unique identifier
private final WindowManagerService
mService
The service
private DisplayContent
mDisplayContent
The display this stack sits under.
private final ArrayList
mTasks
The Tasks that define this stack. Oldest Tasks are at the bottom. The ordering must match mTaskHistory in the ActivityStack with the same mStackId
private android.graphics.Rect
mTmpRect
For comparison with DisplayContent bounds.
private android.graphics.Rect
mBounds
Content limits relative to the DisplayContent this sits in.
private boolean
mFullscreen
Whether mBounds is fullscreen
private DimLayer
mDimLayer
Used to support {@link android.view.WindowManager.LayoutParams#FLAG_DIM_BEHIND}
WindowStateAnimator
mDimWinAnimator
The particular window with FLAG_DIM_BEHIND set. If null, hide mDimLayer.
DimLayer
mAnimationBackgroundSurface
Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()}
WindowStateAnimator
mAnimationBackgroundAnimator
The particular window with an Animation with non-zero background color.
boolean
mDimmingTag
Set to false at the start of performLayoutAndPlaceSurfaces. If it is still false by the end then stop any dimming.
final AppTokenList
mExitingAppTokens
Application tokens that are exiting, but still on screen for animations.
boolean
mDeferDetach
Detach this stack from its display when animation completes.
Constructors Summary
TaskStack(WindowManagerService service, int stackId)


        
        mService = service;
        mStackId = stackId;
        // TODO: remove bounds from log, they are always 0.
        EventLog.writeEvent(EventLogTags.WM_STACK_CREATED, stackId, mBounds.left, mBounds.top,
                mBounds.right, mBounds.bottom);
    
Methods Summary
voidaddTask(Task task, boolean toTop)
Put a Task in this stack. Used for adding and moving.

param
task The task to add.
param
toTop Whether to add it to the top or bottom.

        int stackNdx;
        if (!toTop) {
            stackNdx = 0;
        } else {
            stackNdx = mTasks.size();
            if (!mService.isCurrentProfileLocked(task.mUserId)) {
                // Place the task below all current user tasks.
                while (--stackNdx >= 0) {
                    if (!mService.isCurrentProfileLocked(mTasks.get(stackNdx).mUserId)) {
                        break;
                    }
                }
                // Put it above first non-current user task.
                ++stackNdx;
            }
        }
        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "addTask: task=" + task + " toTop=" + toTop
                + " pos=" + stackNdx);
        mTasks.add(stackNdx, task);

        task.mStack = this;
        mDisplayContent.moveStack(this, true);
        EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, task.taskId, toTop ? 1 : 0, stackNdx);
    
booleananimateDimLayers()

        final int dimLayer;
        final float dimAmount;
        if (mDimWinAnimator == null) {
            dimLayer = mDimLayer.getLayer();
            dimAmount = 0;
        } else {
            dimLayer = mDimWinAnimator.mAnimLayer - WindowManagerService.LAYER_OFFSET_DIM;
            dimAmount = mDimWinAnimator.mWin.mAttrs.dimAmount;
        }
        final float targetAlpha = mDimLayer.getTargetAlpha();
        if (targetAlpha != dimAmount) {
            if (mDimWinAnimator == null) {
                mDimLayer.hide(DEFAULT_DIM_DURATION);
            } else {
                long duration = (mDimWinAnimator.mAnimating && mDimWinAnimator.mAnimation != null)
                        ? mDimWinAnimator.mAnimation.computeDurationHint()
                        : DEFAULT_DIM_DURATION;
                if (targetAlpha > dimAmount) {
                    duration = getDimBehindFadeDuration(duration);
                }
                mDimLayer.show(dimLayer, dimAmount, duration);
            }
        } else if (mDimLayer.getLayer() != dimLayer) {
            mDimLayer.setLayer(dimLayer);
        }
        if (mDimLayer.isAnimating()) {
            if (!mService.okToDisplay()) {
                // Jump to the end of the animation.
                mDimLayer.show();
            } else {
                return mDimLayer.stepAnimation();
            }
        }
        return false;
    
voidattachDisplayContent(DisplayContent displayContent)

        if (mDisplayContent != null) {
            throw new IllegalStateException("attachDisplayContent: Already attached");
        }

        mDisplayContent = displayContent;
        mDimLayer = new DimLayer(mService, this, displayContent);
        mAnimationBackgroundSurface = new DimLayer(mService, this, displayContent);
        updateDisplayInfo();
    
voidclose()

        mDimLayer.mDimSurface.destroy();
        mAnimationBackgroundSurface.mDimSurface.destroy();
    
voiddetachDisplay()

        EventLog.writeEvent(EventLogTags.WM_STACK_REMOVED, mStackId);

        boolean doAnotherLayoutPass = false;
        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
            final AppTokenList appWindowTokens = mTasks.get(taskNdx).mAppTokens;
            for (int appNdx = appWindowTokens.size() - 1; appNdx >= 0; --appNdx) {
                final WindowList appWindows = appWindowTokens.get(appNdx).allAppWindows;
                for (int winNdx = appWindows.size() - 1; winNdx >= 0; --winNdx) {
                    mService.removeWindowInnerLocked(null, appWindows.get(winNdx));
                    doAnotherLayoutPass = true;
                }
            }
        }
        if (doAnotherLayoutPass) {
            mService.requestTraversalLocked();
        }

        mAnimationBackgroundSurface.destroySurface();
        mAnimationBackgroundSurface = null;
        mDimLayer.destroySurface();
        mDimLayer = null;
        mDisplayContent = null;
    
public voiddump(java.lang.String prefix, java.io.PrintWriter pw)

        pw.print(prefix); pw.print("mStackId="); pw.println(mStackId);
        pw.print(prefix); pw.print("mDeferDetach="); pw.println(mDeferDetach);
        for (int taskNdx = 0; taskNdx < mTasks.size(); ++taskNdx) {
            pw.print(prefix); pw.println(mTasks.get(taskNdx));
        }
        if (mAnimationBackgroundSurface.isDimming()) {
            pw.print(prefix); pw.println("mWindowAnimationBackgroundSurface:");
            mAnimationBackgroundSurface.printTo(prefix + "  ", pw);
        }
        if (mDimLayer.isDimming()) {
            pw.print(prefix); pw.println("mDimLayer:");
            mDimLayer.printTo(prefix, pw);
            pw.print(prefix); pw.print("mDimWinAnimator="); pw.println(mDimWinAnimator);
        }
        if (!mExitingAppTokens.isEmpty()) {
            pw.println();
            pw.println("  Exiting application tokens:");
            for (int i=mExitingAppTokens.size()-1; i>=0; i--) {
                WindowToken token = mExitingAppTokens.get(i);
                pw.print("  Exiting App #"); pw.print(i);
                pw.print(' "); pw.print(token);
                pw.println(':");
                token.dump(pw, "    ");
            }
        }
    
voidgetBounds(android.graphics.Rect out)

        out.set(mBounds);
    
private longgetDimBehindFadeDuration(long duration)

        TypedValue tv = new TypedValue();
        mService.mContext.getResources().getValue(
                com.android.internal.R.fraction.config_dimBehindFadeDuration, tv, true);
        if (tv.type == TypedValue.TYPE_FRACTION) {
            duration = (long)tv.getFraction(duration, duration);
        } else if (tv.type >= TypedValue.TYPE_FIRST_INT && tv.type <= TypedValue.TYPE_LAST_INT) {
            duration = tv.data;
        }
        return duration;
    
DisplayContentgetDisplayContent()

        return mDisplayContent;
    
java.util.ArrayListgetTasks()

        return mTasks;
    
booleanisAnimating()

        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                    final WindowStateAnimator winAnimator = windows.get(winNdx).mWinAnimator;
                    if (winAnimator.isAnimating() || winAnimator.mWin.mExiting) {
                        return true;
                    }
                }
            }
        }
        return false;
    
booleanisDimming()

        return mDimLayer.isDimming();
    
booleanisDimming(WindowStateAnimator winAnimator)

        return mDimWinAnimator == winAnimator && mDimLayer.isDimming();
    
booleanisFullscreen()

        return mFullscreen;
    
voidmoveTaskToBottom(Task task)

        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToBottom: task=" + task);
        mTasks.remove(task);
        addTask(task, false);
    
voidmoveTaskToTop(Task task)

        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "moveTaskToTop: task=" + task + " Callers="
                + Debug.getCallers(6));
        mTasks.remove(task);
        addTask(task, true);
    
voidremoveTask(Task task)
Delete a Task from this stack. If it is the last Task in the stack, move this stack to the back.

param
task The Task to delete.

        if (DEBUG_TASK_MOVEMENT) Slog.d(TAG, "removeTask: task=" + task);
        mTasks.remove(task);
        if (mDisplayContent != null) {
            if (mTasks.isEmpty()) {
                mDisplayContent.moveStack(this, false);
            }
            mDisplayContent.layoutNeeded = true;
        }
    
voidresetAnimationBackgroundAnimator()

        mAnimationBackgroundAnimator = null;
        mAnimationBackgroundSurface.hide();
    
voidresetDimmingTag()

        mDimmingTag = false;
    
voidresizeWindows()

        final boolean underStatusBar = mBounds.top == 0;

        final ArrayList<WindowState> resizingWindows = mService.mResizingWindows;
        for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) {
            final ArrayList<AppWindowToken> activities = mTasks.get(taskNdx).mAppTokens;
            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
                final ArrayList<WindowState> windows = activities.get(activityNdx).allAppWindows;
                for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
                    final WindowState win = windows.get(winNdx);
                    if (!resizingWindows.contains(win)) {
                        if (WindowManagerService.DEBUG_RESIZE) Slog.d(TAG,
                                "setBounds: Resizing " + win);
                        resizingWindows.add(win);
                    }
                    win.mUnderStatusBar = underStatusBar;
                }
            }
        }
    
voidsetAnimationBackground(WindowStateAnimator winAnimator, int color)

        int animLayer = winAnimator.mAnimLayer;
        if (mAnimationBackgroundAnimator == null
                || animLayer < mAnimationBackgroundAnimator.mAnimLayer) {
            mAnimationBackgroundAnimator = winAnimator;
            animLayer = mService.adjustAnimationBackground(winAnimator);
            mAnimationBackgroundSurface.show(animLayer - WindowManagerService.LAYER_OFFSET_DIM,
                    ((color >> 24) & 0xff) / 255f, 0);
        }
    
booleansetBounds(android.graphics.Rect bounds)

        boolean oldFullscreen = mFullscreen;
        if (mDisplayContent != null) {
            mDisplayContent.getLogicalDisplayRect(mTmpRect);
            mFullscreen = mTmpRect.equals(bounds);
        }

        if (mBounds.equals(bounds) && oldFullscreen == mFullscreen) {
            return false;
        }

        mDimLayer.setBounds(bounds);
        mAnimationBackgroundSurface.setBounds(bounds);
        mBounds.set(bounds);

        return true;
    
voidsetDimmingTag()

        mDimmingTag = true;
    
voidstartDimmingIfNeeded(WindowStateAnimator newWinAnimator)

        // Only set dim params on the highest dimmed layer.
        final WindowStateAnimator existingDimWinAnimator = mDimWinAnimator;
        // Don't turn on for an unshown surface, or for any layer but the highest dimmed layer.
        if (newWinAnimator.mSurfaceShown && (existingDimWinAnimator == null
                || !existingDimWinAnimator.mSurfaceShown
                || existingDimWinAnimator.mAnimLayer < newWinAnimator.mAnimLayer)) {
            mDimWinAnimator = newWinAnimator;
        }
    
voidstopDimmingIfNeeded()

        if (!mDimmingTag && isDimming()) {
            mDimWinAnimator = null;
        }
    
voidswitchUser(int userId)

        int top = mTasks.size();
        for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
            Task task = mTasks.get(taskNdx);
            if (mService.isCurrentProfileLocked(task.mUserId)) {
                mTasks.remove(taskNdx);
                mTasks.add(task);
                --top;
            }
        }
    
booleantestDimmingTag()

        return mDimmingTag;
    
public java.lang.StringtoString()

        return "{stackId=" + mStackId + " tasks=" + mTasks + "}";
    
voidupdateDisplayInfo()

        if (mFullscreen && mDisplayContent != null) {
            mDisplayContent.getLogicalDisplayRect(mTmpRect);
            setBounds(mTmpRect);
        }