Refactoring to support groups.
- Removing RecentService, determining animations just in time
- Fixing a few issues with animations of newly picked up tasks from the pool
- Moving helper classes into sub package
Change-Id: Ie10385d1f9ca79eea918b16932f56b60e2802304
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java b/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
index 6568b1a..49a7ff9 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/FullscreenTransitionOverlayView.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
-import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -31,7 +30,7 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
import com.android.systemui.R;
-import com.android.systemui.recents.Console;
+import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
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 f203d3e..87d45ba 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -34,7 +34,7 @@
import android.view.View;
import android.view.WindowInsets;
import android.widget.FrameLayout;
-import com.android.systemui.recents.Console;
+import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.model.RecentsPackageMonitor;
@@ -438,23 +438,25 @@
}
// Upfront the processing of the thumbnail
- TaskViewTransform transform;
+ TaskViewTransform transform = new TaskViewTransform();
View sourceView = tv;
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(stack.indexOfTask(task),
- stackScroll);
+ transform = stackView.getStackAlgorithm().getStackTransform(groupTaskIndex.groupIndex,
+ groupTaskIndex.taskIndex, stackScroll, transform);
offsetX = transform.rect.left;
offsetY = Math.min(transform.rect.top, mConfig.displayRect.height());
} else {
- transform = stackView.getStackAlgorithm().getStackTransform(stack.indexOfTask(task),
- stackScroll);
+ transform = stackView.getStackAlgorithm().getStackTransform(groupTaskIndex.groupIndex,
+ groupTaskIndex.taskIndex, stackScroll, transform);
}
// Compute the thumbnail to scale up from
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
index cae6bd7..8409227 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
@@ -28,7 +28,7 @@
import android.view.VelocityTracker;
import android.view.View;
import android.view.animation.LinearInterpolator;
-import com.android.systemui.recents.Console;
+import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.Constants;
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
index 9c60603..4ed3b59 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
@@ -34,7 +34,7 @@
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.Utilities;
+import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
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 dd47fddf..4a1faee 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -31,18 +31,19 @@
import android.widget.FrameLayout;
import android.widget.OverScroller;
import com.android.systemui.R;
-import com.android.systemui.recents.Console;
import com.android.systemui.recents.Constants;
-import com.android.systemui.recents.DozeTrigger;
import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.ReferenceCountedTrigger;
-import com.android.systemui.recents.Utilities;
+import com.android.systemui.recents.misc.Console;
+import com.android.systemui.recents.misc.DozeTrigger;
+import com.android.systemui.recents.misc.ReferenceCountedTrigger;
+import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.RecentsPackageMonitor;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Set;
@@ -180,7 +181,18 @@
mStackViewsDirty = true;
}
- /** Finds the child view given a specific task */
+ /** Returns a mapping of child view to Task. */
+ HashMap<Task, TaskView> getTaskChildViewMap() {
+ HashMap<Task, TaskView> taskViewMap = new HashMap<Task, TaskView>();
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ TaskView tv = (TaskView) getChildAt(i);
+ taskViewMap.put(tv.getTask(), tv);
+ }
+ return taskViewMap;
+ }
+
+ /** Finds the child view given a specific task. */
TaskView getChildViewForTask(Task t) {
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -225,9 +237,11 @@
}
// Update the stack transforms
+ TaskStack.GroupTaskIndex groupTaskIndex = new TaskStack.GroupTaskIndex();
for (int i = taskCount - 1; i >= 0; i--) {
- TaskViewTransform transform = mStackAlgorithm.getStackTransform(i, stackScroll,
- taskTransforms.get(i));
+ mStack.getGroupIndexForTask(tasks.get(i), groupTaskIndex);
+ TaskViewTransform transform = mStackAlgorithm.getStackTransform(groupTaskIndex.groupIndex,
+ groupTaskIndex.taskIndex, stackScroll, taskTransforms.get(i));
if (transform.visible) {
if (frontMostVisibleIndex < 0) {
frontMostVisibleIndex = i;
@@ -253,6 +267,11 @@
if (visibleRangeOut != null) {
visibleRangeOut[0] = frontMostVisibleIndex;
visibleRangeOut[1] = backMostVisibleIndex;
+ if (Console.Enabled) {
+ Console.log(Constants.Log.TaskStack.SynchronizeViewsWithModel,
+ "[TaskStackView|updateStackTransforms]",
+ "Back: " + backMostVisibleIndex + " Front: " + frontMostVisibleIndex);
+ }
}
}
@@ -278,58 +297,57 @@
"mStackViewsDirty: " + mStackViewsDirty, Console.AnsiYellow);
}
if (mStackViewsDirty) {
- // XXX: Consider using TaskViewTransform pool to prevent allocations
- // XXX: Iterate children views, update transforms and remove all that are not visible
- // For all remaining tasks, update transforms and if visible add the view
-
// Get all the task transforms
- int[] visibleRange = mTmpVisibleRange;
- int stackScroll = getStackScroll();
ArrayList<Task> tasks = mStack.getTasks();
+ int stackScroll = getStackScroll();
+ int[] visibleRange = mTmpVisibleRange;
updateStackTransforms(mCurrentTaskTransforms, tasks, stackScroll, visibleRange, false);
+ TaskViewTransform tmpTransform = new TaskViewTransform();
+ TaskStack.GroupTaskIndex gti = new TaskStack.GroupTaskIndex();
- // Update the visible state of all the tasks
- int taskCount = tasks.size();
- for (int i = 0; i < taskCount; i++) {
- Task task = tasks.get(i);
- TaskViewTransform transform = mCurrentTaskTransforms.get(i);
- TaskView tv = getChildViewForTask(task);
-
- if (transform.visible) {
- if (tv == null) {
- tv = mViewPool.pickUpViewFromPool(task, task);
- // When we are picking up a new view from the view pool, prepare it for any
- // following animation by putting it in a reasonable place
- if (mStackViewsAnimationDuration > 0 && i != 0) {
- int fromIndex = (transform.t < 0) ?
- Math.max(0, (visibleRange[1] - 1)) :
- Math.min(taskCount - 1, (visibleRange[0] + 1));
- tv.updateViewPropertiesToTaskTransform(
- mStackAlgorithm.getStackTransform(fromIndex, stackScroll), 0);
- }
- }
- } else {
- if (tv != null) {
- mViewPool.returnViewToPool(tv);
- }
- }
- }
-
- // Update all the remaining view children
- // NOTE: We have to iterate in reverse where because we are removing views directly
+ // Return all the invisible children to the pool
+ HashMap<Task, TaskView> taskChildViewMap = getTaskChildViewMap();
int childCount = getChildCount();
for (int i = childCount - 1; i >= 0; i--) {
TaskView tv = (TaskView) getChildAt(i);
Task task = tv.getTask();
int taskIndex = mStack.indexOfTask(task);
- if (taskIndex < 0 || !mCurrentTaskTransforms.get(taskIndex).visible) {
+ if (taskIndex < visibleRange[1] || taskIndex > visibleRange[0]) {
+ taskChildViewMap.remove(task);
mViewPool.returnViewToPool(tv);
- } else {
- tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
- mStackViewsAnimationDuration);
}
}
+ // Pick up all the newly visible children and update all the existing children
+ boolean isValidVisibleRange = visibleRange[0] != -1 && visibleRange[1] != -1;
+ for (int i = visibleRange[0]; isValidVisibleRange && i >= visibleRange[1]; i--) {
+ Task task = tasks.get(i);
+ TaskViewTransform transform = mCurrentTaskTransforms.get(i);
+ TaskView tv = taskChildViewMap.get(task);
+ int taskIndex = mStack.indexOfTask(task);
+
+ if (tv == null) {
+ tv = mViewPool.pickUpViewFromPool(task, task);
+ 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);
+ tv.updateViewPropertiesToTaskTransform(tmpTransform, 0);
+ }
+ }
+
+ // Update and animate the task into place
+ tv.updateViewPropertiesToTaskTransform(mCurrentTaskTransforms.get(taskIndex),
+ mStackViewsAnimationDuration);
+ }
+
if (Console.Enabled) {
Console.log(Constants.Log.TaskStack.SynchronizeViewsWithModel,
" [TaskStackView|viewChildren]", "" + getChildCount());
@@ -357,7 +375,7 @@
}
/** Computes the initial stack scroll for the stack. */
int getInitialStackScroll() {
- if (mStack.getTaskCount() > 2) {
+ if (mStack.getGroupingCount() > 2) {
return mMaxScroll - mStackAlgorithm.mTaskRect.height() / 2;
}
return mMaxScroll;
@@ -477,7 +495,7 @@
/** Updates the min and max virtual scroll bounds */
void updateMinMaxScroll(boolean boundScrollToNewMinMax) {
// Compute the min and max scroll values
- mStackAlgorithm.computeMinMaxScroll(mStack.getTaskCount());
+ mStackAlgorithm.computeMinMaxScroll(mStack.getGroupingCount());
mMinScroll = mStackAlgorithm.mMinScroll;
mMaxScroll = mStackAlgorithm.mMaxScroll;
@@ -794,30 +812,37 @@
return;
}
- // Animate all the task views into view
- TaskViewTransform transform = mStackAlgorithm.getStackTransform(mStack.getTaskCount() - 1,
- getInitialStackScroll());
- ctx.taskRect = transform.rect;
- ctx.stackRectSansPeek = mStackAlgorithm.mStackRectSansPeek;
- int childCount = getChildCount();
- for (int i = childCount - 1; i >= 0; i--) {
- TaskView tv = (TaskView) getChildAt(i);
- ctx.stackViewIndex = i;
- ctx.stackViewCount = childCount;
- ctx.isFrontMost = (i == (getChildCount() - 1));
- ctx.transform = mStackAlgorithm.getStackTransform(
- mStack.indexOfTask(tv.getTask()), getStackScroll());
- tv.startEnterRecentsAnimation(ctx);
- }
-
- // Add a runnable to the post animation ref counter to clear all the views
- ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
- @Override
- public void run() {
- // Start dozing
- mUIDozeTrigger.startDozing();
+ if (mStack.getTaskCount() > 0) {
+ // Animate all the task views into view
+ TaskViewTransform transform = new TaskViewTransform();
+ TaskStack.GroupTaskIndex groupTaskIndex = new TaskStack.GroupTaskIndex();
+ mStack.getGroupIndexForTask(mStack.getFrontMostTask(), groupTaskIndex);
+ mStackAlgorithm.getStackTransform(groupTaskIndex.groupIndex, groupTaskIndex.taskIndex,
+ getInitialStackScroll(), transform);
+ ctx.taskRect = transform.rect;
+ ctx.stackRectSansPeek = mStackAlgorithm.mStackRectSansPeek;
+ int childCount = getChildCount();
+ for (int i = childCount - 1; i >= 0; i--) {
+ TaskView tv = (TaskView) getChildAt(i);
+ ctx.stackViewIndex = i;
+ ctx.stackViewCount = childCount;
+ ctx.isFrontMost = (i == (getChildCount() - 1));
+ ctx.transform = new TaskViewTransform();
+ mStack.getGroupIndexForTask(tv.getTask(), groupTaskIndex);
+ mStackAlgorithm.getStackTransform(groupTaskIndex.groupIndex, groupTaskIndex.taskIndex,
+ getStackScroll(), ctx.transform);
+ tv.startEnterRecentsAnimation(ctx);
}
- });
+
+ // Add a runnable to the post animation ref counter to clear all the views
+ ctx.postAnimationTrigger.addLastDecrementRunnable(new Runnable() {
+ @Override
+ public void run() {
+ // Start dozing
+ mUIDozeTrigger.startDozing();
+ }
+ });
+ }
}
/** Requests this task stacks to start it's exit-recents animation. */
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 daa18bc..ab47757 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java
@@ -19,7 +19,7 @@
import android.graphics.Rect;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
-import com.android.systemui.recents.Utilities;
+import com.android.systemui.recents.misc.Utilities;
/* The layout logic for a TaskStackView */
public class TaskStackViewLayoutAlgorithm {
@@ -94,17 +94,11 @@
}
}
- /** Update/get the transform (creates a new TaskViewTransform) */
- public TaskViewTransform getStackTransform(int indexInStack, int stackScroll) {
- TaskViewTransform transform = new TaskViewTransform();
- return getStackTransform(indexInStack, stackScroll, transform);
- }
-
/** Update/get the transform */
- public TaskViewTransform getStackTransform(int indexInStack, int stackScroll,
- TaskViewTransform transformOut) {
+ public TaskViewTransform getStackTransform(int groupIndexInStack, int taskIndexInGroup,
+ int stackScroll, TaskViewTransform transformOut) {
// Return early if we have an invalid index
- if (indexInStack < 0) {
+ if (groupIndexInStack < 0) {
transformOut.reset();
return transformOut;
}
@@ -113,7 +107,7 @@
int numPeekCards = StackPeekNumCards;
float overlapHeight = StackOverlapPct * mTaskRect.height();
float peekHeight = StackPeekHeightPct * mStackRect.height();
- float t = ((indexInStack * overlapHeight) - stackScroll) / overlapHeight;
+ float t = ((groupIndexInStack * overlapHeight) - stackScroll) / overlapHeight;
float boundedT = Math.max(t, -(numPeekCards + 1));
// Set the scale relative to its position
@@ -133,6 +127,7 @@
} else {
transformOut.translationY = (int) (boundedT * overlapHeight - scaleYOffset);
}
+ transformOut.translationY += 100 * taskIndexInGroup;
// Set the z translation
int minZ = mConfig.taskViewTranslationZMinPx;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
index 304d45c..e186e2e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -22,7 +22,7 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewParent;
-import com.android.systemui.recents.Console;
+import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.Constants;
/* Handles touch events for a TaskStackView. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 6b06945..0d0fccc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -25,18 +25,14 @@
import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Point;
import android.graphics.Rect;
-import android.graphics.RectF;
import android.util.AttributeSet;
-import android.view.MotionEvent;
import android.view.View;
import android.view.ViewPropertyAnimator;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
import com.android.systemui.R;
-import com.android.systemui.recents.Console;
+import com.android.systemui.recents.misc.Console;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.model.Task;
@@ -61,6 +57,7 @@
Task mTask;
boolean mTaskDataLoaded;
boolean mIsFocused;
+ boolean mIsStub;
boolean mClipViewInStack;
Rect mTmpRect = new Rect();
Paint mLayerPaint = new Paint();
@@ -133,8 +130,8 @@
// Update the outline
Outline o = new Outline();
- o.setRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight() -
- mConfig.taskViewShadowOutlineBottomInsetPx, mConfig.taskViewRoundedCornerRadiusPx);
+ o.setRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(),
+ mConfig.taskViewRoundedCornerRadiusPx);
setOutline(o);
}
@@ -469,6 +466,21 @@
mBarView.disableHwLayers();
}
+ /** Sets the stubbed state of this task view. */
+ void setStubState(boolean isStub) {
+ if (!mIsStub && isStub) {
+ // This is now a stub task view, so clip to the bar height, hide the thumbnail
+ setClipBounds(new Rect(0, 0, getMeasuredWidth(), mBarView.getMeasuredHeight()));
+ mThumbnailView.setVisibility(View.INVISIBLE);
+ // Temporary
+ mBarView.mActivityDescription.setText("Stub");
+ } else if (mIsStub && !isStub) {
+ setClipBounds(null);
+ mThumbnailView.setVisibility(View.VISIBLE);
+ }
+ mIsStub = isStub;
+ }
+
/**
* Returns whether this view should be clipped, or any views below should clip against this
* view.
@@ -573,7 +585,9 @@
mThumbnailView.rebindToTask(mTask);
mBarView.rebindToTask(mTask);
// Rebind any listeners
- mBarView.mApplicationIcon.setOnClickListener(this);
+ if (Constants.DebugFlags.App.EnableTaskFiltering) {
+ mBarView.mApplicationIcon.setOnClickListener(this);
+ }
mBarView.mDismissButton.setOnClickListener(this);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
if (mConfig.developerOptionsEnabled) {
@@ -592,7 +606,9 @@
mThumbnailView.unbindFromTask();
mBarView.unbindFromTask();
// Unbind any listeners
- mBarView.mApplicationIcon.setOnClickListener(null);
+ if (Constants.DebugFlags.App.EnableTaskFiltering) {
+ mBarView.mApplicationIcon.setOnClickListener(null);
+ }
mBarView.mDismissButton.setOnClickListener(null);
if (Constants.DebugFlags.App.EnableDevAppInfoOnLongPress) {
mBarView.mApplicationIcon.setOnLongClickListener(null);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
index fa97d2c..ec24198 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/ViewAnimation.java
@@ -17,7 +17,7 @@
package com.android.systemui.recents.views;
import android.graphics.Rect;
-import com.android.systemui.recents.ReferenceCountedTrigger;
+import com.android.systemui.recents.misc.ReferenceCountedTrigger;
/* Common code related to view animations */
public class ViewAnimation {