Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b59db97f authored by Winson Chung's avatar Winson Chung Committed by Android (Google) Code Review
Browse files

Merge "Updating freeform layout to be static at the top of recents."

parents 7cc4db18 a5e6b360
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -189,6 +189,7 @@ public class ParametricCurve {
    public float computePOffsetForScaledHeight(int height, Rect bounds) {
    public float computePOffsetForScaledHeight(int height, Rect bounds) {
        int top = bounds.top;
        int top = bounds.top;
        int bottom = bounds.bottom;
        int bottom = bounds.bottom;
        height = Math.min(height, bottom - top);


        if (bounds.height() == 0) {
        if (bounds.height() == 0) {
            return 0;
            return 0;
@@ -231,6 +232,7 @@ public class ParametricCurve {
    public float computePOffsetForHeight(int height, Rect bounds) {
    public float computePOffsetForHeight(int height, Rect bounds) {
        int top = bounds.top;
        int top = bounds.top;
        int bottom = bounds.bottom;
        int bottom = bounds.bottom;
        height = Math.min(height, bottom - top);


        if (bounds.height() == 0) {
        if (bounds.height() == 0) {
            return 0;
            return 0;
+9 −0
Original line number Original line Diff line number Diff line
@@ -235,6 +235,15 @@ public class SystemServicesProxy {
        return null;
        return null;
    }
    }


    /**
     * Returns whether this device has freeform workspaces.
     */
    public boolean hasFreeformWorkspaceSupport() {
        if (mPm == null) return false;

        return mPm.hasSystemFeature(PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT);
    }

    /** Returns whether the recents is currently running */
    /** Returns whether the recents is currently running */
    public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask,
    public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask,
            MutableBoolean isHomeTopMost) {
            MutableBoolean isHomeTopMost) {
+25 −15
Original line number Original line Diff line number Diff line
@@ -17,10 +17,11 @@
package com.android.systemui.recents.views;
package com.android.systemui.recents.views;


import android.util.Log;
import android.util.Log;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.Task;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashMap;
import java.util.List;


/**
/**
 * The layout logic for the contents of the freeform workspace.
 * The layout logic for the contents of the freeform workspace.
@@ -33,6 +34,7 @@ public class FreeformWorkspaceLayoutAlgorithm {
    // The number of cells in the freeform workspace
    // The number of cells in the freeform workspace
    private int mFreeformCellXCount;
    private int mFreeformCellXCount;
    private int mFreeformCellYCount;
    private int mFreeformCellYCount;

    // The width and height of the cells in the freeform workspace
    // The width and height of the cells in the freeform workspace
    private int mFreeformCellWidth;
    private int mFreeformCellWidth;
    private int mFreeformCellHeight;
    private int mFreeformCellHeight;
@@ -44,22 +46,26 @@ public class FreeformWorkspaceLayoutAlgorithm {
     * Updates the layout for each of the freeform workspace tasks.  This is called after the stack
     * Updates the layout for each of the freeform workspace tasks.  This is called after the stack
     * layout is updated.
     * layout is updated.
     */
     */
    public void update(ArrayList<Task> freeformTasks, TaskStackLayoutAlgorithm stackLayout) {
    public void update(List<Task> freeformTasks, TaskStackLayoutAlgorithm stackLayout) {
        mTaskIndexMap.clear();

        int numFreeformTasks = stackLayout.mNumFreeformTasks;
        int numFreeformTasks = stackLayout.mNumFreeformTasks;
        if (!freeformTasks.isEmpty()) {
        if (!freeformTasks.isEmpty()) {
            // Calculate the cell width/height depending on the number of freeform tasks
            // Calculate the cell width/height depending on the number of freeform tasks
            mFreeformCellXCount = Math.max(2, (int) Math.ceil(Math.sqrt(numFreeformTasks)));
            mFreeformCellXCount = Math.max(2, (int) Math.ceil(Math.sqrt(numFreeformTasks)));
            mFreeformCellYCount = Math.max(2, (int) Math.ceil((float) numFreeformTasks / mFreeformCellXCount));
            mFreeformCellYCount = Math.max(2, (int) Math.ceil((float) numFreeformTasks /
            mFreeformCellWidth = stackLayout.mFreeformRect.width() / mFreeformCellXCount;
                    mFreeformCellXCount));
            // For now, make the cells square
            // For now, make the cells square
            mFreeformCellWidth = Math.min(stackLayout.mFreeformRect.width() / mFreeformCellXCount,
                    stackLayout.mFreeformRect.height() / mFreeformCellYCount);
            mFreeformCellHeight = mFreeformCellWidth;
            mFreeformCellHeight = mFreeformCellWidth;


            // Put each of the tasks in the progress map at a fixed index (does not need to actually
            // Put each of the tasks in the progress map at a fixed index (does not need to actually
            // map to a scroll position, just by index)
            // map to a scroll position, just by index)
            int taskCount = freeformTasks.size();
            int taskCount = freeformTasks.size();
            for (int i = 0; i < taskCount; i++) {
            for (int i = taskCount - 1; i >= 0; i--) {
                Task task = freeformTasks.get(i);
                Task task = freeformTasks.get(i);
                mTaskIndexMap.put(task.key, i);
                mTaskIndexMap.put(task.key, taskCount - i - 1);
            }
            }


            if (DEBUG) {
            if (DEBUG) {
@@ -74,24 +80,23 @@ public class FreeformWorkspaceLayoutAlgorithm {
    /**
    /**
     * Returns whether the transform is available for the given task.
     * Returns whether the transform is available for the given task.
     */
     */
    public boolean isTransformAvailable(Task task, float stackScroll,
    public boolean isTransformAvailable(Task task, TaskStackLayoutAlgorithm stackLayout) {
            TaskStackLayoutAlgorithm stackLayout) {
        if (stackLayout.mNumFreeformTasks == 0 || task == null) {
        if (stackLayout.mNumFreeformTasks == 0 || task == null ||
                !mTaskIndexMap.containsKey(task.key)) {
            return false;
            return false;
        }
        }
        return stackScroll > stackLayout.mStackEndScrollP;
        return mTaskIndexMap.containsKey(task.key);
    }
    }


    /**
    /**
     * Returns the transform for the given task.  Any rect returned will be offset by the actual
     * Returns the transform for the given task.  Any rect returned will be offset by the actual
     * transform for the freeform workspace.
     * transform for the freeform workspace.
     */
     */
    public TaskViewTransform getTransform(Task task, float stackScroll,
    public TaskViewTransform getTransform(Task task, TaskViewTransform transformOut,
            TaskViewTransform transformOut, TaskStackLayoutAlgorithm stackLayout) {
            TaskStackLayoutAlgorithm stackLayout) {
        if (Float.compare(stackScroll, stackLayout.mStackEndScrollP) > 0) {
        if (mTaskIndexMap.containsKey(task.key)) {
            // This is a freeform task, so lay it out in the freeform workspace
            // This is a freeform task, so lay it out in the freeform workspace
            int taskIndex = mTaskIndexMap.get(task.key);
            int taskIndex = mTaskIndexMap.get(task.key);
            int topOffset = (stackLayout.mFreeformRect.top - stackLayout.mTaskRect.top);
            int x = taskIndex % mFreeformCellXCount;
            int x = taskIndex % mFreeformCellXCount;
            int y = taskIndex / mFreeformCellXCount;
            int y = taskIndex / mFreeformCellXCount;
            float scale = (float) mFreeformCellWidth / stackLayout.mTaskRect.width();
            float scale = (float) mFreeformCellWidth / stackLayout.mTaskRect.width();
@@ -99,8 +104,13 @@ public class FreeformWorkspaceLayoutAlgorithm {
            int scaleYOffset = (int) (((1f - scale) * stackLayout.mTaskRect.height()) / 2);
            int scaleYOffset = (int) (((1f - scale) * stackLayout.mTaskRect.height()) / 2);
            transformOut.scale = scale * 0.9f;
            transformOut.scale = scale * 0.9f;
            transformOut.translationX = x * mFreeformCellWidth - scaleXOffset;
            transformOut.translationX = x * mFreeformCellWidth - scaleXOffset;
            transformOut.translationY = y * mFreeformCellHeight - scaleYOffset;
            transformOut.translationY = topOffset + y * mFreeformCellHeight - scaleYOffset;
            transformOut.translationZ = stackLayout.mMaxTranslationZ;
            transformOut.rect.set(stackLayout.mTaskRect);
            transformOut.rect.offset(transformOut.translationX, transformOut.translationY);
            Utilities.scaleRectAboutCenter(transformOut.rect, transformOut.scale);
            transformOut.visible = true;
            transformOut.visible = true;
            transformOut.p = 0;
            return transformOut;
            return transformOut;
        }
        }
        return null;
        return null;
+107 −194

File changed.

Preview size limit exceeded, changes collapsed.

+86 −26
Original line number Original line Diff line number Diff line
@@ -281,6 +281,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal


    /**
    /**
     * Gets the stack transforms of a list of tasks, and returns the visible range of tasks.
     * Gets the stack transforms of a list of tasks, and returns the visible range of tasks.
     * This call ignores freeform tasks.
     */
     */
    private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
    private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
                                       ArrayList<Task> tasks,
                                       ArrayList<Task> tasks,
@@ -306,8 +307,16 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        // Update the stack transforms
        // Update the stack transforms
        TaskViewTransform prevTransform = null;
        TaskViewTransform prevTransform = null;
        for (int i = taskCount - 1; i >= 0; i--) {
        for (int i = taskCount - 1; i >= 0; i--) {
            TaskViewTransform transform = mLayoutAlgorithm.getStackTransform(tasks.get(i),
            Task task = tasks.get(i);
                    stackScroll, taskTransforms.get(i), prevTransform);
            if (task.isFreeformTask()) {
                continue;
            }

            TaskViewTransform transform = mLayoutAlgorithm.getStackTransform(task, stackScroll,
                    taskTransforms.get(i), prevTransform);
            if (DEBUG) {
                Log.d(TAG, "updateStackTransform: " + i + ", " + transform.visible);
            }
            if (transform.visible) {
            if (transform.visible) {
                if (frontMostVisibleIndex < 0) {
                if (frontMostVisibleIndex < 0) {
                    frontMostVisibleIndex = i;
                    frontMostVisibleIndex = i;
@@ -327,7 +336,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal


            if (boundTranslationsToRect) {
            if (boundTranslationsToRect) {
                transform.translationY = Math.min(transform.translationY,
                transform.translationY = Math.min(transform.translationY,
                        mLayoutAlgorithm.mStackRect.bottom);
                        mLayoutAlgorithm.mCurrentStackRect.bottom);
            }
            }
            prevTransform = transform;
            prevTransform = transform;
        }
        }
@@ -344,13 +353,13 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
            // Get all the task transforms
            // Get all the task transforms
            ArrayList<Task> tasks = mStack.getTasks();
            ArrayList<Task> tasks = mStack.getTasks();
            float stackScroll = mStackScroller.getStackScroll();
            float stackScroll = mStackScroller.getStackScroll();
            int[] visibleRange = mTmpVisibleRange;
            int[] visibleStackRange = mTmpVisibleRange;
            boolean isValidVisibleRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
            boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
                    stackScroll, visibleRange, false);
                    stackScroll, visibleStackRange, false);
            boolean hasStackBackTransform = false;
            boolean hasStackBackTransform = false;
            boolean hasStackFrontTransform = false;
            boolean hasStackFrontTransform = false;
            if (DEBUG) {
            if (DEBUG) {
                Log.d(TAG, "visibleRange: " + visibleRange[0] + " to " + visibleRange[1]);
                Log.d(TAG, "visibleRange: " + visibleStackRange[0] + " to " + visibleStackRange[1]);
            }
            }


            // Return all the invisible children to the pool
            // Return all the invisible children to the pool
@@ -363,7 +372,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                TaskView tv = taskViews.get(i);
                TaskView tv = taskViews.get(i);
                Task task = tv.getTask();
                Task task = tv.getTask();
                int taskIndex = mStack.indexOfTask(task);
                int taskIndex = mStack.indexOfTask(task);
                if (visibleRange[1] <= taskIndex && taskIndex <= visibleRange[0]) {
                if (task.isFreeformTask() ||
                        visibleStackRange[1] <= taskIndex && taskIndex <= visibleStackRange[0]) {
                    mTmpTaskViewMap.put(task, tv);
                    mTmpTaskViewMap.put(task, tv);
                } else {
                } else {
                    if (tv.isFocusedTask()) {
                    if (tv.isFocusedTask()) {
@@ -371,16 +381,43 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                        lastFocusedTaskIndex = taskIndex;
                        lastFocusedTaskIndex = taskIndex;
                        resetFocusedTask();
                        resetFocusedTask();
                    }
                    }
                    if (DEBUG) {
                        Log.d(TAG, "returning to pool: " + task.key);
                    }
                    mViewPool.returnViewToPool(tv);
                    mViewPool.returnViewToPool(tv);
                }
                }
            }
            }


            // Pick up all the freeform tasks
            int firstVisStackIndex = isValidVisibleStackRange ? visibleStackRange[0] : 0;
            for (int i = mStack.getTaskCount() - 1; i > firstVisStackIndex; i--) {
                Task task = tasks.get(i);
                if (!task.isFreeformTask()) {
                    continue;
                }
                TaskViewTransform transform = mLayoutAlgorithm.getStackTransform(task, stackScroll,
                        mCurrentTaskTransforms.get(i), null);
                TaskView tv = mTmpTaskViewMap.get(task);
                if (tv == null) {
                    if (DEBUG) {
                        Log.d(TAG, "picking up from pool: " + task.key);
                    }
                    tv = mViewPool.pickUpViewFromPool(task, task);
                    if (mLayersDisabled) {
                        tv.disableLayersForOneFrame();
                    }
                }

                // Animate the task into place
                tv.updateViewPropertiesToTaskTransform(transform,
                        mStackViewsAnimationDuration, mRequestUpdateClippingListener);
            }

            // Pick up all the newly visible children and update all the existing children
            // Pick up all the newly visible children and update all the existing children
            for (int i = visibleRange[0]; isValidVisibleRange && i >= visibleRange[1]; i--) {
            for (int i = visibleStackRange[0]; isValidVisibleStackRange && i >= visibleStackRange[1]; i--) {
                Task task = tasks.get(i);
                Task task = tasks.get(i);
                TaskViewTransform transform = mCurrentTaskTransforms.get(i);
                TaskViewTransform transform = mCurrentTaskTransforms.get(i);
                TaskView tv = mTmpTaskViewMap.get(task);
                TaskView tv = mTmpTaskViewMap.get(task);
                int taskIndex = mStack.indexOfTask(task);


                if (tv == null) {
                if (tv == null) {
                    tv = mViewPool.pickUpViewFromPool(task, task);
                    tv = mViewPool.pickUpViewFromPool(task, task);
@@ -409,27 +446,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                }
                }


                // Animate the task into place
                // Animate the task into place
                tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
                tv.updateViewPropertiesToTaskTransform(transform,
                        mStackViewsAnimationDuration, mRequestUpdateClippingListener);
                        mStackViewsAnimationDuration, mRequestUpdateClippingListener);
            }
            }


            // Update the focus if the previous focused task was returned to the view pool
            // Update the focus if the previous focused task was returned to the view pool
            if (lastFocusedTaskIndex != -1) {
            if (lastFocusedTaskIndex != -1) {
                if (lastFocusedTaskIndex < visibleRange[1]) {
                if (lastFocusedTaskIndex < visibleStackRange[1]) {
                    setFocusedTask(visibleRange[1], false, wasLastFocusedTaskAnimated);
                    setFocusedTask(visibleStackRange[1], false, wasLastFocusedTaskAnimated);
                } else {
                } else {
                    setFocusedTask(visibleRange[0], false, wasLastFocusedTaskAnimated);
                    setFocusedTask(visibleStackRange[0], false, wasLastFocusedTaskAnimated);
                }
                }
                }

            // Update the freeform workspace
            mLayoutAlgorithm.getFreeformWorkspaceBounds(stackScroll, mTmpTransform);
            if (mTmpTransform.visible) {
                mTmpTransform.rect.roundOut(mTmpRect);
                mFreeformWorkspaceBackground.setAlpha(255);
                mFreeformWorkspaceBackground.setBounds(mTmpRect);
            } else {
                mFreeformWorkspaceBackground.setAlpha(0);
            }
            }


            // Reset the request-synchronize params
            // Reset the request-synchronize params
@@ -491,6 +518,14 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        // Compute the min and max scroll values
        // Compute the min and max scroll values
        mLayoutAlgorithm.update(mStack);
        mLayoutAlgorithm.update(mStack);


        // Update the freeform workspace
        SystemServicesProxy ssp = Recents.getSystemServices();
        if (ssp.hasFreeformWorkspaceSupport()) {
            mTmpRect.set(mLayoutAlgorithm.mFreeformRect);
            mFreeformWorkspaceBackground.setAlpha(255);
            mFreeformWorkspaceBackground.setBounds(mTmpRect);
        }

        // Debug logging
        // Debug logging
        if (boundScrollToNewMinMax) {
        if (boundScrollToNewMinMax) {
            mStackScroller.boundScroll();
            mStackScroller.boundScroll();
@@ -762,7 +797,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal


    /** Handler for the first layout. */
    /** Handler for the first layout. */
    void onFirstLayout() {
    void onFirstLayout() {
        int offscreenY = mLayoutAlgorithm.mStackRect.bottom;
        int offscreenY = mLayoutAlgorithm.mCurrentStackRect.bottom;


        // Find the launch target task
        // Find the launch target task
        Task launchTargetTask = mStack.getLaunchTarget();
        Task launchTargetTask = mStack.getLaunchTarget();
@@ -863,7 +898,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        mStackScroller.stopScroller();
        mStackScroller.stopScroller();
        mStackScroller.stopBoundScrollAnimation();
        mStackScroller.stopBoundScrollAnimation();
        // Animate all the task views out of view
        // Animate all the task views out of view
        ctx.offscreenTranslationY = mLayoutAlgorithm.mStackRect.bottom;
        ctx.offscreenTranslationY = mLayoutAlgorithm.mCurrentStackRect.bottom;


        List<TaskView> taskViews = getTaskViews();
        List<TaskView> taskViews = getTaskViews();
        int taskViewCount = taskViews.size();
        int taskViewCount = taskViews.size();
@@ -929,6 +964,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        }
        }
    }
    }


    /**
     * Launches the freeform tasks.
     */
    public boolean launchFreeformTasks() {
        Task frontTask = mStack.getFrontMostTask();
        if (frontTask != null && frontTask.isFreeformTask()) {
            onTaskViewClicked(getChildViewForTask(frontTask), frontTask, false);
            return true;
        }
        return false;
    }

    /**** TaskStackCallbacks Implementation ****/
    /**** TaskStackCallbacks Implementation ****/


    @Override
    @Override
@@ -973,6 +1020,19 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                mStackScroller.boundScroll();
                mStackScroller.boundScroll();
            }
            }


            // Animate all the tasks into place
            requestSynchronizeStackViewsWithModel(200);
        } else {
            // Remove the view associated with this task, we can't rely on updateTransforms
            // to work here because the task is no longer in the list
            TaskView tv = getChildViewForTask(removedTask);
            if (tv != null) {
                mViewPool.returnViewToPool(tv);
            }

            // Update the min/max scroll and animate other task views into their new positions
            updateMinMaxScroll(true);

            // Animate all the tasks into place
            // Animate all the tasks into place
            requestSynchronizeStackViewsWithModel(200);
            requestSynchronizeStackViewsWithModel(200);
        }
        }
Loading