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 Diff line number Diff line
@@ -189,6 +189,7 @@ public class ParametricCurve {
    public float computePOffsetForScaledHeight(int height, Rect bounds) {
        int top = bounds.top;
        int bottom = bounds.bottom;
        height = Math.min(height, bottom - top);

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

        if (bounds.height() == 0) {
            return 0;
+9 −0
Original line number Diff line number Diff line
@@ -235,6 +235,15 @@ public class SystemServicesProxy {
        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 */
    public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask,
            MutableBoolean isHomeTopMost) {
+25 −15
Original line number Diff line number Diff line
@@ -17,10 +17,11 @@
package com.android.systemui.recents.views;

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

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

/**
 * 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
    private int mFreeformCellXCount;
    private int mFreeformCellYCount;

    // The width and height of the cells in the freeform workspace
    private int mFreeformCellWidth;
    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
     * 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;
        if (!freeformTasks.isEmpty()) {
            // Calculate the cell width/height depending on the number of freeform tasks
            mFreeformCellXCount = Math.max(2, (int) Math.ceil(Math.sqrt(numFreeformTasks)));
            mFreeformCellYCount = Math.max(2, (int) Math.ceil((float) numFreeformTasks / mFreeformCellXCount));
            mFreeformCellWidth = stackLayout.mFreeformRect.width() / mFreeformCellXCount;
            mFreeformCellYCount = Math.max(2, (int) Math.ceil((float) numFreeformTasks /
                    mFreeformCellXCount));
            // For now, make the cells square
            mFreeformCellWidth = Math.min(stackLayout.mFreeformRect.width() / mFreeformCellXCount,
                    stackLayout.mFreeformRect.height() / mFreeformCellYCount);
            mFreeformCellHeight = mFreeformCellWidth;

            // 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)
            int taskCount = freeformTasks.size();
            for (int i = 0; i < taskCount; i++) {
            for (int i = taskCount - 1; i >= 0; i--) {
                Task task = freeformTasks.get(i);
                mTaskIndexMap.put(task.key, i);
                mTaskIndexMap.put(task.key, taskCount - i - 1);
            }

            if (DEBUG) {
@@ -74,24 +80,23 @@ public class FreeformWorkspaceLayoutAlgorithm {
    /**
     * Returns whether the transform is available for the given task.
     */
    public boolean isTransformAvailable(Task task, float stackScroll,
            TaskStackLayoutAlgorithm stackLayout) {
        if (stackLayout.mNumFreeformTasks == 0 || task == null ||
                !mTaskIndexMap.containsKey(task.key)) {
    public boolean isTransformAvailable(Task task, TaskStackLayoutAlgorithm stackLayout) {
        if (stackLayout.mNumFreeformTasks == 0 || task == null) {
            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
     * transform for the freeform workspace.
     */
    public TaskViewTransform getTransform(Task task, float stackScroll,
            TaskViewTransform transformOut, TaskStackLayoutAlgorithm stackLayout) {
        if (Float.compare(stackScroll, stackLayout.mStackEndScrollP) > 0) {
    public TaskViewTransform getTransform(Task task, TaskViewTransform transformOut,
            TaskStackLayoutAlgorithm stackLayout) {
        if (mTaskIndexMap.containsKey(task.key)) {
            // This is a freeform task, so lay it out in the freeform workspace
            int taskIndex = mTaskIndexMap.get(task.key);
            int topOffset = (stackLayout.mFreeformRect.top - stackLayout.mTaskRect.top);
            int x = taskIndex % mFreeformCellXCount;
            int y = taskIndex / mFreeformCellXCount;
            float scale = (float) mFreeformCellWidth / stackLayout.mTaskRect.width();
@@ -99,8 +104,13 @@ public class FreeformWorkspaceLayoutAlgorithm {
            int scaleYOffset = (int) (((1f - scale) * stackLayout.mTaskRect.height()) / 2);
            transformOut.scale = scale * 0.9f;
            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.p = 0;
            return transformOut;
        }
        return null;
+107 −194

File changed.

Preview size limit exceeded, changes collapsed.

+86 −26
Original line number 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.
     * This call ignores freeform tasks.
     */
    private boolean updateStackTransforms(ArrayList<TaskViewTransform> taskTransforms,
                                       ArrayList<Task> tasks,
@@ -306,8 +307,16 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        // Update the stack transforms
        TaskViewTransform prevTransform = null;
        for (int i = taskCount - 1; i >= 0; i--) {
            TaskViewTransform transform = mLayoutAlgorithm.getStackTransform(tasks.get(i),
                    stackScroll, taskTransforms.get(i), prevTransform);
            Task task = tasks.get(i);
            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 (frontMostVisibleIndex < 0) {
                    frontMostVisibleIndex = i;
@@ -327,7 +336,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal

            if (boundTranslationsToRect) {
                transform.translationY = Math.min(transform.translationY,
                        mLayoutAlgorithm.mStackRect.bottom);
                        mLayoutAlgorithm.mCurrentStackRect.bottom);
            }
            prevTransform = transform;
        }
@@ -344,13 +353,13 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
            // Get all the task transforms
            ArrayList<Task> tasks = mStack.getTasks();
            float stackScroll = mStackScroller.getStackScroll();
            int[] visibleRange = mTmpVisibleRange;
            boolean isValidVisibleRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
                    stackScroll, visibleRange, false);
            int[] visibleStackRange = mTmpVisibleRange;
            boolean isValidVisibleStackRange = updateStackTransforms(mCurrentTaskTransforms, tasks,
                    stackScroll, visibleStackRange, false);
            boolean hasStackBackTransform = false;
            boolean hasStackFrontTransform = false;
            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
@@ -363,7 +372,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                TaskView tv = taskViews.get(i);
                Task task = tv.getTask();
                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);
                } else {
                    if (tv.isFocusedTask()) {
@@ -371,16 +381,43 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                        lastFocusedTaskIndex = taskIndex;
                        resetFocusedTask();
                    }
                    if (DEBUG) {
                        Log.d(TAG, "returning to pool: " + task.key);
                    }
                    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
            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);
                TaskViewTransform transform = mCurrentTaskTransforms.get(i);
                TaskView tv = mTmpTaskViewMap.get(task);
                int taskIndex = mStack.indexOfTask(task);

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

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

            // Update the focus if the previous focused task was returned to the view pool
            if (lastFocusedTaskIndex != -1) {
                if (lastFocusedTaskIndex < visibleRange[1]) {
                    setFocusedTask(visibleRange[1], false, wasLastFocusedTaskAnimated);
                if (lastFocusedTaskIndex < visibleStackRange[1]) {
                    setFocusedTask(visibleStackRange[1], false, wasLastFocusedTaskAnimated);
                } 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
@@ -491,6 +518,14 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
        // Compute the min and max scroll values
        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
        if (boundScrollToNewMinMax) {
            mStackScroller.boundScroll();
@@ -762,7 +797,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal

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

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

        List<TaskView> taskViews = getTaskViews();
        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 ****/

    @Override
@@ -973,6 +1020,19 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
                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
            requestSynchronizeStackViewsWithModel(200);
        }
Loading