diff options
| author | 2016-05-03 21:57:01 +0000 | |
|---|---|---|
| committer | 2016-05-03 21:57:03 +0000 | |
| commit | bd1708a19da3ae205c4da3f22d0682c9bd1f76fe (patch) | |
| tree | e8f9a039ed8e5cc8caa361fb131875c8637c1cb2 | |
| parent | c18009e6dd32f04fdad7f1b27a0a6b52ee5c875c (diff) | |
| parent | 61560f065a334343d9c552796e1c702f4dfb664b (diff) | |
Merge changes If7b8ed3f,I309c3825,Iafd06419,I59f73caf into nyc-dev
* changes:
Fixes several animation issues related to a dismissing task.
Pipe the dismiss button logic through the touch handler.
Skip scroll-to animation when undocking and there are no tasks.
Fixing issue with docking being disallowed for secondary user.
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); |