summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/policy/DividerSnapAlgorithm.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java92
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java4
10 files changed, 132 insertions, 54 deletions
diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
index b8bc1618b3a3..d6172db3d369 100644
--- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
+++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java
@@ -86,7 +86,7 @@ public class DividerSnapAlgorithm {
return new DividerSnapAlgorithm(ctx.getResources(),
displayInfo.logicalWidth, displayInfo.logicalHeight,
dividerWindowWidth - 2 * dividerInsets,
- ctx.getResources().getConfiguration().orientation
+ ctx.getApplicationContext().getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT,
insets);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index f41355cc14f7..24260d5c8bed 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -451,11 +451,13 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD
TaskStack stack = loadPlan.getTaskStack();
int numStackTasks = stack.getStackTaskCount();
+ boolean showDeferredAnimation = numStackTasks > 0;
EventBus.getDefault().send(new ConfigurationChangedEvent(true /* fromMultiWindow */,
false /* fromDeviceOrientationChange */, false /* fromDisplayDensityChange */,
numStackTasks > 0));
- EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode, stack));
+ EventBus.getDefault().send(new MultiWindowStateChangedEvent(isInMultiWindowMode,
+ showDeferredAnimation, stack));
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
index 11649fbbb6a6..64eeafa1ae17 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/MultiWindowStateChangedEvent.java
@@ -25,10 +25,14 @@ import com.android.systemui.recents.model.TaskStack;
public class MultiWindowStateChangedEvent extends EventBus.AnimatedEvent {
public final boolean inMultiWindow;
+ // This flag is only used when undocking a task
+ public final boolean showDeferredAnimation;
public final TaskStack stack;
- public MultiWindowStateChangedEvent(boolean inMultiWindow, TaskStack stack) {
+ public MultiWindowStateChangedEvent(boolean inMultiWindow, boolean showDeferredAnimation,
+ TaskStack stack) {
this.inMultiWindow = inMultiWindow;
+ this.showDeferredAnimation = showDeferredAnimation;
this.stack = stack;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
index 7bd0958ebb24..0628c5015153 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/events/ui/TaskViewDismissedEvent.java
@@ -18,6 +18,7 @@ package com.android.systemui.recents.events.ui;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.model.Task;
+import com.android.systemui.recents.views.AnimationProps;
import com.android.systemui.recents.views.TaskView;
/**
@@ -27,9 +28,11 @@ public class TaskViewDismissedEvent extends EventBus.Event {
public final Task task;
public final TaskView taskView;
+ public final AnimationProps animation;
- public TaskViewDismissedEvent(Task task, TaskView taskView) {
+ public TaskViewDismissedEvent(Task task, TaskView taskView, AnimationProps animation) {
this.task = task;
this.taskView = taskView;
+ this.animation = animation;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 0e5ebc9173bb..c692a16ba2a5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -193,7 +193,7 @@ public class RecentsViewTouchHandler {
}
public final void onBusEvent(ConfigurationChangedEvent event) {
- if (event.fromDisplayDensityChange) {
+ if (event.fromDisplayDensityChange || event.fromDeviceOrientationChange) {
updateSnapAlgorithm();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
index b422cca25a82..cc8e83242fb4 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java
@@ -19,6 +19,7 @@ package com.android.systemui.recents.views;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
@@ -309,6 +310,11 @@ public class TaskStackAnimationHelper {
for (int i = 0; i < taskViewCount; i++) {
int taskIndexFromFront = taskViewCount - i - 1;
TaskView tv = taskViews.get(i);
+ Task task = tv.getTask();
+
+ if (mStackView.isIgnoredTask(task)) {
+ continue;
+ }
// Animate the tasks down
AnimationProps taskAnimation;
@@ -384,29 +390,29 @@ public class TaskStackAnimationHelper {
*/
public void startDeleteTaskAnimation(final TaskView deleteTaskView,
final ReferenceCountedTrigger postAnimationTrigger) {
- Resources res = mStackView.getResources();
- TaskStackLayoutAlgorithm stackLayout = mStackView.getStackAlgorithm();
+ TaskStackViewTouchHandler touchHandler = mStackView.getTouchHandler();
+ touchHandler.onBeginManualDrag(deleteTaskView);
- int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
-
- // Disabling clipping with the stack while the view is animating away, this will get
- // restored when the task is next picked up from the view pool
- deleteTaskView.setClipViewInStack(false);
+ postAnimationTrigger.increment();
+ postAnimationTrigger.addLastDecrementRunnable(() -> {
+ touchHandler.onChildDismissed(deleteTaskView);
+ });
- // Compose the new animation and transform and star the animation
- AnimationProps taskAnimation = new AnimationProps(DISMISS_TASK_DURATION,
- Interpolators.ALPHA_OUT, new AnimatorListenerAdapter() {
+ final float dismissSize = touchHandler.getScaledDismissSize();
+ ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
+ animator.setDuration(400);
+ animator.addUpdateListener((animation) -> {
+ float progress = (Float) animation.getAnimatedValue();
+ deleteTaskView.setTranslationX(progress * dismissSize);
+ touchHandler.updateSwipeProgress(deleteTaskView, true, progress);
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
postAnimationTrigger.decrement();
}
});
- postAnimationTrigger.increment();
-
- mTmpTransform.fillIn(deleteTaskView);
- mTmpTransform.alpha = 0f;
- mTmpTransform.rect.offset(offscreenXOffset, 0);
- mStackView.updateTaskViewToTransform(deleteTaskView, mTmpTransform, taskAnimation);
+ animator.start();
}
/**
@@ -419,7 +425,6 @@ public class TaskStackAnimationHelper {
int offscreenXOffset = mStackView.getMeasuredWidth() - stackLayout.mTaskRect.left;
int taskViewCount = taskViews.size();
-
for (int i = taskViewCount - 1; i >= 0; i--) {
TaskView tv = taskViews.get(i);
int taskIndexFromFront = taskViewCount - i - 1;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
index 270d981734fb..77b733881a0f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java
@@ -623,6 +623,24 @@ public class TaskStackLayoutAlgorithm {
}
}
+ /**
+ * Adds and override task progress for the given task when transitioning from focused to
+ * unfocused state.
+ */
+ public void addUnfocusedTaskOverride(TaskView taskView, float stackScroll) {
+ mFocusedRange.offset(stackScroll);
+ mUnfocusedRange.offset(stackScroll);
+
+ Task task = taskView.getTask();
+ int top = taskView.getTop() - mTaskRect.top;
+ float focusedRangeX = getNormalizedXFromFocusedY(top, FROM_TOP);
+ float unfocusedRangeX = getNormalizedXFromUnfocusedY(top, FROM_TOP);
+ float unfocusedTaskProgress = stackScroll + mUnfocusedRange.getAbsoluteX(unfocusedRangeX);
+ if (Float.compare(focusedRangeX, unfocusedRangeX) != 0) {
+ mTaskIndexOverrideMap.put(task.key.id, unfocusedTaskProgress);
+ }
+ }
+
public void clearUnfocusedTaskOverrides() {
mTaskIndexOverrideMap.clear();
}
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 a1584829e0db..773e5875b04f 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -420,6 +420,13 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
/**
+ * Returns the touch handler for this task stack.
+ */
+ public TaskStackViewTouchHandler getTouchHandler() {
+ return mTouchHandler;
+ }
+
+ /**
* Adds a task to the ignored set.
*/
void addIgnoreTask(Task task) {
@@ -1664,7 +1671,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
public final void onBusEvent(DismissRecentsToHomeAnimationStarted event) {
// Stop any scrolling
- mTouchHandler.finishAnimations();
+ mTouchHandler.cancelNonDismissTaskAnimations();
mStackScroller.stopScroller();
mStackScroller.stopBoundScrollAnimation();
cancelDeferredTaskViewLayoutAnimation();
@@ -1722,8 +1729,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
R.string.accessibility_recents_item_dismissed, event.task.title));
// Remove the task from the stack
- mStack.removeTask(event.task, new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
- Interpolators.FAST_OUT_SLOW_IN), false /* fromDockGesture */);
+ mStack.removeTask(event.task, event.animation, false /* fromDockGesture */);
EventBus.getDefault().send(new DeleteTaskDataEvent(event.task));
MetricsLogger.action(getContext(), MetricsEvent.OVERVIEW_DISMISS,
@@ -1938,7 +1944,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
public final void onBusEvent(final MultiWindowStateChangedEvent event) {
- if (event.inMultiWindow) {
+ if (event.inMultiWindow || !event.showDeferredAnimation) {
setTasks(event.stack, true /* allowNotifyStackChanges */);
} else {
// Reset the launch state before handling the multiwindow change
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 81242fdd4e64..b554a467c7ce 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java
@@ -32,7 +32,6 @@ import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.view.ViewParent;
import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
@@ -189,15 +188,30 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
}
/**
- * Finishes all scroll-fling and swipe animations currently running.
+ * Finishes all scroll-fling and non-dismissing animations currently running.
*/
- public void finishAnimations() {
+ public void cancelNonDismissTaskAnimations() {
Utilities.cancelAnimationWithoutCallbacks(mScrollFlingAnimator);
- ArrayMap<View, Animator> existingAnimators = new ArrayMap<>(mSwipeHelperAnimations);
- for (int i = 0; i < existingAnimators.size(); i++) {
- existingAnimators.get(existingAnimators.keyAt(i)).end();
+ if (!mSwipeHelperAnimations.isEmpty()) {
+ // For the non-dismissing tasks, freeze the position into the task overrides
+ List<TaskView> taskViews = mSv.getTaskViews();
+ for (int i = taskViews.size() - 1; i >= 0; i--) {
+ TaskView tv = taskViews.get(i);
+
+ if (mSv.isIgnoredTask(tv.getTask())) {
+ continue;
+ }
+
+ tv.cancelTransformAnimation();
+ mSv.getStackAlgorithm().addUnfocusedTaskOverride(tv, mTargetStackScroll);
+ }
+ mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
+ // Update the scroll to the final scroll position from onBeginDrag()
+ mSv.getScroller().setStackScroll(mTargetStackScroll, null);
+
+ mSwipeHelperAnimations.clear();
}
- mSwipeHelperAnimations.clear();
+ mActiveTaskView = null;
}
private boolean handleTouchEvent(MotionEvent ev) {
@@ -210,6 +224,13 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
int action = ev.getAction();
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
+ // Stop the current scroll if it is still flinging
+ mScroller.stopScroller();
+ mScroller.stopBoundScrollAnimation();
+ mScroller.resetDeltaScroll();
+ cancelNonDismissTaskAnimations();
+ mSv.cancelDeferredTaskViewLayoutAnimation();
+
// Save the touch down info
mDownX = (int) ev.getX();
mDownY = (int) ev.getY();
@@ -218,13 +239,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
mActivePointerId = ev.getPointerId(0);
mActiveTaskView = findViewAtPoint(mDownX, mDownY);
- // Stop the current scroll if it is still flinging
- mSv.cancelDeferredTaskViewLayoutAnimation();
- mScroller.stopScroller();
- mScroller.stopBoundScrollAnimation();
- mScroller.resetDeltaScroll();
- finishAnimations();
-
// Initialize the velocity tracker
initOrResetVelocityTracker();
mVelocityTracker.addMovement(ev);
@@ -431,8 +445,18 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
public boolean canChildBeDismissed(View v) {
// Disallow dismissing an already dismissed task
TaskView tv = (TaskView) v;
+ Task task = tv.getTask();
return !mSwipeHelperAnimations.containsKey(v) &&
- (mSv.getStack().indexOfStackTask(tv.getTask()) != -1);
+ (mSv.getStack().indexOfStackTask(task) != -1);
+ }
+
+ /**
+ * Starts a manual drag that goes through the same swipe helper path.
+ */
+ public void onBeginManualDrag(TaskView v) {
+ mActiveTaskView = v;
+ mSwipeHelperAnimations.put(v, null);
+ onBeginDrag(v);
}
@Override
@@ -453,7 +477,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
mSv.addIgnoreTask(tv.getTask());
// Determine if we are animating the other tasks while dismissing this task
- mCurrentTasks = mSv.getStack().getStackTasks();
+ mCurrentTasks = new ArrayList<Task>(mSv.getStack().getStackTasks());
MutableBoolean isFrontMostTask = new MutableBoolean(false);
Task anchorTask = mSv.findAnchorTask(mCurrentTasks, isFrontMostTask);
TaskStackLayoutAlgorithm layoutAlgorithm = mSv.getStackAlgorithm();
@@ -513,7 +537,12 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
@Override
public boolean updateSwipeProgress(View v, boolean dismissable, float swipeProgress) {
- updateTaskViewTransforms(Interpolators.FAST_OUT_SLOW_IN.getInterpolation(swipeProgress));
+ // Only update the swipe progress for the surrounding tasks if the dismiss animation was not
+ // preempted from a call to cancelNonDismissTaskAnimations
+ if (mActiveTaskView == v || mSwipeHelperAnimations.containsKey(v)) {
+ updateTaskViewTransforms(
+ Interpolators.FAST_OUT_SLOW_IN.getInterpolation(swipeProgress));
+ }
return true;
}
@@ -528,15 +557,24 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
tv.setClipViewInStack(true);
// Re-enable touch events from this task view
tv.setTouchEnabled(true);
- // Remove the task view from the stack
- EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv));
- // Update the scroll to the final scroll position from onBeginDrag()
- mSv.getScroller().setStackScroll(mTargetStackScroll, null);
- // Update the focus state to the final focus state
- mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
- mSv.getStackAlgorithm().clearUnfocusedTaskOverrides();
- // Stop tracking this deletion animation
- mSwipeHelperAnimations.remove(v);
+ // Remove the task view from the stack, ignoring the animation if we've started dragging
+ // again
+ EventBus.getDefault().send(new TaskViewDismissedEvent(tv.getTask(), tv,
+ mSwipeHelperAnimations.containsKey(v)
+ ? new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
+ Interpolators.FAST_OUT_SLOW_IN)
+ : null));
+ // Only update the final scroll and layout state (set in onBeginDrag()) if the dismiss
+ // animation was not preempted from a call to cancelNonDismissTaskAnimations
+ if (mSwipeHelperAnimations.containsKey(v)) {
+ // Update the scroll to the final scroll position
+ mSv.getScroller().setStackScroll(mTargetStackScroll, null);
+ // Update the focus state to the final focus state
+ mSv.getStackAlgorithm().setFocusState(TaskStackLayoutAlgorithm.STATE_UNFOCUSED);
+ mSv.getStackAlgorithm().clearUnfocusedTaskOverrides();
+ // Stop tracking this deletion animation
+ mSwipeHelperAnimations.remove(v);
+ }
// Keep track of deletions by keyboard
MetricsLogger.histogram(tv.getContext(), "overview_task_dismissed_source",
Constants.Metrics.DismissSourceSwipeGesture);
@@ -631,7 +669,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
/**
* Returns the scaled size used to calculate the dismiss fraction.
*/
- private float getScaledDismissSize() {
+ public float getScaledDismissSize() {
return 1.5f * Math.max(mSv.getWidth(), mSv.getHeight());
}
}
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 1d476c60309b..c1e7e0403c88 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -388,7 +388,9 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks
dismissEvent.addPostAnimationCallback(new Runnable() {
@Override
public void run() {
- EventBus.getDefault().send(new TaskViewDismissedEvent(mTask, tv));
+ EventBus.getDefault().send(new TaskViewDismissedEvent(mTask, tv,
+ new AnimationProps(TaskStackView.DEFAULT_SYNC_STACK_DURATION,
+ Interpolators.FAST_OUT_SLOW_IN)));
}
});
EventBus.getDefault().send(dismissEvent);