Loading packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java +9 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.graphics.Color; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.Trace; import android.util.ArraySet; import android.util.IntProperty; import android.util.Property; Loading Loading @@ -260,6 +261,14 @@ public class Utilities { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics()); } /** * Adds a trace event for debugging. */ public static void addTraceEvent(String event) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, event); Trace.traceEnd(Trace.TRACE_TAG_VIEW); } /** * Returns a lightweight dump of a rect. */ Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +26 −12 Original line number Diff line number Diff line Loading @@ -23,13 +23,13 @@ import android.content.res.Resources; import android.graphics.Path; import android.graphics.Rect; import android.util.ArraySet; import android.util.MutableFloat; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.ViewDebug; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsActivity; import com.android.systemui.recents.RecentsActivityLaunchState; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.RecentsDebugFlags; Loading Loading @@ -628,22 +628,24 @@ public class TaskStackLayoutAlgorithm { /** * Updates this stack when a scroll happens. * */ public void updateFocusStateOnScroll(float stackScroll, float deltaScroll) { if (deltaScroll == 0f) { return; public float updateFocusStateOnScroll(float lastTargetStackScroll, float targetStackScroll, float lastStackScroll) { if (targetStackScroll == lastStackScroll) { return targetStackScroll; } float deltaScroll = targetStackScroll - lastStackScroll; float deltaTargetScroll = targetStackScroll - lastTargetStackScroll; float newScroll = targetStackScroll; mUnfocusedRange.offset(targetStackScroll); for (int i = mTaskIndexOverrideMap.size() - 1; i >= 0; i--) { int taskId = mTaskIndexOverrideMap.keyAt(i); float x = mTaskIndexMap.get(taskId); float overrideX = mTaskIndexOverrideMap.get(taskId, 0f); float newOverrideX = overrideX + deltaScroll; mUnfocusedRange.offset(stackScroll); boolean outOfBounds = mUnfocusedRange.getNormalizedX(newOverrideX) < 0f || mUnfocusedRange.getNormalizedX(newOverrideX) > 1f; if (outOfBounds || (overrideX >= x && x >= newOverrideX) || (overrideX <= x && x <= newOverrideX)) { if (isInvalidOverrideX(x, overrideX, newOverrideX)) { // Remove the override once we reach the original task index mTaskIndexOverrideMap.removeAt(i); } else if ((overrideX >= x && deltaScroll <= 0f) || Loading @@ -652,11 +654,23 @@ public class TaskStackLayoutAlgorithm { mTaskIndexOverrideMap.put(taskId, newOverrideX); } else { // Scrolling override x away from x, we should still move the scroll towards x float deltaX = overrideX - x; newOverrideX = Math.signum(deltaX) * (Math.abs(deltaX) - Math.abs(deltaScroll)); mTaskIndexOverrideMap.put(taskId, x + newOverrideX); newScroll = lastStackScroll; newOverrideX = overrideX - deltaTargetScroll; if (isInvalidOverrideX(x, overrideX, newOverrideX)) { mTaskIndexOverrideMap.removeAt(i); } else{ mTaskIndexOverrideMap.put(taskId, newOverrideX); } } } return newScroll; } private boolean isInvalidOverrideX(float x, float overrideX, float newOverrideX) { boolean outOfBounds = mUnfocusedRange.getNormalizedX(newOverrideX) < 0f || mUnfocusedRange.getNormalizedX(newOverrideX) > 1f; return outOfBounds || (overrideX >= x && x >= newOverrideX) || (overrideX <= x && x <= newOverrideX); } /** Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +0 −1 Original line number Diff line number Diff line Loading @@ -1618,7 +1618,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (animation != null) { relayoutTaskViewsOnNextFrame(animation); } mLayoutAlgorithm.updateFocusStateOnScroll(curScroll, curScroll - prevScroll); if (mEnterAnimationComplete) { if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD && Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +29 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.animation.ObjectAnimator; import android.content.Context; import android.util.FloatProperty; import android.util.Log; import android.util.MutableFloat; import android.util.Property; import android.view.ViewDebug; import android.widget.OverScroller; Loading Loading @@ -66,6 +67,8 @@ public class TaskStackViewScroller { @ViewDebug.ExportedProperty(category="recents") float mStackScrollP; @ViewDebug.ExportedProperty(category="recents") float mLastDeltaP = 0f; float mFlingDownScrollP; int mFlingDownY; Loading @@ -84,6 +87,11 @@ public class TaskStackViewScroller { /** Resets the task scroller. */ void reset() { mStackScrollP = 0f; mLastDeltaP = 0f; } void resetDeltaScroll() { mLastDeltaP = 0f; } /** Gets the current stack scroll */ Loading @@ -98,15 +106,28 @@ public class TaskStackViewScroller { setStackScroll(s, AnimationProps.IMMEDIATE); } /** * Sets the current stack scroll immediately, and returns the difference between the target * scroll and the actual scroll after accounting for the effect on the focus state. */ public float setDeltaStackScroll(float downP, float deltaP) { float targetScroll = downP + deltaP; float newScroll = mLayoutAlgorithm.updateFocusStateOnScroll(downP + mLastDeltaP, targetScroll, mStackScrollP); setStackScroll(newScroll, AnimationProps.IMMEDIATE); mLastDeltaP = deltaP; return newScroll - targetScroll; } /** * Sets the current stack scroll, but indicates to the callback the preferred animation to * update to this new scroll. */ public void setStackScroll(float s, AnimationProps animation) { float prevStackScroll = mStackScrollP; mStackScrollP = s; public void setStackScroll(float newScroll, AnimationProps animation) { float prevScroll = mStackScrollP; mStackScrollP = newScroll; if (mCb != null) { mCb.onStackScrollChanged(prevStackScroll, mStackScrollP, animation); mCb.onStackScrollChanged(prevScroll, mStackScrollP, animation); } } Loading @@ -115,9 +136,9 @@ public class TaskStackViewScroller { * @return whether the stack progress changed. */ public boolean setStackScrollToInitialState() { float prevStackScrollP = mStackScrollP; float prevScroll = mStackScrollP; setStackScroll(mLayoutAlgorithm.mInitialScrollP); return Float.compare(prevStackScrollP, mStackScrollP) != 0; return Float.compare(prevScroll, mStackScrollP) != 0; } /** Loading Loading @@ -227,10 +248,9 @@ public class TaskStackViewScroller { boolean computeScroll() { if (mScroller.computeScrollOffset()) { float deltaP = mLayoutAlgorithm.getDeltaPForY(mFlingDownY, mScroller.getCurrY()); float scroll = mFlingDownScrollP + deltaP; setStackScroll(scroll); mFlingDownScrollP += setDeltaStackScroll(mFlingDownScrollP, deltaP); if (DEBUG) { Log.d(TAG, "computeScroll: " + scroll); Log.d(TAG, "computeScroll: " + (mFlingDownScrollP + deltaP)); } return true; } Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +8 −5 Original line number Diff line number Diff line Loading @@ -200,6 +200,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { // Stop the current scroll if it is still flinging mScroller.stopScroller(); mScroller.stopBoundScrollAnimation(); mScroller.resetDeltaScroll(); Utilities.cancelAnimationWithoutCallbacks(mScrollFlingAnimator); // Finish any existing task animations from the delete Loading @@ -223,6 +224,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { mDownY = (int) ev.getY(index); mLastY = mDownY; mDownScrollP = mScroller.getStackScroll(); mScroller.resetDeltaScroll(); mVelocityTracker.addMovement(ev); break; } Loading Loading @@ -256,20 +258,21 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { // If we just move linearly on the screen, then that would map to 1/arclength // of the curve, so just move the scroll proportional to that float deltaP = layoutAlgorithm.getDeltaPForY(mDownY, y); float curScrollP = mDownScrollP + deltaP; // Modulate the overscroll to prevent users from pulling the stack too far float minScrollP = layoutAlgorithm.mMinScrollP; float maxScrollP = layoutAlgorithm.mMaxScrollP; float curScrollP = mDownScrollP + deltaP; if (curScrollP < minScrollP || curScrollP > maxScrollP) { float clampedScrollP = Utilities.clamp(curScrollP, minScrollP, maxScrollP); float overscrollP = (curScrollP - clampedScrollP); float overscrollX = Math.abs(overscrollP) / MAX_OVERSCROLL; curScrollP = clampedScrollP + (Math.signum(overscrollP) * (OVERSCROLL_INTERP.getInterpolation(overscrollX) * MAX_OVERSCROLL)); float interpX = OVERSCROLL_INTERP.getInterpolation(overscrollX); curScrollP = clampedScrollP + Math.signum(overscrollP) * (interpX * MAX_OVERSCROLL); } mScroller.setStackScroll(curScrollP); mDownScrollP += mScroller.setDeltaStackScroll(mDownScrollP, curScrollP - mDownScrollP); mStackViewScrolledEvent.updateY(y - mLastY); EventBus.getDefault().send(mStackViewScrolledEvent); } Loading Loading
packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java +9 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.graphics.Color; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.Trace; import android.util.ArraySet; import android.util.IntProperty; import android.util.Property; Loading Loading @@ -260,6 +261,14 @@ public class Utilities { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics()); } /** * Adds a trace event for debugging. */ public static void addTraceEvent(String event) { Trace.traceBegin(Trace.TRACE_TAG_VIEW, event); Trace.traceEnd(Trace.TRACE_TAG_VIEW); } /** * Returns a lightweight dump of a rect. */ Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +26 −12 Original line number Diff line number Diff line Loading @@ -23,13 +23,13 @@ import android.content.res.Resources; import android.graphics.Path; import android.graphics.Rect; import android.util.ArraySet; import android.util.MutableFloat; import android.util.SparseArray; import android.util.SparseIntArray; import android.view.ViewDebug; import com.android.systemui.R; import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsActivity; import com.android.systemui.recents.RecentsActivityLaunchState; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.RecentsDebugFlags; Loading Loading @@ -628,22 +628,24 @@ public class TaskStackLayoutAlgorithm { /** * Updates this stack when a scroll happens. * */ public void updateFocusStateOnScroll(float stackScroll, float deltaScroll) { if (deltaScroll == 0f) { return; public float updateFocusStateOnScroll(float lastTargetStackScroll, float targetStackScroll, float lastStackScroll) { if (targetStackScroll == lastStackScroll) { return targetStackScroll; } float deltaScroll = targetStackScroll - lastStackScroll; float deltaTargetScroll = targetStackScroll - lastTargetStackScroll; float newScroll = targetStackScroll; mUnfocusedRange.offset(targetStackScroll); for (int i = mTaskIndexOverrideMap.size() - 1; i >= 0; i--) { int taskId = mTaskIndexOverrideMap.keyAt(i); float x = mTaskIndexMap.get(taskId); float overrideX = mTaskIndexOverrideMap.get(taskId, 0f); float newOverrideX = overrideX + deltaScroll; mUnfocusedRange.offset(stackScroll); boolean outOfBounds = mUnfocusedRange.getNormalizedX(newOverrideX) < 0f || mUnfocusedRange.getNormalizedX(newOverrideX) > 1f; if (outOfBounds || (overrideX >= x && x >= newOverrideX) || (overrideX <= x && x <= newOverrideX)) { if (isInvalidOverrideX(x, overrideX, newOverrideX)) { // Remove the override once we reach the original task index mTaskIndexOverrideMap.removeAt(i); } else if ((overrideX >= x && deltaScroll <= 0f) || Loading @@ -652,11 +654,23 @@ public class TaskStackLayoutAlgorithm { mTaskIndexOverrideMap.put(taskId, newOverrideX); } else { // Scrolling override x away from x, we should still move the scroll towards x float deltaX = overrideX - x; newOverrideX = Math.signum(deltaX) * (Math.abs(deltaX) - Math.abs(deltaScroll)); mTaskIndexOverrideMap.put(taskId, x + newOverrideX); newScroll = lastStackScroll; newOverrideX = overrideX - deltaTargetScroll; if (isInvalidOverrideX(x, overrideX, newOverrideX)) { mTaskIndexOverrideMap.removeAt(i); } else{ mTaskIndexOverrideMap.put(taskId, newOverrideX); } } } return newScroll; } private boolean isInvalidOverrideX(float x, float overrideX, float newOverrideX) { boolean outOfBounds = mUnfocusedRange.getNormalizedX(newOverrideX) < 0f || mUnfocusedRange.getNormalizedX(newOverrideX) > 1f; return outOfBounds || (overrideX >= x && x >= newOverrideX) || (overrideX <= x && x <= newOverrideX); } /** Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +0 −1 Original line number Diff line number Diff line Loading @@ -1618,7 +1618,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal if (animation != null) { relayoutTaskViewsOnNextFrame(animation); } mLayoutAlgorithm.updateFocusStateOnScroll(curScroll, curScroll - prevScroll); if (mEnterAnimationComplete) { if (prevScroll > SHOW_STACK_ACTION_BUTTON_SCROLL_THRESHOLD && Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +29 −9 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import android.animation.ObjectAnimator; import android.content.Context; import android.util.FloatProperty; import android.util.Log; import android.util.MutableFloat; import android.util.Property; import android.view.ViewDebug; import android.widget.OverScroller; Loading Loading @@ -66,6 +67,8 @@ public class TaskStackViewScroller { @ViewDebug.ExportedProperty(category="recents") float mStackScrollP; @ViewDebug.ExportedProperty(category="recents") float mLastDeltaP = 0f; float mFlingDownScrollP; int mFlingDownY; Loading @@ -84,6 +87,11 @@ public class TaskStackViewScroller { /** Resets the task scroller. */ void reset() { mStackScrollP = 0f; mLastDeltaP = 0f; } void resetDeltaScroll() { mLastDeltaP = 0f; } /** Gets the current stack scroll */ Loading @@ -98,15 +106,28 @@ public class TaskStackViewScroller { setStackScroll(s, AnimationProps.IMMEDIATE); } /** * Sets the current stack scroll immediately, and returns the difference between the target * scroll and the actual scroll after accounting for the effect on the focus state. */ public float setDeltaStackScroll(float downP, float deltaP) { float targetScroll = downP + deltaP; float newScroll = mLayoutAlgorithm.updateFocusStateOnScroll(downP + mLastDeltaP, targetScroll, mStackScrollP); setStackScroll(newScroll, AnimationProps.IMMEDIATE); mLastDeltaP = deltaP; return newScroll - targetScroll; } /** * Sets the current stack scroll, but indicates to the callback the preferred animation to * update to this new scroll. */ public void setStackScroll(float s, AnimationProps animation) { float prevStackScroll = mStackScrollP; mStackScrollP = s; public void setStackScroll(float newScroll, AnimationProps animation) { float prevScroll = mStackScrollP; mStackScrollP = newScroll; if (mCb != null) { mCb.onStackScrollChanged(prevStackScroll, mStackScrollP, animation); mCb.onStackScrollChanged(prevScroll, mStackScrollP, animation); } } Loading @@ -115,9 +136,9 @@ public class TaskStackViewScroller { * @return whether the stack progress changed. */ public boolean setStackScrollToInitialState() { float prevStackScrollP = mStackScrollP; float prevScroll = mStackScrollP; setStackScroll(mLayoutAlgorithm.mInitialScrollP); return Float.compare(prevStackScrollP, mStackScrollP) != 0; return Float.compare(prevScroll, mStackScrollP) != 0; } /** Loading Loading @@ -227,10 +248,9 @@ public class TaskStackViewScroller { boolean computeScroll() { if (mScroller.computeScrollOffset()) { float deltaP = mLayoutAlgorithm.getDeltaPForY(mFlingDownY, mScroller.getCurrY()); float scroll = mFlingDownScrollP + deltaP; setStackScroll(scroll); mFlingDownScrollP += setDeltaStackScroll(mFlingDownScrollP, deltaP); if (DEBUG) { Log.d(TAG, "computeScroll: " + scroll); Log.d(TAG, "computeScroll: " + (mFlingDownScrollP + deltaP)); } return true; } Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +8 −5 Original line number Diff line number Diff line Loading @@ -200,6 +200,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { // Stop the current scroll if it is still flinging mScroller.stopScroller(); mScroller.stopBoundScrollAnimation(); mScroller.resetDeltaScroll(); Utilities.cancelAnimationWithoutCallbacks(mScrollFlingAnimator); // Finish any existing task animations from the delete Loading @@ -223,6 +224,7 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { mDownY = (int) ev.getY(index); mLastY = mDownY; mDownScrollP = mScroller.getStackScroll(); mScroller.resetDeltaScroll(); mVelocityTracker.addMovement(ev); break; } Loading Loading @@ -256,20 +258,21 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { // If we just move linearly on the screen, then that would map to 1/arclength // of the curve, so just move the scroll proportional to that float deltaP = layoutAlgorithm.getDeltaPForY(mDownY, y); float curScrollP = mDownScrollP + deltaP; // Modulate the overscroll to prevent users from pulling the stack too far float minScrollP = layoutAlgorithm.mMinScrollP; float maxScrollP = layoutAlgorithm.mMaxScrollP; float curScrollP = mDownScrollP + deltaP; if (curScrollP < minScrollP || curScrollP > maxScrollP) { float clampedScrollP = Utilities.clamp(curScrollP, minScrollP, maxScrollP); float overscrollP = (curScrollP - clampedScrollP); float overscrollX = Math.abs(overscrollP) / MAX_OVERSCROLL; curScrollP = clampedScrollP + (Math.signum(overscrollP) * (OVERSCROLL_INTERP.getInterpolation(overscrollX) * MAX_OVERSCROLL)); float interpX = OVERSCROLL_INTERP.getInterpolation(overscrollX); curScrollP = clampedScrollP + Math.signum(overscrollP) * (interpX * MAX_OVERSCROLL); } mScroller.setStackScroll(curScrollP); mDownScrollP += mScroller.setDeltaStackScroll(mDownScrollP, curScrollP - mDownScrollP); mStackViewScrolledEvent.updateY(y - mLastY); EventBus.getDefault().send(mStackViewScrolledEvent); } Loading