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

Commit 36a5a2c7 authored by Winson's avatar Winson
Browse files

Initial layout/behaviour for freeform workspace.

Change-Id: Idc878862747d0d726cbf10be9893c48736673d0e
parent 53ec42cb
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -616,16 +616,18 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
        ViewAnimation.TaskViewEnterContext ctx = new ViewAnimation.TaskViewEnterContext(t);
        ctx.postAnimationTrigger.increment();
        if (mSearchWidgetInfo != null) {
            if (!Constants.DebugFlags.App.DisableSearchBar) {
                ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
                    @Override
                    public void run() {
                        // Start listening for widget package changes if there is one bound
                    if (!Constants.DebugFlags.App.DisableSearchBar && mAppWidgetHost != null) {
                        if (mAppWidgetHost != null) {
                            mAppWidgetHost.startListening();
                        }
                    }
                });
            }
        }
        ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
            @Override
            public void run() {
+5 −5
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskGrouping;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.views.TaskStackView;
import com.android.systemui.recents.views.TaskStackViewLayoutAlgorithm;
import com.android.systemui.recents.views.TaskStackLayoutAlgorithm;
import com.android.systemui.recents.views.TaskViewHeader;
import com.android.systemui.recents.views.TaskViewTransform;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
@@ -465,10 +465,10 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub
                mSearchBarBounds, mTaskStackBounds);

        // Rebind the header bar and draw it for the transition
        TaskStackViewLayoutAlgorithm algo = mDummyStackView.getStackAlgorithm();
        TaskStackLayoutAlgorithm algo = mDummyStackView.getStackAlgorithm();
        Rect taskStackBounds = new Rect(mTaskStackBounds);
        algo.setSystemInsets(systemInsets);
        algo.computeRects(taskStackBounds);
        algo.initialize(taskStackBounds);
        Rect taskViewBounds = algo.getUntransformedTaskViewBounds();
        if (!taskViewBounds.equals(mLastTaskViewBounds)) {
            mLastTaskViewBounds.set(taskViewBounds);
@@ -666,7 +666,7 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub

        // Prepare the dummy stack for the transition
        mDummyStackView.updateMinMaxScrollForStack(stack);
        TaskStackViewLayoutAlgorithm.VisibilityReport stackVr =
        TaskStackLayoutAlgorithm.VisibilityReport stackVr =
                mDummyStackView.computeStackVisibilityReport();
        boolean hasRecentTasks = stack.getTaskCount() > 0;
        boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks;
@@ -713,7 +713,7 @@ public class RecentsImpl extends IRecentsNonSystemUserCallbacks.Stub
     */
    private void startRecentsActivity(ActivityManager.RunningTaskInfo topTask,
              ActivityOptions opts, boolean fromHome, boolean fromSearchHome, boolean fromThumbnail,
              TaskStackViewLayoutAlgorithm.VisibilityReport vr) {
              TaskStackLayoutAlgorithm.VisibilityReport vr) {
        mStartAnimationTriggered = false;

        // Update the configuration based on the launch options
+9 −2
Original line number Diff line number Diff line
@@ -137,12 +137,19 @@ public class RecentsTaskLoadPlan {
            task.thumbnail = loader.getAndUpdateThumbnail(taskKey, ssp, false);
            if (DEBUG) Log.d(TAG, "\tthumbnail: " + taskKey + ", " + task.thumbnail);

            if (task.isFreeformTask()) {
                freeformTasks.add(task);
            } else {
                stackTasks.add(task);
            }
        }

        // Initialize the stacks
        ArrayList<Task> allTasks = new ArrayList<>();
        allTasks.addAll(stackTasks);
        allTasks.addAll(freeformTasks);
        mStack = new TaskStack();
        mStack.setTasks(stackTasks);
        mStack.setTasks(allTasks);
        mStack.createAffiliatedGroupings(mContext);
    }

+30 −0
Original line number Diff line number Diff line
@@ -399,6 +399,21 @@ public class TaskStack {
        return mTaskList.size();
    }

    /**
     * Returns the task in this stack which is the launch target.
     */
    public Task getLaunchTarget() {
        ArrayList<Task> tasks = mTaskList.getTasks();
        int taskCount = tasks.size();
        for (int i = 0; i < taskCount; i++) {
            Task task = tasks.get(i);
            if (task.isLaunchTarget) {
                return task;
            }
        }
        return null;
    }

    /** Returns the index of this task in this current task stack */
    public int indexOfTask(Task t) {
        return mTaskList.indexOf(t);
@@ -417,6 +432,21 @@ public class TaskStack {
        return null;
    }

    /**
     * Returns whether this stack has freeform tasks.
     */
    public boolean hasFreeformTasks() {
        ArrayList<Task> tasks = mTaskList.getTasks();
        int taskCount = tasks.size();
        for (int i = 0; i < taskCount; i++) {
            Task task = tasks.get(i);
            if (task.isFreeformTask()) {
                return true;
            }
        }
        return false;
    }

    /******** Filtering ********/

    /** Filters the stack into tasks similar to the one specified */
+108 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.systemui.recents.views;

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

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

/**
 * The layout logic for the contents of the freeform workspace.
 */
public class FreeformWorkspaceLayoutAlgorithm {

    private static final String TAG = "FreeformWorkspaceLayoutAlgorithm";
    private static final boolean DEBUG = false;

    // 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;

    // Optimization, allows for quick lookup of task -> index
    private HashMap<Task.TaskKey, Integer> mTaskIndexMap = new HashMap<>();

    /**
     * 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) {
        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;
            // For now, make the cells square
            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++) {
                Task task = freeformTasks.get(i);
                mTaskIndexMap.put(task.key, i);
            }

            if (DEBUG) {
                Log.d(TAG, "mFreeformCellXCount: " + mFreeformCellXCount);
                Log.d(TAG, "mFreeformCellYCount: " + mFreeformCellYCount);
                Log.d(TAG, "mFreeformCellWidth: " + mFreeformCellWidth);
                Log.d(TAG, "mFreeformCellHeight: " + mFreeformCellHeight);
            }
        }
    }

    /**
     * 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)) {
            return false;
        }
        return stackScroll > stackLayout.mStackEndScrollP;
    }

    /**
     * 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) {
            // This is a freeform task, so lay it out in the freeform workspace
            int taskIndex = mTaskIndexMap.get(task.key);
            int x = taskIndex % mFreeformCellXCount;
            int y = taskIndex / mFreeformCellXCount;
            float scale = (float) mFreeformCellWidth / stackLayout.mTaskRect.width();
            int scaleXOffset = (int) (((1f - scale) * stackLayout.mTaskRect.width()) / 2);
            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.visible = true;
            return transformOut;
        }
        return null;
    }
}
Loading