From a433fa9c17772f563163ff7db177d091d6aebd5b Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 8 Jul 2014 21:50:31 -0700 Subject: [PATCH] Updating task grouping logic. - More fixes for graphical glitches when picking up task views. Change-Id: I93fab1c2a9cc727c68d8f8fbd506bedaf681715f --- .../SystemUI/res/layout/recents_task_view.xml | 2 +- packages/SystemUI/res/values/dimens.xml | 3 ++ .../recents/AlternateRecentsComponent.java | 5 +- .../recents/RecentsConfiguration.java | 6 ++- .../systemui/recents/model/TaskGrouping.java | 16 +++++- .../systemui/recents/model/TaskStack.java | 43 +++------------- .../systemui/recents/views/RecentsView.java | 8 +-- .../systemui/recents/views/TaskStackView.java | 49 +++++++++--------- .../views/TaskStackViewLayoutAlgorithm.java | 51 ++++++++++++++----- 9 files changed, 97 insertions(+), 86 deletions(-) diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml index 1bab67af7094c..2b50a95028878 100644 --- a/packages/SystemUI/res/layout/recents_task_view.xml +++ b/packages/SystemUI/res/layout/recents_task_view.xml @@ -25,7 +25,7 @@ 1dp + + 56dp + 64dp diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java index f59ba5885a2e7..c72943207d232 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java @@ -341,10 +341,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta } // Get the transform for the running task - TaskStack.GroupTaskIndex groupTaskIndex = new TaskStack.GroupTaskIndex(); - stack.getGroupIndexForTask(task, groupTaskIndex); - mTmpTransform = algo.getStackTransform(groupTaskIndex.groupIndex, groupTaskIndex.taskIndex, - tsv.getStackScroll(), mTmpTransform); + mTmpTransform = algo.getStackTransform(task, tsv.getStackScroll(), mTmpTransform); mTmpTransform.rect.offset(mTaskStackBounds.left, mTaskStackBounds.top); mTmpTransform.rect.offset(0, mStatusBarHeight); return new Rect(mTmpTransform.rect); diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index f6e508f3c9d5f..b039485797bab 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -85,7 +85,8 @@ public class RecentsConfiguration { public int taskBarViewDarkTextColor; public int taskBarViewHighlightColor; - /** Task bar animations */ + /** Task bar size & animations */ + public int taskBarHeight; public int taskBarEnterAnimDuration; public int taskBarEnterAnimDelay; public int taskBarExitAnimDuration; @@ -214,7 +215,8 @@ public class RecentsConfiguration { taskBarViewHighlightColor = res.getColor(R.color.recents_task_bar_highlight_color); - // Task bar animations + // Task bar size & animations + taskBarHeight = res.getDimensionPixelSize(R.dimen.recents_task_bar_height); taskBarEnterAnimDuration = res.getInteger(R.integer.recents_animate_task_bar_enter_duration); taskBarEnterAnimDelay = diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java index 3a18bce21af91..77935493cf8ba 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskGrouping.java @@ -1,6 +1,7 @@ package com.android.systemui.recents.model; import java.util.ArrayList; +import java.util.HashMap; /** Represents a grouping of tasks witihin a stack. */ public class TaskGrouping { @@ -9,6 +10,7 @@ public class TaskGrouping { long latestActiveTimeInGroup; ArrayList mTasks = new ArrayList(); + HashMap mTaskIndices = new HashMap(); /** Creates a group with a specified affiliation. */ public TaskGrouping(String affiliation) { @@ -22,6 +24,7 @@ public class TaskGrouping { latestActiveTimeInGroup = t.key.lastActiveTime; } t.setGroup(this); + updateTaskIndices(); } /** Removes a task from this group. */ @@ -36,6 +39,7 @@ public class TaskGrouping { } } t.setGroup(null); + updateTaskIndices(); } /** Gets the front task */ @@ -45,9 +49,19 @@ public class TaskGrouping { /** Finds the index of a given task in a group. */ public int indexOf(Task t) { - return mTasks.indexOf(t.key); + return mTaskIndices.get(t.key); } /** Returns the number of tasks in this group. */ public int getTaskCount() { return mTasks.size(); } + + /** Updates the mapping of tasks to indices. */ + private void updateTaskIndices() { + mTaskIndices.clear(); + int taskCount = mTasks.size(); + for (int i = 0; i < taskCount; i++) { + Task.TaskKey k = mTasks.get(i); + mTaskIndices.put(k, i); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java index ffd2857db8f00..6bc74a72b5859 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; +import java.util.Random; /** @@ -174,7 +175,6 @@ public class TaskStack { ArrayList mGroups = new ArrayList(); HashMap mAffinitiesGroups = new HashMap(); - HashMap mGroupsIndices = new HashMap(); /** Sets the callbacks for this task stack */ public void setCallbacks(TaskStackCallbacks cb) { @@ -295,23 +295,11 @@ public class TaskStack { public void addGroup(TaskGrouping group) { mGroups.add(group); mAffinitiesGroups.put(group.affiliation, group); - updateTaskGroupingIndices(); } public void removeGroup(TaskGrouping group) { - // XXX: Ensure that there are no more tasks in this group mGroups.remove(group); mAffinitiesGroups.remove(group.affiliation); - mGroupsIndices.remove(group); - updateTaskGroupingIndices(); - } - - /** Adds a mapping from a task to a group. */ - public void addTaskToGroup(TaskGrouping group, Task task) { - if (!mAffinitiesGroups.containsKey(group.affiliation)) { - throw new RuntimeException("Unexpected group"); - } - group.addTask(task); } /** Returns the group with the specified affiliation. */ @@ -319,17 +307,6 @@ public class TaskStack { return mAffinitiesGroups.get(affiliation); } - /** Returns the number of groups. */ - public int getGroupingCount() { - return mGroups.size(); - } - - /** Returns the group and task indices for a given task. */ - public void getGroupIndexForTask(Task task, GroupTaskIndex indices) { - indices.groupIndex = mGroupsIndices.get(task.group); - indices.taskIndex = task.group.indexOf(task); - } - /** * Temporary: This method will simulate affiliation groups by */ @@ -349,18 +326,23 @@ public class TaskStack { int taskCount = tasks.size(); String prevPackage = ""; String prevAffiliation = ""; + Random r = new Random(); + int groupCountDown = 1000; for (int i = 0; i < taskCount; i++) { Task t = tasks.get(i); String packageName = t.key.baseIntent.getComponent().getPackageName(); + packageName = "pkg"; TaskGrouping group; - if (packageName.equals(prevPackage)) { + if (packageName.equals(prevPackage) && groupCountDown > 0) { group = getGroupWithAffiliation(prevAffiliation); + groupCountDown--; } else { String affiliation = counter.nextName(); group = new TaskGrouping(affiliation); addGroup(group); prevAffiliation = affiliation; prevPackage = packageName; + groupCountDown = 1000; } group.addTask(t); taskMap.put(t.key, t); @@ -373,7 +355,6 @@ public class TaskStack { taskGrouping2.latestActiveTimeInGroup); } }); - updateTaskGroupingIndices(); // Sort group tasks by increasing firstActiveTime of the task, and also build a new list of // tasks int taskIndex = 0; @@ -408,16 +389,6 @@ public class TaskStack { } } - /** Updates the mapping of tasks to indices. */ - private void updateTaskGroupingIndices() { - mGroupsIndices.clear(); - int groupsCount = mGroups.size(); - for (int i = 0; i < groupsCount; i++) { - TaskGrouping g = mGroups.get(i); - mGroupsIndices.put(g, i); - } - } - @Override public String toString() { String str = "Tasks:\n"; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index 87d45ba8b49bc..85afb32b2c1f7 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -443,20 +443,16 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV int offsetX = 0; int offsetY = 0; int stackScroll = stackView.getStackScroll(); - TaskStack.GroupTaskIndex groupTaskIndex = new TaskStack.GroupTaskIndex(); - stack.getGroupIndexForTask(task, groupTaskIndex); if (tv == null) { // If there is no actual task view, then use the stack view as the source view // and then offset to the expected transform rect, but bound this to just // outside the display rect (to ensure we don't animate from too far away) sourceView = stackView; - transform = stackView.getStackAlgorithm().getStackTransform(groupTaskIndex.groupIndex, - groupTaskIndex.taskIndex, stackScroll, transform); + transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform); offsetX = transform.rect.left; offsetY = Math.min(transform.rect.top, mConfig.displayRect.height()); } else { - transform = stackView.getStackAlgorithm().getStackTransform(groupTaskIndex.groupIndex, - groupTaskIndex.taskIndex, stackScroll, transform); + transform = stackView.getStackAlgorithm().getStackTransform(task, stackScroll, transform); } // Compute the thumbnail to scale up from diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index f9b360082e205..61101b1e08333 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -238,11 +238,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } // Update the stack transforms - TaskStack.GroupTaskIndex groupTaskIndex = new TaskStack.GroupTaskIndex(); for (int i = taskCount - 1; i >= 0; i--) { - mStack.getGroupIndexForTask(tasks.get(i), groupTaskIndex); - TaskViewTransform transform = mStackAlgorithm.getStackTransform(groupTaskIndex.groupIndex, - groupTaskIndex.taskIndex, stackScroll, taskTransforms.get(i)); + TaskViewTransform transform = mStackAlgorithm.getStackTransform(tasks.get(i), stackScroll, taskTransforms.get(i)); if (transform.visible) { if (frontMostVisibleIndex < 0) { frontMostVisibleIndex = i; @@ -332,14 +329,12 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (mStackViewsAnimationDuration > 0) { // For items in the list, put them in start animating them from the // approriate ends of the list where they are expected to appear - Task fromTask = (transform.t < 0) ? - tasks.get(visibleRange[1]) : - tasks.get(visibleRange[0]); - mStack.getGroupIndexForTask(fromTask, gti); - tmpTransform = mStackAlgorithm.getStackTransform( - (transform.t < 0) ? gti.groupIndex - 1 : gti.groupIndex + 1, - (transform.t < 0) ? gti.taskIndex - 1 : gti.taskIndex + 1, - stackScroll, tmpTransform); + if (transform.t < 0) { + tmpTransform = mStackAlgorithm.getStackTransform(tasks.get(0), stackScroll, tmpTransform); + } else { + tmpTransform = mStackAlgorithm.getStackTransform(tasks.get(Math.min(tasks.size() - 1, visibleRange[0] + 1)), + stackScroll, tmpTransform); + } tv.updateViewPropertiesToTaskTransform(tmpTransform, 0); } } @@ -376,7 +371,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } /** Computes the initial stack scroll for the stack. */ int getInitialStackScroll() { - if (mStack.getGroupingCount() > 2) { + if (mStack.getTaskCount() > 2) { return mMaxScroll - mStackAlgorithm.mTaskRect.height() / 2; } return mMaxScroll; @@ -496,7 +491,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal /** Updates the min and max virtual scroll bounds */ void updateMinMaxScroll(boolean boundScrollToNewMinMax) { // Compute the min and max scroll values - mStackAlgorithm.computeMinMaxScroll(mStack.getGroupingCount()); + mStackAlgorithm.computeMinMaxScroll(mStack.getTasks()); mMinScroll = mStackAlgorithm.mMinScroll; mMaxScroll = mStackAlgorithm.mMaxScroll; @@ -562,7 +557,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (scrollToNewPosition) { // Scroll the view into position int newScroll = Math.max(mMinScroll, Math.min(mMaxScroll, - mStackAlgorithm.getStackScrollForTaskIndex(taskIndex))); + mStackAlgorithm.getStackScrollForTaskIndex(t))); animateScroll(getStackScroll(), newScroll, postScrollRunnable); } else { @@ -692,7 +687,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal /** Computes the stack and task rects */ public void computeRects(int width, int height, int insetLeft, int insetBottom) { // Compute the rects in the stack algorithm - mStackAlgorithm.computeRects(width, height, insetLeft, insetBottom); + mStackAlgorithm.computeRects(mStack.getTasks(), width, height, insetLeft, insetBottom); // Update the scroll bounds updateMinMaxScroll(false); @@ -814,8 +809,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } if (mStack.getTaskCount() > 0) { - TaskStack.GroupTaskIndex groupTaskIndex = new TaskStack.GroupTaskIndex(); - if (Constants.DebugFlags.App.EnableScreenshotAppTransition) { // Find the target task with the specified id ArrayList tasks = mStack.getTasks(); @@ -834,10 +827,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Find the group and task index of the target task if (targetTask != null) { - mStack.getGroupIndexForTask(targetTask, groupTaskIndex); ctx.targetTaskTransform = new TaskViewTransform(); - mStackAlgorithm.getStackTransform(groupTaskIndex.groupIndex, - groupTaskIndex.taskIndex, getStackScroll(), ctx.targetTaskTransform); + mStackAlgorithm.getStackTransform(targetTask, getStackScroll(), ctx.targetTaskTransform); Rect taskStackBounds = new Rect(); mConfig.getTaskStackBounds(getMeasuredWidth(), getMeasuredHeight(), taskStackBounds); ctx.targetTaskTransform.rect.offset(taskStackBounds.left, taskStackBounds.top); @@ -852,9 +843,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal ctx.currentStackViewIndex = i; ctx.currentStackViewCount = childCount; ctx.isCurrentTaskFrontMost = (i == (getChildCount() - 1)); - mStack.getGroupIndexForTask(tv.getTask(), groupTaskIndex); - mStackAlgorithm.getStackTransform(groupTaskIndex.groupIndex, groupTaskIndex.taskIndex, - getStackScroll(), ctx.currentTaskTransform); + mStackAlgorithm.getStackTransform(tv.getTask(), getStackScroll(), ctx.currentTaskTransform); tv.startEnterRecentsAnimation(ctx); } @@ -909,11 +898,17 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal @Override public void onStackTaskAdded(TaskStack stack, Task t) { + // Update the task offsets + mStackAlgorithm.updateTaskOffsets(mStack.getTasks()); + requestSynchronizeStackViewsWithModel(); } @Override public void onStackTaskRemoved(TaskStack stack, Task t) { + // Update the task offsets + mStackAlgorithm.updateTaskOffsets(mStack.getTasks()); + // 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(t); @@ -953,6 +948,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal ArrayList curTaskTransforms = getStackTransforms(curTasks, getStackScroll(), null, true); + // Update the task offsets + mStackAlgorithm.updateTaskOffsets(mStack.getTasks()); + // Scroll the item to the top of the stack (sans-peek) rect so that we can see it better updateMinMaxScroll(false); float overlapHeight = mStackAlgorithm.getTaskOverlapHeight(); @@ -977,6 +975,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal final ArrayList curTaskTransforms = getStackTransforms(curTasks, getStackScroll(), null, true); + // Update the task offsets + mStackAlgorithm.updateTaskOffsets(mStack.getTasks()); + // Restore the stashed scroll updateMinMaxScroll(false); setStackScrollRaw(mStashedScroll); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java index ab47757d2e842..789b4f7ab3581 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java @@ -20,6 +20,10 @@ import android.graphics.Rect; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.misc.Utilities; +import com.android.systemui.recents.model.Task; + +import java.util.ArrayList; +import java.util.HashMap; /* The layout logic for a TaskStackView */ public class TaskStackViewLayoutAlgorithm { @@ -42,12 +46,14 @@ public class TaskStackViewLayoutAlgorithm { int mMinScroll; int mMaxScroll; + HashMap mTaskOffsetMap = new HashMap(); + public TaskStackViewLayoutAlgorithm(RecentsConfiguration config) { mConfig = config; } /** Computes the stack and task rects */ - public void computeRects(int width, int height, int insetLeft, int insetBottom) { + public void computeRects(ArrayList tasks, int width, int height, int insetLeft, int insetBottom) { // Note: We let the stack view be the full height because we want the cards to go under the // navigation bar if possible. However, the stack rects which we use to calculate // max scroll, etc. need to take the nav bar into account @@ -76,29 +82,31 @@ public class TaskStackViewLayoutAlgorithm { int left = mStackRect.left + (mStackRect.width() - size) / 2; mTaskRect.set(left, mStackRectSansPeek.top, left + size, mStackRectSansPeek.top + size); + + // Update the task offsets once the size changes + updateTaskOffsets(tasks); } - void computeMinMaxScroll(int taskCount) { + void computeMinMaxScroll(ArrayList tasks) { // Compute the min and max scroll values - int numTasks = Math.max(1, taskCount); + int numTasks = Math.max(1, tasks.size()); int taskHeight = mTaskRect.height(); int stackHeight = mStackRectSansPeek.height(); - int maxScrollHeight = taskHeight + getStackScrollForTaskIndex(numTasks - 1); if (numTasks <= 1) { // If there is only one task, then center the task in the stack rect (sans peek) mMinScroll = mMaxScroll = -(stackHeight - taskHeight) / 2; } else { + int maxScrollHeight = taskHeight + getStackScrollForTaskIndex(tasks.get(tasks.size() - 1)); mMinScroll = Math.min(stackHeight, maxScrollHeight) - stackHeight; mMaxScroll = maxScrollHeight - stackHeight; } } /** Update/get the transform */ - public TaskViewTransform getStackTransform(int groupIndexInStack, int taskIndexInGroup, - int stackScroll, TaskViewTransform transformOut) { + public TaskViewTransform getStackTransform(Task task, int stackScroll, TaskViewTransform transformOut) { // Return early if we have an invalid index - if (groupIndexInStack < 0) { + if (task == null) { transformOut.reset(); return transformOut; } @@ -107,7 +115,7 @@ public class TaskStackViewLayoutAlgorithm { int numPeekCards = StackPeekNumCards; float overlapHeight = StackOverlapPct * mTaskRect.height(); float peekHeight = StackPeekHeightPct * mStackRect.height(); - float t = ((groupIndexInStack * overlapHeight) - stackScroll) / overlapHeight; + float t = (getStackScrollForTaskIndex(task) - stackScroll) / overlapHeight; float boundedT = Math.max(t, -(numPeekCards + 1)); // Set the scale relative to its position @@ -118,6 +126,8 @@ public class TaskStackViewLayoutAlgorithm { float scale = Math.max(minScale, Math.min(1f, minScale + ((boundedT + (numPeekCards + 1)) * scaleInc))); float scaleYOffset = ((1f - scale) * mTaskRect.height()) / 2; + // Account for the bar offsets being scaled? + float scaleBarYOffset = (1f - scale) * mConfig.taskBarHeight; transformOut.scale = scale; // Set the y translation @@ -125,9 +135,8 @@ public class TaskStackViewLayoutAlgorithm { transformOut.translationY = (int) ((Math.max(-numPeekCards, boundedT) / numPeekCards) * peekHeight - scaleYOffset); } else { - transformOut.translationY = (int) (boundedT * overlapHeight - scaleYOffset); + transformOut.translationY = (int) (boundedT * overlapHeight - scaleYOffset - scaleBarYOffset); } - transformOut.translationY += 100 * taskIndexInGroup; // Set the z translation int minZ = mConfig.taskViewTranslationZMinPx; @@ -161,8 +170,26 @@ public class TaskStackViewLayoutAlgorithm { * Returns the scroll to such that the task transform at that index will have t=0. (If the scroll * is not bounded) */ - int getStackScrollForTaskIndex(int i) { - return (int) (i * getTaskOverlapHeight()); + int getStackScrollForTaskIndex(Task t) { + return mTaskOffsetMap.get(t.key); + } + + /** + * Updates the cache of tasks to offsets. + */ + void updateTaskOffsets(ArrayList tasks) { + mTaskOffsetMap.clear(); + int offset = 0; + int taskCount = tasks.size(); + for (int i = 0; i < taskCount; i++) { + Task t = tasks.get(i); + mTaskOffsetMap.put(t.key, offset); + if (t.group.isFrontMostTask(t)) { + offset += getTaskOverlapHeight(); + } else { + offset += mConfig.taskBarHeight; + } + } } } \ No newline at end of file