Search in sources :

Example 46 with Task

use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.

the class FreeformWorkspaceLayoutAlgorithm method update.

/**
     * Updates the layout for each of the freeform workspace tasks.  This is called after the stack
     * layout is updated.
     */
public void update(List<Task> freeformTasks, TaskStackLayoutAlgorithm stackLayout) {
    Collections.reverse(freeformTasks);
    mTaskRectMap.clear();
    int numFreeformTasks = stackLayout.mNumFreeformTasks;
    if (!freeformTasks.isEmpty()) {
        // Normalize the widths so that we can calculate the best layout below
        int workspaceWidth = stackLayout.mFreeformRect.width();
        int workspaceHeight = stackLayout.mFreeformRect.height();
        float normalizedWorkspaceWidth = (float) workspaceWidth / workspaceHeight;
        float normalizedWorkspaceHeight = 1f;
        float[] normalizedTaskWidths = new float[numFreeformTasks];
        for (int i = 0; i < numFreeformTasks; i++) {
            Task task = freeformTasks.get(i);
            float rowTaskWidth;
            if (task.bounds != null) {
                rowTaskWidth = (float) task.bounds.width() / task.bounds.height();
            } else {
                // If this is a stack task that was dragged into the freeform workspace, then
                // the task will not yet have an associated bounds, so assume the full workspace
                // width for the time being
                rowTaskWidth = normalizedWorkspaceWidth;
            }
            // Bound the task width to the workspace width so that at the worst case, it will
            // fit its own row
            normalizedTaskWidths[i] = Math.min(rowTaskWidth, normalizedWorkspaceWidth);
        }
        // Determine the scale to best fit each of the tasks in the workspace
        float rowScale = 0.85f;
        float rowWidth = 0f;
        float maxRowWidth = 0f;
        int rowCount = 1;
        for (int i = 0; i < numFreeformTasks; ) {
            float width = normalizedTaskWidths[i] * rowScale;
            if (rowWidth + width > normalizedWorkspaceWidth) {
                // That is too long for this row, create new row
                if ((rowCount + 1) * rowScale > normalizedWorkspaceHeight) {
                    // The new row is too high, so we need to try fitting again.  Update the
                    // scale to be the smaller of the scale needed to fit the task in the
                    // previous row, or the scale needed to fit the new row
                    rowScale = Math.min(normalizedWorkspaceWidth / (rowWidth + width), normalizedWorkspaceHeight / (rowCount + 1));
                    rowCount = 1;
                    rowWidth = 0;
                    i = 0;
                } else {
                    // The new row fits, so continue
                    rowWidth = width;
                    rowCount++;
                    i++;
                }
            } else {
                // Task is OK in this row
                rowWidth += width;
                i++;
            }
            maxRowWidth = Math.max(rowWidth, maxRowWidth);
        }
        // Normalize each of the actual rects to that scale
        float defaultRowLeft = ((1f - (maxRowWidth / normalizedWorkspaceWidth)) * workspaceWidth) / 2f;
        float rowLeft = defaultRowLeft;
        float rowTop = ((1f - (rowScale * rowCount)) * workspaceHeight) / 2f;
        float rowHeight = rowScale * workspaceHeight;
        for (int i = 0; i < numFreeformTasks; i++) {
            Task task = freeformTasks.get(i);
            float width = rowHeight * normalizedTaskWidths[i];
            if (rowLeft + width > workspaceWidth) {
                // This goes on the next line
                rowTop += rowHeight;
                rowLeft = defaultRowLeft;
            }
            RectF rect = new RectF(rowLeft, rowTop, rowLeft + width, rowTop + rowHeight);
            rect.inset(mTaskPadding, mTaskPadding);
            rowLeft += width;
            mTaskRectMap.put(task.key, rect);
        }
    }
}
Also used : RectF(android.graphics.RectF) Task(com.android.systemui.recents.model.Task)

Example 47 with Task

use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.

the class RecentsTransitionHelper method composeDockAnimationSpec.

/**
     * Composes the transition spec when docking a task, which includes a full task bitmap.
     */
public List<AppTransitionAnimationSpec> composeDockAnimationSpec(TaskView taskView, Rect bounds) {
    mTmpTransform.fillIn(taskView);
    Task task = taskView.getTask();
    Bitmap thumbnail = RecentsTransitionHelper.composeTaskBitmap(taskView, mTmpTransform);
    return Collections.singletonList(new AppTransitionAnimationSpec(task.key.id, thumbnail, bounds));
}
Also used : Task(com.android.systemui.recents.model.Task) Bitmap(android.graphics.Bitmap) AppTransitionAnimationSpec(android.view.AppTransitionAnimationSpec)

