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

Commit a5e6b360 authored by Winson's avatar Winson
Browse files

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

Change-Id: I5118d03c115080e05447d325097419b9a1c6f8b4
parent e6e6c996
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