Loading packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.recents.views; import android.app.ActivityOptions; import android.app.TaskStackBuilder; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -35,7 +34,6 @@ import android.view.WindowInsets; import android.widget.FrameLayout; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.misc.Console; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.model.RecentsPackageMonitor; Loading Loading @@ -339,7 +337,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV View child = getChildAt(i); if (child != mSearchBar) { TaskStackView stackView = (TaskStackView) child; stackView.focusNextTask(forward); stackView.focusNextTask(forward, true); break; } } Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +56 −15 Original line number Diff line number Diff line Loading @@ -414,7 +414,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } /** Focuses the task at the specified index in the stack */ void focusTask(int taskIndex, boolean scrollToNewPosition) { void focusTask(int taskIndex, boolean scrollToNewPosition, final boolean animateFocusedState) { // Return early if the task is already focused if (taskIndex == mFocusedTaskIndex) return; Loading @@ -426,7 +426,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal TaskView tv = getChildViewForTask(t); Runnable postScrollRunnable = null; if (tv != null) { tv.setFocusedTask(); tv.setFocusedTask(animateFocusedState); } else { postScrollRunnable = new Runnable() { @Override Loading @@ -434,7 +434,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal Task t = mStack.getTasks().get(mFocusedTaskIndex); TaskView tv = getChildViewForTask(t); if (tv != null) { tv.setFocusedTask(); tv.setFocusedTask(animateFocusedState); } } }; Loading @@ -454,18 +454,50 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } /** Focuses the next task in the stack */ void focusNextTask(boolean forward) { /** * Ensures that there is a task focused, if nothign is focused, then we will use the task * at the center of the visible stack. */ public boolean ensureFocusedTask() { if (mFocusedTaskIndex < 0) { // If there is no task focused, then find the task that is closes to the center // of the screen and use that as the currently focused task int x = mLayoutAlgorithm.mStackVisibleRect.centerX(); int y = mLayoutAlgorithm.mStackVisibleRect.centerY(); int childCount = getChildCount(); for (int i = childCount - 1; i >= 0; i--) { TaskView tv = (TaskView) getChildAt(i); tv.getHitRect(mTmpRect); if (mTmpRect.contains(x, y)) { mFocusedTaskIndex = mStack.indexOfTask(tv.getTask()); break; } } // If we can't find the center task, then use the front most index if (mFocusedTaskIndex < 0 && childCount > 0) { mFocusedTaskIndex = childCount - 1; } } return mFocusedTaskIndex >= 0; } /** * Focuses the next task in the stack. * @param animateFocusedState determines whether to actually draw the highlight along with * the change in focus, as well as whether to scroll to fit the * task into view. */ public void focusNextTask(boolean forward, boolean animateFocusedState) { // Find the next index to focus int numTasks = mStack.getTaskCount(); if (numTasks == 0) return; int nextFocusIndex = numTasks - 1; if (0 <= mFocusedTaskIndex && mFocusedTaskIndex < numTasks) { nextFocusIndex = Math.max(0, Math.min(numTasks - 1, mFocusedTaskIndex + (forward ? -1 : 1))); int direction = (forward ? -1 : 1); int newIndex = mFocusedTaskIndex + direction; if (newIndex >= 0 && newIndex <= (numTasks - 1)) { newIndex = Math.max(0, Math.min(numTasks - 1, newIndex)); focusTask(newIndex, true, animateFocusedState); } focusTask(nextFocusIndex, true); } /** Dismisses the focused task. */ Loading Loading @@ -504,6 +536,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal return mTouchHandler.onTouchEvent(ev); } @Override public boolean onGenericMotionEvent(MotionEvent ev) { return mTouchHandler.onGenericMotionEvent(ev); } @Override public void computeScroll() { mStackScroller.computeScroll(); Loading Loading @@ -652,9 +689,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // When Alt-Tabbing, we scroll to and focus the previous task if (mConfig.launchedWithAltTab) { if (mConfig.launchedFromHome) { focusTask(Math.max(0, mStack.getTaskCount() - 1), false); focusTask(Math.max(0, mStack.getTaskCount() - 1), false, true); } else { focusTask(Math.max(0, mStack.getTaskCount() - 2), false); focusTask(Math.max(0, mStack.getTaskCount() - 2), false, true); } } } Loading Loading @@ -1018,14 +1055,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal tv.getTask().activityLabel)); // Remove the task from the view mStack.removeTask(task); // If the dismissed task was focused, then we should focus the next task in front // If the dismissed task was focused, then we should focus the new task in the same index if (taskWasFocused) { ArrayList<Task> tasks = mStack.getTasks(); int nextTaskIndex = Math.min(tasks.size() - 1, taskIndex); int nextTaskIndex = Math.min(tasks.size() - 1, taskIndex - 1); if (nextTaskIndex >= 0) { Task nextTask = tasks.get(nextTaskIndex); TaskView nextTv = getChildViewForTask(nextTask); nextTv.setFocusedTask(); if (nextTv != null) { // Focus the next task, and only animate the visible state if we are launched // from Alt-Tab nextTv.setFocusedTask(mConfig.launchedWithAltTab); } } } } Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java +2 −6 Original line number Diff line number Diff line Loading @@ -199,18 +199,14 @@ public class TaskStackViewLayoutAlgorithm { return transformOut; } /** * Returns the untransformed task view size. */ /** Returns the untransformed task view size. */ public Rect getUntransformedTaskViewSize() { Rect tvSize = new Rect(mTaskRect); tvSize.offsetTo(0, 0); return tvSize; } /** * Returns the scroll to such task top = 1f; */ /** Returns the scroll to such task top = 1f; */ float getStackScrollForTask(Task t) { return mTaskProgressMap.get(t.key); } Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +7 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ public class TaskStackViewScroller { OverScroller mScroller; ObjectAnimator mScrollAnimator; float mFinalAnimatedScroll; public TaskStackViewScroller(Context context, RecentsConfiguration config, TaskStackViewLayoutAlgorithm layoutAlgorithm) { mConfig = config; Loading Loading @@ -128,10 +129,15 @@ public class TaskStackViewScroller { /** Animates the stack scroll */ void animateScroll(float curScroll, float newScroll, final Runnable postRunnable) { // Abort any current animations // Finish any current scrolling animations if (mScrollAnimator != null && mScrollAnimator.isRunning()) { setStackScroll(mFinalAnimatedScroll); mScroller.startScroll(0, progressToScrollRange(mFinalAnimatedScroll), 0, 0, 0); } stopScroller(); stopBoundScrollAnimation(); mFinalAnimatedScroll = newScroll; mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll); mScrollAnimator.setDuration(mConfig.taskStackScrollDuration); mScrollAnimator.setInterpolator(mConfig.linearOutSlowInInterpolator); Loading packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +25 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.recents.views; import android.content.Context; import android.view.InputDevice; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; Loading Loading @@ -189,7 +190,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { /** Handles touch events once we have intercepted them */ public boolean onTouchEvent(MotionEvent ev) { // Short circuit if we have no children boolean hasChildren = (mSv.getChildCount() > 0); if (!hasChildren) { Loading Loading @@ -336,6 +336,30 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { return true; } /** Handles generic motion events */ public boolean onGenericMotionEvent(MotionEvent ev) { if ((ev.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER) { int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_SCROLL: // Find the front most task and scroll the next task to the front float vScroll = ev.getAxisValue(MotionEvent.AXIS_VSCROLL); if (vScroll > 0) { if (mSv.ensureFocusedTask()) { mSv.focusNextTask(true, false); } } else { if (mSv.ensureFocusedTask()) { mSv.focusNextTask(false, false); } } return true; } } return false; } /**** SwipeHelper Implementation ****/ @Override Loading Loading
packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.recents.views; import android.app.ActivityOptions; import android.app.TaskStackBuilder; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Context; import android.content.Intent; Loading @@ -35,7 +34,6 @@ import android.view.WindowInsets; import android.widget.FrameLayout; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.misc.Console; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.model.RecentsPackageMonitor; Loading Loading @@ -339,7 +337,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV View child = getChildAt(i); if (child != mSearchBar) { TaskStackView stackView = (TaskStackView) child; stackView.focusNextTask(forward); stackView.focusNextTask(forward, true); break; } } Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +56 −15 Original line number Diff line number Diff line Loading @@ -414,7 +414,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } /** Focuses the task at the specified index in the stack */ void focusTask(int taskIndex, boolean scrollToNewPosition) { void focusTask(int taskIndex, boolean scrollToNewPosition, final boolean animateFocusedState) { // Return early if the task is already focused if (taskIndex == mFocusedTaskIndex) return; Loading @@ -426,7 +426,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal TaskView tv = getChildViewForTask(t); Runnable postScrollRunnable = null; if (tv != null) { tv.setFocusedTask(); tv.setFocusedTask(animateFocusedState); } else { postScrollRunnable = new Runnable() { @Override Loading @@ -434,7 +434,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal Task t = mStack.getTasks().get(mFocusedTaskIndex); TaskView tv = getChildViewForTask(t); if (tv != null) { tv.setFocusedTask(); tv.setFocusedTask(animateFocusedState); } } }; Loading @@ -454,18 +454,50 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal } } /** Focuses the next task in the stack */ void focusNextTask(boolean forward) { /** * Ensures that there is a task focused, if nothign is focused, then we will use the task * at the center of the visible stack. */ public boolean ensureFocusedTask() { if (mFocusedTaskIndex < 0) { // If there is no task focused, then find the task that is closes to the center // of the screen and use that as the currently focused task int x = mLayoutAlgorithm.mStackVisibleRect.centerX(); int y = mLayoutAlgorithm.mStackVisibleRect.centerY(); int childCount = getChildCount(); for (int i = childCount - 1; i >= 0; i--) { TaskView tv = (TaskView) getChildAt(i); tv.getHitRect(mTmpRect); if (mTmpRect.contains(x, y)) { mFocusedTaskIndex = mStack.indexOfTask(tv.getTask()); break; } } // If we can't find the center task, then use the front most index if (mFocusedTaskIndex < 0 && childCount > 0) { mFocusedTaskIndex = childCount - 1; } } return mFocusedTaskIndex >= 0; } /** * Focuses the next task in the stack. * @param animateFocusedState determines whether to actually draw the highlight along with * the change in focus, as well as whether to scroll to fit the * task into view. */ public void focusNextTask(boolean forward, boolean animateFocusedState) { // Find the next index to focus int numTasks = mStack.getTaskCount(); if (numTasks == 0) return; int nextFocusIndex = numTasks - 1; if (0 <= mFocusedTaskIndex && mFocusedTaskIndex < numTasks) { nextFocusIndex = Math.max(0, Math.min(numTasks - 1, mFocusedTaskIndex + (forward ? -1 : 1))); int direction = (forward ? -1 : 1); int newIndex = mFocusedTaskIndex + direction; if (newIndex >= 0 && newIndex <= (numTasks - 1)) { newIndex = Math.max(0, Math.min(numTasks - 1, newIndex)); focusTask(newIndex, true, animateFocusedState); } focusTask(nextFocusIndex, true); } /** Dismisses the focused task. */ Loading Loading @@ -504,6 +536,11 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal return mTouchHandler.onTouchEvent(ev); } @Override public boolean onGenericMotionEvent(MotionEvent ev) { return mTouchHandler.onGenericMotionEvent(ev); } @Override public void computeScroll() { mStackScroller.computeScroll(); Loading Loading @@ -652,9 +689,9 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // When Alt-Tabbing, we scroll to and focus the previous task if (mConfig.launchedWithAltTab) { if (mConfig.launchedFromHome) { focusTask(Math.max(0, mStack.getTaskCount() - 1), false); focusTask(Math.max(0, mStack.getTaskCount() - 1), false, true); } else { focusTask(Math.max(0, mStack.getTaskCount() - 2), false); focusTask(Math.max(0, mStack.getTaskCount() - 2), false, true); } } } Loading Loading @@ -1018,14 +1055,18 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal tv.getTask().activityLabel)); // Remove the task from the view mStack.removeTask(task); // If the dismissed task was focused, then we should focus the next task in front // If the dismissed task was focused, then we should focus the new task in the same index if (taskWasFocused) { ArrayList<Task> tasks = mStack.getTasks(); int nextTaskIndex = Math.min(tasks.size() - 1, taskIndex); int nextTaskIndex = Math.min(tasks.size() - 1, taskIndex - 1); if (nextTaskIndex >= 0) { Task nextTask = tasks.get(nextTaskIndex); TaskView nextTv = getChildViewForTask(nextTask); nextTv.setFocusedTask(); if (nextTv != null) { // Focus the next task, and only animate the visible state if we are launched // from Alt-Tab nextTv.setFocusedTask(mConfig.launchedWithAltTab); } } } } Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewLayoutAlgorithm.java +2 −6 Original line number Diff line number Diff line Loading @@ -199,18 +199,14 @@ public class TaskStackViewLayoutAlgorithm { return transformOut; } /** * Returns the untransformed task view size. */ /** Returns the untransformed task view size. */ public Rect getUntransformedTaskViewSize() { Rect tvSize = new Rect(mTaskRect); tvSize.offsetTo(0, 0); return tvSize; } /** * Returns the scroll to such task top = 1f; */ /** Returns the scroll to such task top = 1f; */ float getStackScrollForTask(Task t) { return mTaskProgressMap.get(t.key); } Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +7 −1 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ public class TaskStackViewScroller { OverScroller mScroller; ObjectAnimator mScrollAnimator; float mFinalAnimatedScroll; public TaskStackViewScroller(Context context, RecentsConfiguration config, TaskStackViewLayoutAlgorithm layoutAlgorithm) { mConfig = config; Loading Loading @@ -128,10 +129,15 @@ public class TaskStackViewScroller { /** Animates the stack scroll */ void animateScroll(float curScroll, float newScroll, final Runnable postRunnable) { // Abort any current animations // Finish any current scrolling animations if (mScrollAnimator != null && mScrollAnimator.isRunning()) { setStackScroll(mFinalAnimatedScroll); mScroller.startScroll(0, progressToScrollRange(mFinalAnimatedScroll), 0, 0, 0); } stopScroller(); stopBoundScrollAnimation(); mFinalAnimatedScroll = newScroll; mScrollAnimator = ObjectAnimator.ofFloat(this, "stackScroll", curScroll, newScroll); mScrollAnimator.setDuration(mConfig.taskStackScrollDuration); mScrollAnimator.setInterpolator(mConfig.linearOutSlowInInterpolator); Loading
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewTouchHandler.java +25 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.recents.views; import android.content.Context; import android.view.InputDevice; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; Loading Loading @@ -189,7 +190,6 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { /** Handles touch events once we have intercepted them */ public boolean onTouchEvent(MotionEvent ev) { // Short circuit if we have no children boolean hasChildren = (mSv.getChildCount() > 0); if (!hasChildren) { Loading Loading @@ -336,6 +336,30 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback { return true; } /** Handles generic motion events */ public boolean onGenericMotionEvent(MotionEvent ev) { if ((ev.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER) { int action = ev.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_SCROLL: // Find the front most task and scroll the next task to the front float vScroll = ev.getAxisValue(MotionEvent.AXIS_VSCROLL); if (vScroll > 0) { if (mSv.ensureFocusedTask()) { mSv.focusNextTask(true, false); } } else { if (mSv.ensureFocusedTask()) { mSv.focusNextTask(false, false); } } return true; } } return false; } /**** SwipeHelper Implementation ****/ @Override Loading