Example 48 with Task

use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.

the class RecentsView method launchPreviousTask.

/** Launches the task that recents was launched from if possible */
public boolean launchPreviousTask() {
    if (mTaskStackView != null) {
        Task task = getStack().getLaunchTarget();
        if (task != null) {
            TaskView taskView = mTaskStackView.getChildViewForTask(task);
            EventBus.getDefault().send(new LaunchTaskEvent(taskView, task, null, INVALID_STACK_ID, false));
            return true;
        }
    }
    return false;
}
Also used : Task(com.android.systemui.recents.model.Task) LaunchTaskEvent(com.android.systemui.recents.events.activity.LaunchTaskEvent)

Example 49 with Task

use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.

the class TaskStackLayoutAlgorithm method update.

/**
     * Computes the minimum and maximum scroll progress values and the progress values for each task
     * in the stack.
     */
void update(TaskStack stack, ArraySet<Task.TaskKey> ignoreTasksSet) {
    SystemServicesProxy ssp = Recents.getSystemServices();
    RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
    // Clear the progress map
    mTaskIndexMap.clear();
    // Return early if we have no tasks
    ArrayList<Task> tasks = stack.getStackTasks();
    if (tasks.isEmpty()) {
        mFrontMostTaskP = 0;
        mMinScrollP = mMaxScrollP = mInitialScrollP = 0;
        mNumStackTasks = mNumFreeformTasks = 0;
        return;
    }
    // Filter the set of freeform and stack tasks
    ArrayList<Task> freeformTasks = new ArrayList<>();
    ArrayList<Task> stackTasks = new ArrayList<>();
    for (int i = 0; i < tasks.size(); i++) {
        Task task = tasks.get(i);
        if (ignoreTasksSet.contains(task.key)) {
            continue;
        }
        if (task.isFreeformTask()) {
            freeformTasks.add(task);
        } else {
            stackTasks.add(task);
        }
    }
    mNumStackTasks = stackTasks.size();
    mNumFreeformTasks = freeformTasks.size();
    // 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 = stackTasks.size();
    for (int i = 0; i < taskCount; i++) {
        Task task = stackTasks.get(i);
        mTaskIndexMap.put(task.key.id, i);
    }
    // Update the freeform tasks
    if (!freeformTasks.isEmpty()) {
        mFreeformLayoutAlgorithm.update(freeformTasks, this);
    }
    // Calculate the min/max/initial scroll
    Task launchTask = stack.getLaunchTarget();
    int launchTaskIndex = launchTask != null ? stack.indexOfStackTask(launchTask) : mNumStackTasks - 1;
    if (getInitialFocusState() == STATE_FOCUSED) {
        int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
        float maxBottomNormX = getNormalizedXFromFocusedY(maxBottomOffset, FROM_BOTTOM);
        mFocusedRange.offset(0f);
        mMinScrollP = 0;
        mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) - Math.max(0, mFocusedRange.getAbsoluteX(maxBottomNormX)));
        if (launchState.launchedFromHome) {
            mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
        } else {
            mInitialScrollP = Utilities.clamp(launchTaskIndex - 1, mMinScrollP, mMaxScrollP);
        }
    } else if (!ssp.hasFreeformWorkspaceSupport() && mNumStackTasks == 1) {
        // If there is one stack task, ignore the min/max/initial scroll positions
        mMinScrollP = 0;
        mMaxScrollP = 0;
        mInitialScrollP = 0;
    } else {
        // Set the max scroll to be the point where the front most task is visible with the
        // stack bottom offset
        int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
        float maxBottomNormX = getNormalizedXFromUnfocusedY(maxBottomOffset, FROM_BOTTOM);
        mUnfocusedRange.offset(0f);
        mMinScrollP = 0;
        mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) - Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX)));
        boolean scrollToFront = launchState.launchedFromHome || launchState.launchedViaDockGesture;
        if (launchState.launchedFromBlacklistedApp) {
            mInitialScrollP = mMaxScrollP;
        } else if (launchState.launchedWithAltTab) {
            mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
        } else if (scrollToFront) {
            mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
        } else {
            // We are overriding the initial two task positions, so set the initial scroll
            // position to match the second task (aka focused task) position
            float initialTopNormX = getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP);
            mInitialScrollP = Math.max(mMinScrollP, Math.min(mMaxScrollP, (mNumStackTasks - 2)) - Math.max(0, mUnfocusedRange.getAbsoluteX(initialTopNormX)));
        }
    }
}
Also used : SystemServicesProxy(com.android.systemui.recents.misc.SystemServicesProxy) Task(com.android.systemui.recents.model.Task) RecentsActivityLaunchState(com.android.systemui.recents.RecentsActivityLaunchState) ArrayList(java.util.ArrayList)

Example 50 with Task

use of com.android.systemui.recents.model.Task in project android_frameworks_base by DirtyUnicorns.

the class TaskStackLayoutAlgorithm method setTaskOverridesForInitialState.

/**
     * Creates task overrides to ensure the initial stack layout if necessary.
     */
public void setTaskOverridesForInitialState(TaskStack stack, boolean ignoreScrollToFront) {
    RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
    mTaskIndexOverrideMap.clear();
    boolean scrollToFront = launchState.launchedFromHome || launchState.launchedFromBlacklistedApp || launchState.launchedViaDockGesture;
    if (getInitialFocusState() == STATE_UNFOCUSED && mNumStackTasks > 1) {
        if (ignoreScrollToFront || (!launchState.launchedWithAltTab && !scrollToFront)) {
            // Set the initial scroll to the predefined state (which differs from the stack)
            float[] initialNormX = null;
            float minBottomTaskNormX = getNormalizedXFromUnfocusedY(mSystemInsets.bottom + mInitialBottomOffset, FROM_BOTTOM);
            float maxBottomTaskNormX = getNormalizedXFromUnfocusedY(mFocusedTopPeekHeight + mTaskRect.height() - mMinMargin, FROM_TOP);
            if (mNumStackTasks <= 2) {
                // For small stacks, position the tasks so that they are top aligned to under
                // the action button, but ensure that it is at least a certain offset from the
                // bottom of the stack
                initialNormX = new float[] { Math.min(maxBottomTaskNormX, minBottomTaskNormX), getNormalizedXFromUnfocusedY(mFocusedTopPeekHeight, FROM_TOP) };
            } else {
                initialNormX = new float[] { minBottomTaskNormX, getNormalizedXFromUnfocusedY(mInitialTopOffset, FROM_TOP) };
            }
            mUnfocusedRange.offset(0f);
            List<Task> tasks = stack.getStackTasks();
            int taskCount = tasks.size();
            for (int i = taskCount - 1; i >= 0; i--) {
                int indexFromFront = taskCount - i - 1;
                if (indexFromFront >= initialNormX.length) {
                    break;
                }
                float newTaskProgress = mInitialScrollP + mUnfocusedRange.getAbsoluteX(initialNormX[indexFromFront]);
                mTaskIndexOverrideMap.put(tasks.get(i).key.id, newTaskProgress);
            }
        }
    }
}
Also used : Task(com.android.systemui.recents.model.Task) RecentsActivityLaunchState(com.android.systemui.recents.RecentsActivityLaunchState)

Aggregations

Task (com.android.systemui.recents.model.Task)225 TaskStack (com.android.systemui.recents.model.TaskStack)56 GridTaskView (com.android.systemui.recents.views.grid.GridTaskView)43 RecentsActivityLaunchState (com.android.systemui.recents.RecentsActivityLaunchState)30 SystemServicesProxy (com.android.systemui.recents.misc.SystemServicesProxy)25 ArrayList (java.util.ArrayList)23 ActivityOptions (android.app.ActivityOptions)20 RecentsConfiguration (com.android.systemui.recents.RecentsConfiguration)20 RecentsTaskLoadPlan (com.android.systemui.recents.model.RecentsTaskLoadPlan)20 RecentsTaskLoader (com.android.systemui.recents.model.RecentsTaskLoader)20 Resources (android.content.res.Resources)15 AppTransitionAnimationSpec (android.view.AppTransitionAnimationSpec)15 LaunchTaskEvent (com.android.systemui.recents.events.activity.LaunchTaskEvent)11 TimeInterpolator (android.animation.TimeInterpolator)10 ActivityManager (android.app.ActivityManager)10 Bitmap (android.graphics.Bitmap)10 Rect (android.graphics.Rect)10 RectF (android.graphics.RectF)10 Interpolator (android.view.animation.Interpolator)10 PathInterpolator (android.view.animation.PathInterpolator)10